@fieldwangai/agentflow 0.1.133 → 0.1.135

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,8 +15,8 @@
15
15
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0"
16
16
  rel="stylesheet"
17
17
  />
18
- <script type="module" crossorigin src="/assets/index-CtH_zTEj.js"></script>
19
- <link rel="stylesheet" crossorigin href="/assets/index-DQA8LAlU.css">
18
+ <script type="module" crossorigin src="/assets/index-CmpbCHAj.js"></script>
19
+ <link rel="stylesheet" crossorigin href="/assets/index-BFQVTav-.css">
20
20
  </head>
21
21
  <body>
22
22
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fieldwangai/agentflow",
3
- "version": "0.1.133",
3
+ "version": "0.1.135",
4
4
  "description": "Orchestration system for long-running complex agent tasks using Cursor, OpenCode, Claude Code, or Codex as execution backends",
5
5
  "type": "module",
6
6
  "main": "bin/agentflow.mjs",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: agentflow-cli
3
- description: Direct AgentFlow platform operation through a bundled token-backed CLI, without MCP. Use when Codex needs to list AgentFlow workspaces or flows, start or inspect runs, fetch display outputs, or read and report Workflow actions, artifacts, and global state through AgentFlow HTTP APIs using AGENTFLOW_TOKEN from env or .env. Default AgentFlow base URL is http://ai.mengma.bigo.inner/.
3
+ description: Direct AgentFlow platform operation through a bundled token-backed CLI, without MCP. Use when Codex needs to list AgentFlow workspaces or flows, start or inspect runs, read graphs and logs, or fetch display outputs through AgentFlow HTTP APIs using AGENTFLOW_TOKEN from env or .env. Default AgentFlow base URL is http://ai.mengma.bigo.inner/.
4
4
  ---
5
5
 
6
6
  # AgentFlow CLI
@@ -118,72 +118,9 @@ Extract display outputs from a flow:
118
118
  node skills/agentflow-cli/scripts/agentflow-cli.mjs display-outputs --flow-id TestNodes --flow-source user
119
119
  ```
120
120
 
121
- Read the current materialized Workflow before making an incremental update:
121
+ ## Workflow reporting
122
122
 
123
- ```bash
124
- node skills/agentflow-cli/scripts/agentflow-cli.mjs workflow-get \
125
- --workflow tapd:1015046 \
126
- --runtime-only
127
- ```
128
-
129
- Report an action, its artifacts, and/or a global-state patch:
130
-
131
- ```bash
132
- node skills/agentflow-cli/scripts/agentflow-cli.mjs workflow-report \
133
- --workflow tapd:1015046 \
134
- --file workflow-report.json \
135
- --expected-revision 'runtime:replace-with-current-revision' \
136
- --idempotency-key 'implementation-finished:android:issue-2:v1'
137
- ```
138
-
139
- `workflow-report.json` uses one general model. Include at least one of `action`, `artifacts`, or `globalState`:
140
-
141
- ```json
142
- {
143
- "action": {
144
- "key": "implementation-finished",
145
- "title": "实现完成",
146
- "detail": "Remote Config 拉取频控已实现",
147
- "status": "done",
148
- "group": "development",
149
- "scope": "firebase-remote-config-fetch-control-android",
150
- "platform": "android",
151
- "issueKey": "issue-2",
152
- "tags": ["remote-config"]
153
- },
154
- "artifacts": [
155
- {
156
- "key": "implementation-mr",
157
- "type": "gitlab-mr",
158
- "title": "Android 实现 MR",
159
- "url": "https://git.example.test/group/project/-/merge_requests/123",
160
- "scope": "action",
161
- "status": "ready"
162
- }
163
- ],
164
- "globalState": {
165
- "mode": "merge",
166
- "patch": {
167
- "status": { "label": "开发中" },
168
- "sections": {
169
- "android": {
170
- "title": "Android",
171
- "fields": {
172
- "owner": { "label": "负责人", "type": "user", "value": "alice" },
173
- "tags": { "label": "Tag", "type": "chips", "value": ["remote-config"] },
174
- "rules": { "label": "实现规则", "type": "list", "value": ["仅允许国家注册 listener"] }
175
- }
176
- }
177
- }
178
- },
179
- "remove": []
180
- }
181
- }
182
- ```
183
-
184
- Artifact `scope` is `action` or `global`. Action-scoped artifacts appear with the timeline action; global artifacts appear in the related-artifacts area. Use stable `key` values so later reports update an existing item instead of duplicating it.
185
-
186
- Supported global-state field types are `text`, `user`, `chips`, `list`, and `link`. The model does not require Android/iOS sections; section and field keys are application-defined.
123
+ The CLI implements `workflow-get` and `workflow-report`, but their state model, projection contract, concurrency rules, and AI procedure belong to the separate [`agentflow-workflow-report`](../agentflow-workflow-report/SKILL.md) skill. Use that skill whenever reading or mutating Workflow state; do not reconstruct the protocol from this general CLI guide.
187
124
 
188
125
  ## Workflow
189
126
 
@@ -191,14 +128,10 @@ Supported global-state field types are `text`, `user`, `chips`, `list`, and `lin
191
128
  2. Use `list-workspace` or `list-flows` to discover targets.
