@gobing-ai/knowledge-kit 0.0.19 → 0.0.21
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/package.json +1 -1
- package/plugins/generations/dailynews-gen/dist/index.js +9 -1
- package/plugins/generations/dailynews-gen/src/script-builder.ts +19 -1
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/pipeline.py +13 -5
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/qc.py +23 -15
- package/plugins/ingestions/aihot-ingest/dist/index.js +1 -1
- package/plugins/ingestions/aihot-ingest/plugin.json +1 -1
- package/plugins/ingestions/aihot-ingest/src/rss.ts +12 -2
- package/plugins/kk/commands/workflow-run.md +20 -6
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/scripts/itc-stages.ts +563 -0
- package/plugins/kk/scripts/kk-workflow-stages.ts +93 -14
- package/plugins/kk/skills/article-adapt/SKILL.md +85 -0
- package/plugins/kk/workflows/kk-daily-ai-voice.yaml +26 -16
- package/plugins/kk/workflows/kk-itc.yaml +461 -12
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
name: kk-itc
|
|
4
4
|
kind: state-machine
|
|
5
5
|
description: >-
|
|
6
|
-
IT content authoring pipeline using topic/itc-generating, Spur HITL gates, and optional judging
|
|
6
|
+
IT content authoring pipeline using topic/itc-generating, Spur HITL gates, and optional judging;
|
|
7
|
+
an auto path (auto-picked outline, unslop pass, judge revise loop) ends in a run report
|
|
7
8
|
initialState: prepare
|
|
8
9
|
terminalStates:
|
|
9
10
|
- done
|
|
@@ -19,6 +20,9 @@ vars:
|
|
|
19
20
|
playbook: "generic"
|
|
20
21
|
research: "false"
|
|
21
22
|
judge: "false"
|
|
23
|
+
auto: "false" # auto mode: writer-recommended outline, no draft-review pause, mandatory judge, auto revise loop
|
|
24
|
+
unslop: "false" # run kk:taste-unslop on the draft before review/judge
|
|
25
|
+
max_revisions: "2" # cap on the auto revise loop (interactive stays bounded by the existing 3)
|
|
22
26
|
outline: ""
|
|
23
27
|
force: "false"
|
|
24
28
|
rubric: "tech-accuracy"
|
|
@@ -26,6 +30,13 @@ vars:
|
|
|
26
30
|
agent: ""
|
|
27
31
|
__hitlAnswer: ""
|
|
28
32
|
__hitlInput: ""
|
|
33
|
+
__verdictFeedback: "" # raw .itc-verdict.json, read by judge so draft-revise can show the feedback
|
|
34
|
+
publish_targets: "" # comma list of publish plugin names; empty = no publish tail (V1)
|
|
35
|
+
publish_live: "false" # live instead of draft; launch-only, never implied by auto (V4)
|
|
36
|
+
source_locale: "en" # locale of the authored draft (en|zh|ja)
|
|
37
|
+
cover_enabled: "false" # generate a cover via kk:image-authoring — this is the spend approval (R7)
|
|
38
|
+
inline_images: "false" # also generate inline illustrations — also a spend approval
|
|
39
|
+
browser_target: "" # internal cursor for the browser publish loop (written by itc-publish-next)
|
|
29
40
|
|
|
30
41
|
states:
|
|
31
42
|
- id: prepare
|
|
@@ -62,6 +73,7 @@ states:
|
|
|
62
73
|
input: |
|
|
63
74
|
Invoke the kk:${vars.writer} skill.
|
|
64
75
|
Generate outline options (outline-option-a.md, outline-option-b.md, and optionally outline-option-c.md) in ${vars.work_dir}/2-outline/ from the brief at ${vars.work_dir}/brief.md using playbook ${vars.playbook}.
|
|
76
|
+
When auto mode is on (auto=true), also write 2-outline/outline-recommendation.json as {"pick": "a|b|c", "rationale": "<why this option is strongest>"} recommending the option you would commit.
|
|
65
77
|
Do not wait for operator selection; write the option files.
|
|
66
78
|
expectFile: ${vars.work_dir}/2-outline/outline-option-a.md
|
|
67
79
|
- kind: shell
|
|
@@ -82,6 +94,18 @@ states:
|
|
|
82
94
|
- c
|
|
83
95
|
var: __hitlAnswer
|
|
84
96
|
|
|
97
|
+
- id: outline-autopick
|
|
98
|
+
description: "Auto mode — validate the writer's outline-recommendation.json and bind the pick as the selected outline"
|
|
99
|
+
onEnter:
|
|
100
|
+
- kind: shell
|
|
101
|
+
options:
|
|
102
|
+
command: >-
|
|
103
|
+
kk stage itc-outline-pick "${vars.work_dir}"
|
|
104
|
+
- kind: file.read.into-var
|
|
105
|
+
options:
|
|
106
|
+
path: ${vars.work_dir}/2-outline/.auto-pick
|
|
107
|
+
var: outline
|
|
108
|
+
|
|
85
109
|
- id: outline-commit
|
|
86
110
|
description: "Copy selected outline to outline-approved.md"
|
|
87
111
|
onEnter:
|
|
@@ -110,6 +134,21 @@ states:
|
|
|
110
134
|
Revision feedback: ${vars.__hitlInput}
|
|
111
135
|
expectFile: ${vars.work_dir}/3-draft-draft-article.md
|
|
112
136
|
|
|
137
|
+
- id: unslop
|
|
138
|
+
description: "De-slop pass — kk:taste-unslop line-edits the draft (writes a new file, then the swap makes it in place)"
|
|
139
|
+
onEnter:
|
|
140
|
+
- kind: agent.run
|
|
141
|
+
options:
|
|
142
|
+
role: scribe
|
|
143
|
+
agent: ${vars.agent}
|
|
144
|
+
input: |
|
|
145
|
+
Invoke the kk:taste-unslop skill.
|
|
146
|
+
Read ${vars.work_dir}/3-draft-draft-article.md and write the line-edited version to ${vars.work_dir}/3-draft-draft-article.new.md, removing slop (AI-tell phrasing, filler, hedging) while preserving the technical claims, code blocks, links, and the approved outline's structure. Do not modify or delete the original file; the pipeline swaps the edited file in.
|
|
147
|
+
expectFile: ${vars.work_dir}/3-draft-draft-article.new.md
|
|
148
|
+
- kind: shell
|
|
149
|
+
options:
|
|
150
|
+
command: mv -f "${vars.work_dir}/3-draft-draft-article.new.md" "${vars.work_dir}/3-draft-draft-article.md"
|
|
151
|
+
|
|
113
152
|
- id: draft-review
|
|
114
153
|
description: "Operator reviews and approves or requests revision on draft-article.md"
|
|
115
154
|
pause: true
|
|
@@ -130,9 +169,139 @@ states:
|
|
|
130
169
|
echo $((n + 1)) > "${vars.work_dir}/.revise-count";
|
|
131
170
|
- kind: hitl.input
|
|
132
171
|
options:
|
|
133
|
-
prompt: "
|
|
172
|
+
prompt: "Judge feedback (from ${vars.work_dir}/.itc-verdict.json): ${vars.__verdictFeedback}\nProvide specific revision feedback for ${vars.work_dir}/3-draft-draft-article.md:"
|
|
134
173
|
var: __hitlInput
|
|
135
174
|
|
|
175
|
+
- id: draft-autorevise
|
|
176
|
+
description: "Auto mode — apply the judge feedback[] to the draft and consume one revision from the budget"
|
|
177
|
+
onEnter:
|
|
178
|
+
- kind: shell
|
|
179
|
+
options:
|
|
180
|
+
command: >-
|
|
181
|
+
n=$(cat "${vars.work_dir}/.auto-revise-count" 2>/dev/null || echo 0);
|
|
182
|
+
echo $((n + 1)) > "${vars.work_dir}/.auto-revise-count";
|
|
183
|
+
- kind: agent.run
|
|
184
|
+
options:
|
|
185
|
+
role: scribe
|
|
186
|
+
agent: ${vars.agent}
|
|
187
|
+
input: |
|
|
188
|
+
Invoke the kk:${vars.writer} skill.
|
|
189
|
+
Read the draft at ${vars.work_dir}/3-draft-draft-article.md and write a revised version to ${vars.work_dir}/3-draft-draft-article.new.md, applying every item of feedback[] in ${vars.work_dir}/.itc-verdict.json. Do not modify or delete the original file; the pipeline swaps the revised file in.
|
|
190
|
+
expectFile: ${vars.work_dir}/3-draft-draft-article.new.md
|
|
191
|
+
- kind: shell
|
|
192
|
+
options:
|
|
193
|
+
command: mv -f "${vars.work_dir}/3-draft-draft-article.new.md" "${vars.work_dir}/3-draft-draft-article.md"
|
|
194
|
+
|
|
195
|
+
- id: publish-entry
|
|
196
|
+
description: "Publish tail entry — targets are set; route into illustration/materialization"
|
|
197
|
+
|
|
198
|
+
- id: illustrate
|
|
199
|
+
description: "Optional cover/inline illustrations via kk:image-authoring — entered only when a spend var is on (R7)"
|
|
200
|
+
onEnter:
|
|
201
|
+
- kind: agent.run
|
|
202
|
+
options:
|
|
203
|
+
role: scribe
|
|
204
|
+
agent: ${vars.agent}
|
|
205
|
+
input: |
|
|
206
|
+
Invoke the kk:image-authoring skill with KK_NONINTERACTIVE=1 and KK_IMAGE_AUTO_CONFIRM=1 (non-interactive, auto-confirm — the operator approved spend via the cover_enabled/inline_images vars).
|
|
207
|
+
Create ${vars.work_dir}/4-illustrations/ and generate the cover illustration into it as cover.png (cover.jpg acceptable), sized for an article hero image.
|
|
208
|
+
When inline_images=true, also generate inline figures for the draft's key sections as inline-<slug>.png in the same directory.
|
|
209
|
+
Print each written path as the last line of stdout.
|
|
210
|
+
- kind: shell
|
|
211
|
+
options:
|
|
212
|
+
command: >-
|
|
213
|
+
test "${vars.cover_enabled}" = "true" || exit 0;
|
|
214
|
+
ls "${vars.work_dir}"/4-illustrations/cover.* >/dev/null 2>&1 || { echo "cover_enabled=true but no 4-illustrations/cover.* in ${vars.work_dir}" >&2; exit 1; }
|
|
215
|
+
|
|
216
|
+
- id: materialize
|
|
217
|
+
description: "Materialize the approved draft to 4-publish/content.json"
|
|
218
|
+
onEnter:
|
|
219
|
+
- kind: shell
|
|
220
|
+
options:
|
|
221
|
+
command: >-
|
|
222
|
+
kk stage itc-materialize "${vars.work_dir}" "${vars.publish_live}"
|
|
223
|
+
|
|
224
|
+
- id: publish-plan
|
|
225
|
+
description: "Split targets into fan-out groups and browser targets (4-publish/publish-plan.json)"
|
|
226
|
+
onEnter:
|
|
227
|
+
- kind: shell
|
|
228
|
+
options:
|
|
229
|
+
command: >-
|
|
230
|
+
kk stage itc-publish-plan "${vars.work_dir}" "${vars.publish_targets}" "${vars.source_locale}" "${vars.publish_live}"
|
|
231
|
+
|
|
232
|
+
- id: adapt
|
|
233
|
+
description: "Write one adapted Content file per plan variant with adapt:true — kk:article-adapt (R9)"
|
|
234
|
+
onEnter:
|
|
235
|
+
- kind: agent.run
|
|
236
|
+
options:
|
|
237
|
+
role: scribe
|
|
238
|
+
agent: ${vars.agent}
|
|
239
|
+
input: |
|
|
240
|
+
Invoke the kk:article-adapt skill.
|
|
241
|
+
Read ${vars.work_dir}/4-publish/publish-plan.json and, for every entry in variants with adapt=true, read the source ${vars.work_dir}/4-publish/content.json and write ${vars.work_dir}/4-publish/<entry.file>: translate title and body to the variant locale, apply the entry's limits, and keep code blocks, URLs and references unchanged.
|
|
242
|
+
Set format to the variant key's format suffix. Never set metadata.published, metadata.publishStatus or metadata.operation — itc-publish-fanout stamps the draft/live switches at send time.
|
|
243
|
+
- kind: shell
|
|
244
|
+
options:
|
|
245
|
+
command: >-
|
|
246
|
+
kk stage itc-adapt-verify "${vars.work_dir}"
|
|
247
|
+
|
|
248
|
+
- id: publish-gate
|
|
249
|
+
description: "Route to the operator confirm unless auto publishes drafts"
|
|
250
|
+
|
|
251
|
+
- id: publish-confirm
|
|
252
|
+
description: "Operator confirms the send — every target, draft or live mode"
|
|
253
|
+
pause: true
|
|
254
|
+
onEnter:
|
|
255
|
+
- kind: hitl.confirm
|
|
256
|
+
options:
|
|
257
|
+
prompt: >-
|
|
258
|
+
Send to targets [${vars.publish_targets}] in ${vars.publish_live} mode (false = draft,
|
|
259
|
+
true = LIVE)? Review ${vars.work_dir}/4-publish/publish-plan.json first.
|
|
260
|
+
var: __hitlAnswer
|
|
261
|
+
- kind: shell
|
|
262
|
+
options:
|
|
263
|
+
command: >-
|
|
264
|
+
test "${vars.__hitlAnswer}" = "yes" || printf declined > "${vars.work_dir}/4-publish/.publish-declined"
|
|
265
|
+
|
|
266
|
+
- id: publish-fanout
|
|
267
|
+
description: "Send each fan-out group through kk executor fan-out — target failures are data"
|
|
268
|
+
onEnter:
|
|
269
|
+
- kind: shell
|
|
270
|
+
options:
|
|
271
|
+
command: >-
|
|
272
|
+
kk stage itc-publish-fanout "${vars.work_dir}"
|
|
273
|
+
|
|
274
|
+
- id: publish-retry
|
|
275
|
+
description: "Re-send failed fan-out groups once through --retry-from (V5)"
|
|
276
|
+
onEnter:
|
|
277
|
+
- kind: shell
|
|
278
|
+
options:
|
|
279
|
+
command: >-
|
|
280
|
+
n=$(cat "${vars.work_dir}/.publish-retry-count" 2>/dev/null || echo 0);
|
|
281
|
+
echo $((n + 1)) > "${vars.work_dir}/.publish-retry-count";
|
|
282
|
+
kk stage itc-publish-fanout "${vars.work_dir}" --retry
|
|
283
|
+
|
|
284
|
+
- id: publish-agent
|
|
285
|
+
description: "Publish one pending browser target via kk:publish — file-cursor loop bounded by the plan"
|
|
286
|
+
onEnter:
|
|
287
|
+
- kind: file.read.into-var
|
|
288
|
+
options:
|
|
289
|
+
path: ${vars.work_dir}/4-publish/.next-browser
|
|
290
|
+
var: browser_target
|
|
291
|
+
- kind: agent.run
|
|
292
|
+
options:
|
|
293
|
+
role: scribe
|
|
294
|
+
agent: ${vars.agent}
|
|
295
|
+
input: |
|
|
296
|
+
Invoke the kk:publish skill for the browser target ${vars.browser_target}.
|
|
297
|
+
Read ${vars.work_dir}/4-publish/publish-plan.json, find the browser entry whose target is ${vars.browser_target}, and use that variant's file under ${vars.work_dir}/4-publish/ as the Content input.
|
|
298
|
+
When the plan's live is true pass the skill's --live flag; otherwise publish as a draft (V4).
|
|
299
|
+
Always write the Result to ${vars.work_dir}/4-publish/result.${vars.browser_target}.json, including {ok: false, error: ...} when the publish fails.
|
|
300
|
+
expectFile: ${vars.work_dir}/4-publish/result.${vars.browser_target}.json
|
|
301
|
+
- kind: shell
|
|
302
|
+
options:
|
|
303
|
+
command: 'kk stage itc-publish-next "${vars.work_dir}"'
|
|
304
|
+
|
|
136
305
|
- id: judge
|
|
137
306
|
description: "Evaluate technical draft with content-judge (agent.run)"
|
|
138
307
|
onEnter:
|
|
@@ -143,9 +312,22 @@ states:
|
|
|
143
312
|
input: |
|
|
144
313
|
Invoke the kk:content-judge skill.
|
|
145
314
|
Evaluate the draft at ${vars.work_dir}/3-draft-draft-article.md against the ${vars.rubric} rubric.
|
|
315
|
+
Research evidence: if ${vars.work_dir}/docs.json exists, read it and weigh it when judging.
|
|
146
316
|
Write the verdict JSON to ${vars.work_dir}/.itc-verdict.json per the skill's verdict contract.
|
|
147
317
|
Print the verdict path as the last line of stdout.
|
|
148
318
|
expectFile: ${vars.work_dir}/.itc-verdict.json
|
|
319
|
+
- kind: file.read.into-var
|
|
320
|
+
options:
|
|
321
|
+
path: ${vars.work_dir}/.itc-verdict.json
|
|
322
|
+
var: __verdictFeedback
|
|
323
|
+
|
|
324
|
+
- id: report
|
|
325
|
+
description: "Write the run report, then route to done or failed on its outcome"
|
|
326
|
+
onEnter:
|
|
327
|
+
- kind: shell
|
|
328
|
+
options:
|
|
329
|
+
command: >-
|
|
330
|
+
kk stage itc-report "${vars.work_dir}" "${vars.max_revisions}"
|
|
149
331
|
|
|
150
332
|
- id: done
|
|
151
333
|
description: "Terminal — IT content draft generated and approved successfully"
|
|
@@ -175,13 +357,21 @@ transitions:
|
|
|
175
357
|
guard:
|
|
176
358
|
kind: always
|
|
177
359
|
|
|
360
|
+
- from: outline-write
|
|
361
|
+
to: outline-autopick
|
|
362
|
+
description: "Auto mode with no pre-selected outline -> validate the writer recommendation and bind it"
|
|
363
|
+
guard:
|
|
364
|
+
kind: shell
|
|
365
|
+
options:
|
|
366
|
+
command: 'test "${vars.auto}" = "true" -a -z "${vars.outline}"'
|
|
367
|
+
|
|
178
368
|
- from: outline-write
|
|
179
369
|
to: outline-select
|
|
180
|
-
description: "
|
|
370
|
+
description: "Interactive mode with no pre-selected outline -> pause for operator selection"
|
|
181
371
|
guard:
|
|
182
372
|
kind: shell
|
|
183
373
|
options:
|
|
184
|
-
command: 'test -z "${vars.outline}"'
|
|
374
|
+
command: 'test "${vars.auto}" != "true" -a -z "${vars.outline}"'
|
|
185
375
|
|
|
186
376
|
- from: outline-write
|
|
187
377
|
to: outline-commit
|
|
@@ -197,17 +387,57 @@ transitions:
|
|
|
197
387
|
guard:
|
|
198
388
|
kind: always
|
|
199
389
|
|
|
390
|
+
- from: outline-autopick
|
|
391
|
+
to: outline-commit
|
|
392
|
+
description: "Writer recommendation validated and bound -> commit approved outline"
|
|
393
|
+
guard:
|
|
394
|
+
kind: always
|
|
395
|
+
|
|
200
396
|
- from: outline-commit
|
|
201
397
|
to: draft-write
|
|
202
398
|
description: "Approved outline committed -> write draft"
|
|
203
399
|
guard:
|
|
204
400
|
kind: always
|
|
205
401
|
|
|
402
|
+
- from: draft-write
|
|
403
|
+
to: unslop
|
|
404
|
+
description: "Unslop enabled -> de-slop the fresh draft"
|
|
405
|
+
guard:
|
|
406
|
+
kind: shell
|
|
407
|
+
options:
|
|
408
|
+
command: 'test "${vars.unslop}" = "true"'
|
|
409
|
+
|
|
206
410
|
- from: draft-write
|
|
207
411
|
to: draft-review
|
|
208
|
-
description: "
|
|
412
|
+
description: "Interactive mode without unslop -> pause for operator review"
|
|
209
413
|
guard:
|
|
210
|
-
kind:
|
|
414
|
+
kind: shell
|
|
415
|
+
options:
|
|
416
|
+
command: 'test "${vars.auto}" != "true" -a "${vars.unslop}" != "true"'
|
|
417
|
+
|
|
418
|
+
- from: draft-write
|
|
419
|
+
to: judge
|
|
420
|
+
description: "Auto mode without unslop -> straight to the judge"
|
|
421
|
+
guard:
|
|
422
|
+
kind: shell
|
|
423
|
+
options:
|
|
424
|
+
command: 'test "${vars.auto}" = "true" -a "${vars.unslop}" != "true"'
|
|
425
|
+
|
|
426
|
+
- from: unslop
|
|
427
|
+
to: judge
|
|
428
|
+
description: "Auto mode -> the de-slopped draft goes to the judge"
|
|
429
|
+
guard:
|
|
430
|
+
kind: shell
|
|
431
|
+
options:
|
|
432
|
+
command: 'test "${vars.auto}" = "true"'
|
|
433
|
+
|
|
434
|
+
- from: unslop
|
|
435
|
+
to: draft-review
|
|
436
|
+
description: "Interactive mode -> pause for operator review of the de-slopped draft"
|
|
437
|
+
guard:
|
|
438
|
+
kind: shell
|
|
439
|
+
options:
|
|
440
|
+
command: 'test "${vars.auto}" != "true"'
|
|
211
441
|
|
|
212
442
|
- from: draft-review
|
|
213
443
|
to: judge
|
|
@@ -219,11 +449,19 @@ transitions:
|
|
|
219
449
|
|
|
220
450
|
- from: draft-review
|
|
221
451
|
to: done
|
|
222
|
-
description: "Draft approved
|
|
452
|
+
description: "Draft approved, judge disabled, no publish targets -> complete workflow"
|
|
453
|
+
guard:
|
|
454
|
+
kind: shell
|
|
455
|
+
options:
|
|
456
|
+
command: '{ test -z "${vars.__hitlAnswer}" || test "${vars.__hitlAnswer}" = "yes"; } && test "${vars.judge}" != "true" && test -z "${vars.publish_targets}"'
|
|
457
|
+
|
|
458
|
+
- from: draft-review
|
|
459
|
+
to: publish-entry
|
|
460
|
+
description: "Draft approved, judge disabled, targets set -> enter the publish tail"
|
|
223
461
|
guard:
|
|
224
462
|
kind: shell
|
|
225
463
|
options:
|
|
226
|
-
command: '{ test -z "${vars.__hitlAnswer}" || test "${vars.__hitlAnswer}" = "yes"; } && test "${vars.judge}" != "true"'
|
|
464
|
+
command: '{ test -z "${vars.__hitlAnswer}" || test "${vars.__hitlAnswer}" = "yes"; } && test "${vars.judge}" != "true" && test -n "${vars.publish_targets}"'
|
|
227
465
|
|
|
228
466
|
- from: draft-review
|
|
229
467
|
to: draft-revise
|
|
@@ -247,18 +485,229 @@ transitions:
|
|
|
247
485
|
guard:
|
|
248
486
|
kind: always
|
|
249
487
|
|
|
488
|
+
- from: draft-autorevise
|
|
489
|
+
to: unslop
|
|
490
|
+
description: "Unslop enabled -> de-slop the auto-revised draft"
|
|
491
|
+
guard:
|
|
492
|
+
kind: shell
|
|
493
|
+
options:
|
|
494
|
+
command: 'test "${vars.unslop}" = "true"'
|
|
495
|
+
|
|
496
|
+
- from: draft-autorevise
|
|
497
|
+
to: judge
|
|
498
|
+
description: "Auto mode without unslop -> back to the judge"
|
|
499
|
+
guard:
|
|
500
|
+
kind: shell
|
|
501
|
+
options:
|
|
502
|
+
command: 'test "${vars.auto}" = "true" -a "${vars.unslop}" != "true"'
|
|
503
|
+
|
|
504
|
+
- from: judge
|
|
505
|
+
to: done
|
|
506
|
+
description: "Interactive mode, verdict PASS (or empty in dry-run), no publish targets -> complete workflow"
|
|
507
|
+
guard:
|
|
508
|
+
kind: shell
|
|
509
|
+
options:
|
|
510
|
+
command: '{ test "${vars.auto}" != "true"; } && { v="$(jq -r .verdict ${vars.work_dir}/.itc-verdict.json 2>/dev/null)"; test -z "$v" -o "$v" = PASS; } && test -z "${vars.publish_targets}"'
|
|
511
|
+
|
|
512
|
+
- from: judge
|
|
513
|
+
to: publish-entry
|
|
514
|
+
description: "Verdict PASS with targets set -> enter the publish tail (auto runs report after the tail)"
|
|
515
|
+
guard:
|
|
516
|
+
kind: shell
|
|
517
|
+
options:
|
|
518
|
+
command: '{ v="$(jq -r .verdict ${vars.work_dir}/.itc-verdict.json 2>/dev/null)"; test -z "$v" -o "$v" = PASS; } && test -n "${vars.publish_targets}"'
|
|
519
|
+
|
|
250
520
|
- from: judge
|
|
521
|
+
to: report
|
|
522
|
+
description: "Auto mode -> the run ends in the report (PASS without targets, FAIL, or exhausted NEEDS_REVISION)"
|
|
523
|
+
guard:
|
|
524
|
+
kind: shell
|
|
525
|
+
options:
|
|
526
|
+
command: '{ test "${vars.auto}" = "true"; } && { v="$(jq -r .verdict ${vars.work_dir}/.itc-verdict.json 2>/dev/null)"; c="$(cat "${vars.work_dir}/.auto-revise-count" 2>/dev/null || echo 0)"; { test -z "$v" -o "$v" = PASS; } || test "$v" = FAIL || { test "$v" = NEEDS_REVISION -a "$c" -ge "${vars.max_revisions}"; }; }'
|
|
527
|
+
|
|
528
|
+
- from: judge
|
|
529
|
+
to: draft-autorevise
|
|
530
|
+
description: "Auto mode, NEEDS_REVISION with revise budget left -> apply feedback and re-judge"
|
|
531
|
+
guard:
|
|
532
|
+
kind: shell
|
|
533
|
+
options:
|
|
534
|
+
command: '{ test "${vars.auto}" = "true"; } && { v="$(jq -r .verdict ${vars.work_dir}/.itc-verdict.json 2>/dev/null)"; c="$(cat "${vars.work_dir}/.auto-revise-count" 2>/dev/null || echo 0)"; test "$v" = NEEDS_REVISION -a "$c" -lt "${vars.max_revisions}"; }'
|
|
535
|
+
|
|
536
|
+
- from: judge
|
|
537
|
+
to: draft-revise
|
|
538
|
+
description: "Interactive mode, NEEDS_REVISION with revise budget left -> collect revision with the feedback shown"
|
|
539
|
+
guard:
|
|
540
|
+
kind: shell
|
|
541
|
+
options:
|
|
542
|
+
command: '{ test "${vars.auto}" != "true"; } && { v="$(jq -r .verdict ${vars.work_dir}/.itc-verdict.json 2>/dev/null)"; c="$(cat "${vars.work_dir}/.revise-count" 2>/dev/null || echo 0)"; test "$v" = NEEDS_REVISION -a "$c" -lt 3; }'
|
|
543
|
+
|
|
544
|
+
- from: judge
|
|
545
|
+
to: failed
|
|
546
|
+
description: "Interactive mode, verdict FAIL or revise budget exhausted -> fail"
|
|
547
|
+
guard:
|
|
548
|
+
kind: shell
|
|
549
|
+
options:
|
|
550
|
+
command: '{ test "${vars.auto}" != "true"; } && { v="$(jq -r .verdict ${vars.work_dir}/.itc-verdict.json 2>/dev/null)"; c="$(cat "${vars.work_dir}/.revise-count" 2>/dev/null || echo 0)"; test "$v" = FAIL || { test "$v" = NEEDS_REVISION -a "$c" -ge 3; }; }'
|
|
551
|
+
|
|
552
|
+
# --- 0151 publish tail: materialize -> plan -> gate -> confirm/fanout -> retry -> browser loop ---
|
|
553
|
+
|
|
554
|
+
- from: publish-entry
|
|
555
|
+
to: illustrate
|
|
556
|
+
description: "Cover or inline images approved -> run the illustration step (R7: no image spend while both vars are false)"
|
|
557
|
+
guard:
|
|
558
|
+
kind: shell
|
|
559
|
+
options:
|
|
560
|
+
command: 'test "${vars.cover_enabled}" = "true" -o "${vars.inline_images}" = "true"'
|
|
561
|
+
|
|
562
|
+
- from: publish-entry
|
|
563
|
+
to: materialize
|
|
564
|
+
description: "No illustration spend approved -> materialize directly"
|
|
565
|
+
guard:
|
|
566
|
+
kind: shell
|
|
567
|
+
options:
|
|
568
|
+
command: 'test "${vars.cover_enabled}" != "true" -a "${vars.inline_images}" != "true"'
|
|
569
|
+
|
|
570
|
+
- from: illustrate
|
|
571
|
+
to: materialize
|
|
572
|
+
description: "Illustrations written -> materialize the final draft (metadata.coverImage picks up 4-illustrations/cover.*)"
|
|
573
|
+
guard:
|
|
574
|
+
kind: always
|
|
575
|
+
|
|
576
|
+
- from: materialize
|
|
577
|
+
to: publish-plan
|
|
578
|
+
description: "content.json written -> split targets into groups"
|
|
579
|
+
guard:
|
|
580
|
+
kind: always
|
|
581
|
+
|
|
582
|
+
- from: publish-plan
|
|
583
|
+
to: adapt
|
|
584
|
+
description: "The plan has at least one adapt:true variant -> write the adapted variant files (R9)"
|
|
585
|
+
guard:
|
|
586
|
+
kind: shell
|
|
587
|
+
options:
|
|
588
|
+
command: >-
|
|
589
|
+
v="$(jq '[.variants[] | select(.adapt == true)] | length' "${vars.work_dir}/4-publish/publish-plan.json" 2>/dev/null)";
|
|
590
|
+
test -n "$v" -a "$v" -gt 0
|
|
591
|
+
|
|
592
|
+
- from: publish-plan
|
|
593
|
+
to: publish-gate
|
|
594
|
+
description: "Nothing needs adaptation -> route through the send gate"
|
|
595
|
+
guard:
|
|
596
|
+
kind: always
|
|
597
|
+
|
|
598
|
+
- from: adapt
|
|
599
|
+
to: publish-gate
|
|
600
|
+
description: "Variant files verified (itc-adapt-verify) -> route through the send gate"
|
|
601
|
+
guard:
|
|
602
|
+
kind: always
|
|
603
|
+
|
|
604
|
+
- from: publish-gate
|
|
605
|
+
to: publish-confirm
|
|
606
|
+
description: "Interactive run or live publish -> pause for the operator answer (V4)"
|
|
607
|
+
guard:
|
|
608
|
+
kind: shell
|
|
609
|
+
options:
|
|
610
|
+
command: >-
|
|
611
|
+
test "${vars.auto}" != "true" -o "${vars.publish_live}" = "true"
|
|
612
|
+
|
|
613
|
+
- from: publish-gate
|
|
614
|
+
to: publish-fanout
|
|
615
|
+
description: "Auto draft run -> send without pausing (ADR-022)"
|
|
616
|
+
guard:
|
|
617
|
+
kind: always
|
|
618
|
+
|
|
619
|
+
- from: publish-confirm
|
|
620
|
+
to: publish-fanout
|
|
621
|
+
description: "Operator confirmed -> send"
|
|
622
|
+
guard:
|
|
623
|
+
kind: shell
|
|
624
|
+
options:
|
|
625
|
+
command: 'test "${vars.__hitlAnswer}" = "yes"'
|
|
626
|
+
|
|
627
|
+
- from: publish-confirm
|
|
628
|
+
to: report
|
|
629
|
+
description: "Operator declined (or dry-run left no answer) -> report without any publish call"
|
|
630
|
+
guard:
|
|
631
|
+
kind: shell
|
|
632
|
+
options:
|
|
633
|
+
command: >-
|
|
634
|
+
test -z "${vars.__hitlAnswer}" -o "${vars.__hitlAnswer}" = "no"
|
|
635
|
+
|
|
636
|
+
- from: publish-fanout
|
|
637
|
+
to: publish-retry
|
|
638
|
+
description: "A fan-out group has ok:false and the retry budget is untouched -> re-send once (V5)"
|
|
639
|
+
guard:
|
|
640
|
+
kind: shell
|
|
641
|
+
options:
|
|
642
|
+
command: >-
|
|
643
|
+
test "$(cat "${vars.work_dir}/.publish-retry-count" 2>/dev/null || echo 0)" -lt 1
|
|
644
|
+
-a -s "${vars.work_dir}/4-publish/.fanout-failed"
|
|
645
|
+
|
|
646
|
+
- from: publish-fanout
|
|
647
|
+
to: publish-agent
|
|
648
|
+
description: "A browser target has no result.<target>.json -> run the kk:publish loop"
|
|
649
|
+
guard:
|
|
650
|
+
kind: shell
|
|
651
|
+
options:
|
|
652
|
+
# .next-browser cursor: seeded by itc-publish-fanout, recomputed after each kk:publish step
|
|
653
|
+
command: 'test -s "${vars.work_dir}/4-publish/.next-browser"'
|
|
654
|
+
|
|
655
|
+
- from: publish-fanout
|
|
656
|
+
to: report
|
|
657
|
+
description: "Otherwise -> report the per-target outcomes"
|
|
658
|
+
guard:
|
|
659
|
+
kind: always
|
|
660
|
+
|
|
661
|
+
- from: publish-retry
|
|
662
|
+
to: publish-agent
|
|
663
|
+
description: "Retry done, a browser target is still pending -> run the kk:publish loop"
|
|
664
|
+
guard:
|
|
665
|
+
kind: shell
|
|
666
|
+
options:
|
|
667
|
+
# .next-browser cursor: seeded by itc-publish-fanout, recomputed after each kk:publish step
|
|
668
|
+
command: 'test -s "${vars.work_dir}/4-publish/.next-browser"'
|
|
669
|
+
|
|
670
|
+
- from: publish-retry
|
|
671
|
+
to: report
|
|
672
|
+
description: "Otherwise -> report (remaining fan-out failures are terminal data)"
|
|
673
|
+
guard:
|
|
674
|
+
kind: always
|
|
675
|
+
|
|
676
|
+
- from: publish-agent
|
|
677
|
+
to: publish-agent
|
|
678
|
+
description: "A browser target is still pending -> next cursor iteration (bounded by the plan, V5)"
|
|
679
|
+
guard:
|
|
680
|
+
kind: shell
|
|
681
|
+
options:
|
|
682
|
+
# .next-browser cursor: seeded by itc-publish-fanout, recomputed after each kk:publish step
|
|
683
|
+
command: 'test -s "${vars.work_dir}/4-publish/.next-browser"'
|
|
684
|
+
|
|
685
|
+
- from: publish-agent
|
|
686
|
+
to: report
|
|
687
|
+
description: "Browser list exhausted -> report"
|
|
688
|
+
guard:
|
|
689
|
+
kind: always
|
|
690
|
+
|
|
691
|
+
- from: report
|
|
251
692
|
to: done
|
|
252
|
-
description: "
|
|
693
|
+
description: "Report outcome done or declined (empty outcome = done in dry-run, mirroring the empty-verdict PASS convention)"
|
|
694
|
+
guard:
|
|
695
|
+
kind: shell
|
|
696
|
+
options:
|
|
697
|
+
command: 'o="$(jq -r .outcome ${vars.work_dir}/5-report/report.json 2>/dev/null)"; test -z "$o" -o "$o" = done -o "$o" = declined'
|
|
698
|
+
|
|
699
|
+
- from: report
|
|
700
|
+
to: failed
|
|
701
|
+
description: "Report outcome failed -> fail"
|
|
253
702
|
guard:
|
|
254
703
|
kind: shell
|
|
255
704
|
options:
|
|
256
|
-
command: '
|
|
705
|
+
command: 'o="$(jq -r .outcome ${vars.work_dir}/5-report/report.json 2>/dev/null)"; test -n "$o" -a "$o" != done'
|
|
257
706
|
|
|
258
707
|
- from: judge
|
|
259
708
|
to: failed
|
|
260
|
-
description: "
|
|
709
|
+
description: "Catch-all: an out-of-contract verdict string fails the run instead of deadlocking the machine (0149 review P3)"
|
|
261
710
|
guard:
|
|
262
711
|
kind: shell
|
|
263
712
|
options:
|
|
264
|
-
command: 'v="$(jq -r .verdict ${vars.work_dir}/.itc-verdict.json 2>/dev/null)"; test -n "$v" -a "$v" != PASS'
|
|
713
|
+
command: 'v="$(jq -r .verdict ${vars.work_dir}/.itc-verdict.json 2>/dev/null)"; test -n "$v" -a "$v" != PASS -a "$v" != FAIL -a "$v" != NEEDS_REVISION'
|