192
129
  3. Use `run` to start the flow. If the task needs the generated page/text, inspect returned `displayOutputs` or call `display-outputs`.
193
130
  4. Use `status`, `list-run-by-workspace`, and `logs` when a run is active, failed, or needs debugging.
194
- 5. Before changing Workflow global state, call `workflow-get` and retain `snapshot.runtimeRevision`.
195
- 6. Merge the intended semantic change into the current state; do not replace unrelated fields.
196
- 7. Call `workflow-report` with `--expected-revision` and a stable `--idempotency-key`. If the API returns a revision conflict, fetch again, re-apply the intended patch, and retry once with a new revision.
197
131
 
198
132
  ## Failure Handling
199
133
 
200
134
  - If the CLI says the token is missing, ask the user to set `AGENTFLOW_TOKEN` in env or `.env`.
201
135
  - If the API returns 401/403, do not retry with a printed token. Ask the user to refresh the token.
202
136
  - If `run` fails because a flow is already running, call `status` and `list-run-by-workspace` before retrying.
203
- - If `workflow-report` returns a revision conflict, do not blindly overwrite remote state. Read the returned snapshot or call `workflow-get`, merge the intended fields, and retry with its revision.
204
137
  - If local debugging is needed, override `AGENTFLOW_BASE_URL`; otherwise keep the default internal URL.
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: "AgentFlow CLI"
3
- short_description: "Run flows and report Workflow state through AgentFlow APIs"
4
- default_prompt: "Use $agentflow-cli to operate AgentFlow and report Workflow actions, artifacts, or global state with the bundled token-backed CLI."
3
+ short_description: "Operate AgentFlow workspaces, flows, runs, graphs, and logs"
4
+ default_prompt: "Use $agentflow-cli to inspect or operate AgentFlow with the bundled token-backed CLI."
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: agentflow-workflow-report
3
+ description: Safely read, merge, and report AgentFlow Workflow actions, artifacts, producer-owned global state, and generic timeline projections through the AgentFlow CLI and HTTP protocol. Use when an AI agent or producer such as prd-flow needs to integrate Workflow reporting, publish progress or evidence, update globalState, assign version/sprint/milestone timeline membership, clear projections, or resolve revision and idempotency conflicts.
4
+ ---
5
+
6
+ # AgentFlow Workflow Report
7
+
8
+ Treat Workflow reporting as a read-modify-report protocol. Keep producer business state opaque to AgentFlow and publish only generic dashboard indexes through projections.
9
+
10
+ ## Prerequisites
11
+
12
+ Use the CLI bundled with the sibling `agentflow-cli` skill:
13
+
14
+ ```bash
15
+ node skills/agentflow-cli/scripts/agentflow-cli.mjs <command> [options]
16
+ ```
17
+
18
+ If the script is unavailable, install `agentflow-cli` beside this skill. Require `AGENTFLOW_TOKEN` or `AGENTFLOW_SESSION_TOKEN`; never print either token. Use `AGENTFLOW_BASE_URL` only when overriding the default service.
19
+
20
+ Read [references/protocol.md](references/protocol.md) completely before implementing a producer, changing the report contract, or constructing a payload beyond the quick pattern below.
21
+
22
+ ## Required sequence
23
+
24
+ 1. Resolve a canonical Workflow reference such as `tapd:1015046`.
25
+ 2. Read the current materialized state and retain `snapshot.runtimeRevision`:
26
+
27
+ ```bash
28
+ node skills/agentflow-cli/scripts/agentflow-cli.mjs workflow-get \
29
+ --workflow tapd:1015046 \
30
+ --runtime-only
31
+ ```
32
+
33
+ 3. Compute only the intended semantic update.
34
+ 4. Preserve unrelated `globalState` fields. Never infer or rewrite a producer's private schema.
35
+ 5. When timeline membership changes, derive the complete current `projections.timeline` array from producer state. Use `[]` to clear it.
36
+ 6. Write the payload to a JSON file and report it with the retained revision and a stable operation key:
37
+
38
+ ```bash
39
+ node skills/agentflow-cli/scripts/agentflow-cli.mjs workflow-report \
40
+ --workflow tapd:1015046 \
41
+ --file workflow-report.json \
42
+ --expected-revision 'runtime:current-revision' \
43
+ --idempotency-key 'implementation-finished:android:issue-2:v1'
44
+ ```
45
+
46
+ 7. On HTTP 409, fetch the latest state, reapply the intended semantic update, and retry once with the new revision. Never resend a stale full snapshot.
47
+
48
+ ## Report selection
49
+
50
+ Include at least one capability:
51
+
52
+ - `action`: report a stable progress or lifecycle event.
53
+ - `artifacts`: attach evidence; use stable artifact keys.
54
+ - `globalState`: merge producer-owned durable state or remove explicit paths.
55
+ - `projections`: replace generic derived indexes used by AgentFlow dashboards.
56
+
57
+ Use projection-only reports when the producer state is already current and only dashboard membership needs synchronization.
58
+
59
+ ## Non-negotiable rules
60
+
61
+ - Keep `schemaVersion` at `1` unless the server advertises another version.
62
+ - Give every action a stable `key`.
63
+ - Give every timeline entry stable `kind` and `id` values.
64
+ - Treat `dimensions` as opaque facets; do not hardcode Android, iOS, version, or prd-flow fields into AgentFlow state.
65
+ - Treat `globalState` as the source of truth owned by the producer; treat projections as replaceable derived views.
66
+ - Send the complete current timeline array whenever changing it. Omitting `projections` means no projection change.
67
+ - Use `expectedRevision` for state or projection changes and a stable `idempotencyKey` for every logical operation.
68
+ - Do not include credentials, tokens, cookies, or private environment values in actions, artifacts, state, projections, or logs.
69
+
70
+ ## Failure handling
71
+
72
+ - Missing token: stop and ask the user to configure `AGENTFLOW_TOKEN`.
73
+ - HTTP 401/403: stop; do not retry with a token printed in a command or answer.
74
+ - HTTP 409: follow the single read-merge-retry sequence.
75
+ - HTTP 400: fix the payload against the protocol reference; do not weaken validation.
76
+ - Replayed idempotency key: accept `alreadyApplied: true` as success.
77
+
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "AgentFlow Workflow Report"
3
+ short_description: "Read and report Workflow state safely with a stable protocol"
4
+ default_prompt: "Use $agentflow-workflow-report to read the current Workflow, merge the intended update, and report it with revision and idempotency safeguards."
@@ -0,0 +1,337 @@
1
+ # AgentFlow Workflow Report Protocol
2
+
3
+ ## Contents
4
+
5
+ 1. Contract boundary
6
+ 2. Transport and authentication
7
+ 3. Read endpoint
8
+ 4. Report envelope
9
+ 5. Action model
10
+ 6. Artifact model
11
+ 7. Global-state model
12
+ 8. Timeline projection model
13
+ 9. Concurrency and idempotency
14
+ 10. Producer integration procedure
15
+ 11. Examples
16
+ 12. Acceptance checklist
17
+
18
+ ## 1. Contract boundary
19
+
20
+ AgentFlow owns transport, validation, event persistence, materialization, permissions, optimistic concurrency, idempotency, and dashboard aggregation.
21
+
22
+ The producer owns the meaning and internal schema of `globalState`. AgentFlow must not parse private fields to infer version, sprint, release, or milestone membership.
23
+
24
+ The producer derives `projections` from its current state. Projections are replaceable indexes for generic AgentFlow views, not a second source of truth.
25
+
26
+ ## 2. Transport and authentication
27
+
28
+ Default service URL:
29
+
30
+ ```text
31
+ http://ai.mengma.bigo.inner/
32
+ ```
33
+
34
+ Use bearer authentication through `AGENTFLOW_TOKEN` or `AGENTFLOW_SESSION_TOKEN`. For local testing only, set `AGENTFLOW_BASE_URL` to the local server URL.
35
+
36
+ Preferred transport is the bundled CLI because it resolves env files and auth headers without exposing tokens. Direct HTTP integrations may call the endpoints below with `Authorization: Bearer <token>` and `Content-Type: application/json`.
37
+
38
+ ## 3. Read endpoint
39
+
40
+ CLI:
41
+
42
+ ```bash
43
+ node skills/agentflow-cli/scripts/agentflow-cli.mjs workflow-get \
44
+ --workflow tapd:1015046 \
45
+ --runtime-only
46
+ ```
47
+
48
+ HTTP:
49
+
50
+ ```http
51
+ GET /api/workflows/state?workflow=tapd%3A1015046&runtimeOnly=1
52
+ ```
53
+
54
+ Use the returned `snapshot.runtimeRevision` as `expectedRevision`. Read the existing `snapshot.globalState` before producing a patch and the existing `snapshot.projections.timeline` before replacing timeline membership.
55
+
56
+ The deployed server currently supports the `tapd` Workflow namespace. The reference object remains namespaced for future producers:
57
+
58
+ ```json
59
+ {
60
+ "namespace": "tapd",
61
+ "id": "1015046"
62
+ }
63
+ ```
64
+
65
+ ## 4. Report envelope
66
+
67
+ Endpoint:
68
+
69
+ ```http
70
+ POST /api/workflows/report
71
+ ```
72
+
73
+ Top-level fields:
74
+
75
+ | Field | Required | Meaning |
76
+ | --- | --- | --- |
77
+ | `schemaVersion` | No | Protocol version; defaults to `1` |
78
+ | `workflow` | Yes | `{ namespace, id }` or canonical key |
79
+ | `action` | Conditional | One lifecycle/progress update |
80
+ | `artifacts` | Conditional | Evidence associated with the action or global state |
81
+ | `globalState` | Conditional | Producer-owned merge patch and removals |
82
+ | `projections` | Conditional | Generic replaceable dashboard indexes |
83
+ | `expectedRevision` | For mutations | Revision returned by the latest read |
84
+ | `idempotencyKey` | Recommended | Stable identity of the logical operation |
85
+ | `source` | No | Reporting producer, default `agentflow-cli` |
86
+ | `flowId` | No | Related AgentFlow project identifier |
87
+ | `flowSource` | No | Related project source, default `user` |
88
+
89
+ Include at least one of `action`, `artifacts`, `globalState`, or `projections`.
90
+
91
+ ## 5. Action model
92
+
93
+ ```json
94
+ {
95
+ "key": "implementation:android:issue-2",
96
+ "title": "Android 实现完成",
97
+ "detail": "Remote Config 拉取频控已实现",
98
+ "status": "done",
99
+ "group": "implementation",
100
+ "scope": "remote-config-android",
101
+ "platform": "android",
102
+ "issueKey": "issue-2",
103
+ "tags": ["remote-config"],
104
+ "occurredAt": "2026-08-04T08:00:00.000Z"
105
+ }
106
+ ```
107
+
108
+ `key` is required and stable. Supported normalized statuses are `pending`, `running`, `done`, `error`, `conflict`, `skipped`, `cancelled`, and `observed`. Common aliases such as `completed` and `success` normalize to `done`.
109
+
110
+ Repeated reports for the same stage may update its visible timeline entry. Use a new action key only for a semantically different action.
111
+
112
+ ## 6. Artifact model
113
+
114
+ ```json
115
+ {
116
+ "key": "implementation-mr:issue-2:android",
117
+ "type": "gitlab-mr",
118
+ "title": "Android 实现 MR",
119
+ "url": "https://git.example.test/group/project/-/merge_requests/123",
120
+ "scope": "action",
121
+ "status": "ready"
122
+ }
123
+ ```
124
+
125
+ Use stable keys. `scope` is `action` or `global`. Action-scoped artifacts appear with an action; global artifacts appear in the related-artifacts area. URL and path aliases may be deduplicated, but producers must not rely on title-based identity.
126
+
127
+ ## 7. Global-state model
128
+
129
+ AgentFlow defines only the update operation:
130
+
131
+ ```json
132
+ {
133
+ "mode": "merge",
134
+ "patch": {
135
+ "producerDefined": {
136
+ "anySafeJsonShape": true
137
+ }
138
+ },
139
+ "remove": ["obsolete.path"]
140
+ }
141
+ ```
142
+
143
+ Rules:
144
+
145
+ - `mode` must be `merge`.
146
+ - `patch` recursively merges objects; arrays and scalar values replace the existing value.
147
+ - `null` removes a field during merge.
148
+ - `remove` contains dot-separated paths and is applied after the patch.
149
+ - Never send the entire state unless the producer intentionally owns and has reconciled every field.
150
+ - AgentFlow does not require Android/iOS sections or any prd-flow-specific layout.
151
+
152
+ ## 8. Timeline projection model
153
+
154
+ Timeline projections give generic personal and team dashboards enough metadata to group Workflows without reading producer state:
155
+
156
+ ```json
157
+ {
158
+ "timeline": [
159
+ {
160
+ "kind": "version",
161
+ "id": "android-5.63.0",
162
+ "title": "Likee Android 5.63.0",
163
+ "date": "2026-08-20",
164
+ "source": "prd-flow",
165
+ "dimensions": {
166
+ "platform": "android"
167
+ },
168
+ "order": 0
169
+ }
170
+ ]
171
+ }
172
+ ```
173
+
174
+ Fields:
175
+
176
+ | Field | Required | Meaning |
177
+ | --- | --- | --- |
178
+ | `kind` | Yes | Generic membership type, such as `version`, `release`, `sprint`, or `milestone` |
179
+ | `id` | Yes | Stable producer identity within the kind |
180
+ | `title` | No | Display title; defaults to `id` |
181
+ | `date` | No | ISO-compatible target date used for timeline sorting |
182
+ | `source` | No | Producer namespace, such as `prd-flow` |
183
+ | `dimensions` | No | Opaque grouping and filtering facets |
184
+ | `order` | No | Stable fallback ordering when dates are absent or equal |
185
+ | `key` | No | Explicit aggregate key; otherwise derived from `source`, `kind`, and `id` |
186
+
187
+ Replacement semantics:
188
+
189
+ - When `projections.timeline` is present, it is the complete current timeline membership and replaces the previous array.
190
+ - `"timeline": []` explicitly clears all membership.
191
+ - Omitting `projections` leaves the previous projection unchanged.
192
+ - Multiple entries allow one Workflow to belong to multiple generic timelines.
193
+ - Unknown `kind` and `dimensions` values remain valid and opaque.
194
+
195
+ Dashboard aggregation uses the explicit `key` when supplied; otherwise it derives one from `source + kind + id`. Invalid entries without `kind` or `id` are rejected on report.
196
+
197
+ ## 9. Concurrency and idempotency
198
+
199
+ Use optimistic concurrency for every state or projection mutation:
200
+
201
+ 1. Read the Workflow.
202
+ 2. Retain `snapshot.runtimeRevision`.
203
+ 3. Compute the semantic patch and complete derived projection.
204
+ 4. Report with `expectedRevision`.
205
+ 5. On 409, read again, reapply the same semantic intent, and retry once.
206
+
207
+ Do not blindly replace remote state after a conflict.
208
+
209
+ Use an idempotency key that identifies the logical operation, not the HTTP attempt:
210
+
211
+ ```text
212
+ <operation>:<scope>:<entity>:<semantic-version>
213
+ ```
214
+
215
+ Examples:
216
+
217
+ ```text
218
+ implementation-finished:android:issue-2:v1
219
+ timeline-membership:tapd-1015046:android-5.63.0:v1
220
+ ```
221
+
222
+ A replay may return `alreadyApplied: true`; treat it as successful completion.
223
+
224
+ ## 10. Producer integration procedure
225
+
226
+ Implement the producer adapter in this order:
227
+
228
+ 1. Define its private `globalState` schema outside AgentFlow.
229
+ 2. Define a deterministic function from current producer state to the complete `projections.timeline` array.
230
+ 3. Make projection identities stable across title and date changes.
231
+ 4. Read the current materialized Workflow before reporting.
232
+ 5. Patch only owned global-state fields.
233
+ 6. Report the complete derived projection with the same operation when relevant.
234
+ 7. Persist or derive a stable idempotency key.
235
+ 8. Handle one revision-conflict retry.
236
+ 9. Verify the returned materialized state and projection.
237
+ 10. Confirm the personal and team iteration views group the Workflow correctly.
238
+
239
+ ## 11. Examples
240
+
241
+ ### Action, artifact, state, and timeline together
242
+
243
+ ```json
244
+ {
245
+ "schemaVersion": 1,
246
+ "workflow": { "namespace": "tapd", "id": "1015046" },
247
+ "source": "prd-flow",
248
+ "action": {
249
+ "key": "implementation:android:issue-2",
250
+ "title": "Android 实现完成",
251
+ "status": "done",
252
+ "group": "implementation",
253
+ "platform": "android",
254
+ "issueKey": "issue-2"
255
+ },
256
+ "artifacts": [
257
+ {
258
+ "key": "implementation-mr:issue-2:android",
259
+ "type": "gitlab-mr",
260
+ "title": "Android 实现 MR",
261
+ "url": "https://git.example.test/group/project/-/merge_requests/123",
262
+ "scope": "action",
263
+ "status": "ready"
264
+ }
265
+ ],
266
+ "globalState": {
267
+ "mode": "merge",
268
+ "patch": {
269
+ "prdFlowOwnedState": {
270
+ "status": "implementing"
271
+ }
272
+ },
273
+ "remove": []
274
+ },
275
+ "projections": {
276
+ "timeline": [
277
+ {
278
+ "kind": "version",
279
+ "id": "android-5.63.0",
280
+ "title": "Likee Android 5.63.0",
281
+ "date": "2026-08-20",
282
+ "source": "prd-flow",
283
+ "dimensions": { "platform": "android" }
284
+ }
285
+ ]
286
+ },
287
+ "expectedRevision": "runtime:replace-with-current-revision",
288
+ "idempotencyKey": "implementation-finished:android:issue-2:v1"
289
+ }
290
+ ```
291
+
292
+ ### Projection-only synchronization
293
+
294
+ ```json
295
+ {
296
+ "workflow": { "namespace": "tapd", "id": "1015046" },
297
+ "source": "prd-flow",
298
+ "projections": {
299
+ "timeline": [
300
+ {
301
+ "kind": "sprint",
302
+ "id": "2026-w32",
303
+ "title": "2026 第 32 周",
304
+ "date": "2026-08-03",
305
+ "source": "prd-flow",
306
+ "dimensions": { "team": "client" }
307
+ }
308
+ ]
309
+ },
310
+ "expectedRevision": "runtime:replace-with-current-revision",
311
+ "idempotencyKey": "timeline-membership:tapd-1015046:2026-w32:v1"
312
+ }
313
+ ```
314
+
315
+ ### Clear timeline membership
316
+
317
+ ```json
318
+ {
319
+ "workflow": { "namespace": "tapd", "id": "1015046" },
320
+ "projections": { "timeline": [] },
321
+ "expectedRevision": "runtime:replace-with-current-revision",
322
+ "idempotencyKey": "timeline-membership-clear:tapd-1015046:v1"
323
+ }
324
+ ```
325
+
326
+ ## 12. Acceptance checklist
327
+
328
+ - The producer can read the current Workflow using only token-backed configuration.
329
+ - The producer never prints or stores the token in report data.
330
+ - Global-state changes preserve unrelated fields.
331
+ - Actions and artifacts use stable keys.
332
+ - Timeline entries use stable `kind` and `id` values.
333
+ - Timeline replacement and explicit clearing both work.
334
+ - Revision conflicts trigger one read-merge-retry cycle.
335
+ - Replaying an idempotency key does not duplicate visible state.
336
+ - Returned `snapshot.runtimeRevision` changes after a real update.
337
+ - Personal and team iteration pages show the same canonical grouping for accessible Workflows.