@gobing-ai/knowledge-kit 0.1.14 → 0.1.15
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/dist/index.js +796 -176
- package/package.json +1 -1
- package/plugins/generations/content-gen/dist/index.js +2 -2
- package/plugins/generations/core-facts-gen/dist/index.js +2 -2
- package/plugins/generations/daily-article-gen/dist/index.js +2 -2
- package/plugins/generations/dailynews-gen/dist/index.js +72 -9
- package/plugins/generations/dailynews-gen/src/index.ts +23 -1
- package/plugins/generations/dailynews-gen/src/script-plan.ts +103 -5
- package/plugins/generations/episode-plan-gen/dist/index.js +2 -2
- package/plugins/generations/gemini-tts/dist/index.js +2 -2
- package/plugins/generations/image-gen/dist/index.js +2 -2
- package/plugins/generations/news-report-gen/dist/index.js +2 -2
- package/plugins/generations/voice-gen/dist/index.js +2 -2
- package/plugins/generations/voxcpm-tts/dist/index.js +2 -2
- package/plugins/ingestions/aihot-ingest/dist/index.js +2 -2
- package/plugins/ingestions/horizon-ingest/dist/index.js +2 -2
- package/plugins/ingestions/last30days-ingest/dist/index.js +2 -2
- package/plugins/ingestions/web-search/dist/index.js +2 -2
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/scripts/daily-scheduled-run.ts +4 -0
- package/plugins/kk/scripts/daily-stages.ts +476 -12
- package/plugins/kk/scripts/kk-workflow-stages.ts +20 -4
- package/plugins/kk/skills/content-judge/SKILL.md +5 -4
- package/plugins/kk/skills/content-judge/references/rubrics.md +14 -0
- package/plugins/kk/skills/news-editorial/SKILL.md +122 -0
- package/plugins/kk/skills/news-editorial/references/selection.md +47 -0
- package/plugins/kk/skills/news-editorial/references/style-contract.zh.md +99 -0
- package/plugins/kk/skills/publish/SKILL.md +3 -3
- package/plugins/kk/skills/web-automation/SKILL.md +229 -77
- package/plugins/kk/skills/web-automation/references/browser-launch.md +127 -36
- package/plugins/kk/workflows/kk-daily-ai-voice2.yaml +4 -6
- package/plugins/kk/workflows/kk-daily-ai-voice3.yaml +183 -222
- package/plugins/kk/workflows/kk-daily-publish3.yaml +16 -8
- package/plugins/publishings/bilibili-pub/dist/index.js +5 -3
- package/plugins/publishings/bilibili-pub/dist/profile-check.js +3 -1
- package/plugins/publishings/cnblogs-pub/dist/index.js +5 -3
- package/plugins/publishings/cnblogs-pub/dist/profile-check.js +3 -1
- package/plugins/publishings/csdn-pub/dist/index.js +5 -3
- package/plugins/publishings/csdn-pub/dist/profile-check.js +5 -3
- package/plugins/publishings/emdash-pub/dist/index.js +2 -2
- package/plugins/publishings/infoq-pub/dist/index.js +5 -3
- package/plugins/publishings/infoq-pub/dist/profile-check.js +5 -3
- package/plugins/publishings/jike-pub/dist/index.js +5 -3
- package/plugins/publishings/jike-pub/dist/profile-check.js +5 -3
- package/plugins/publishings/juejin-pub/dist/index.js +5 -3
- package/plugins/publishings/juejin-pub/dist/profile-check.js +5 -3
- package/plugins/publishings/linkedin-pub/dist/index.js +5 -3
- package/plugins/publishings/linkedin-pub/dist/profile-check.js +5 -3
- package/plugins/publishings/medium-pub/dist/index.js +2 -2
- package/plugins/publishings/podcast-pub/dist/index.js +147 -4
- package/plugins/publishings/podcast-pub/src/index.ts +71 -2
- package/plugins/publishings/podcast-pub/src/map.ts +3 -0
- package/plugins/publishings/podcast-pub/src/transcript.ts +195 -0
- package/plugins/publishings/qiita-pub/dist/index.js +2 -2
- package/plugins/publishings/shipinhao-pub/dist/index.js +5 -3
- package/plugins/publishings/shipinhao-pub/dist/profile-check.js +3 -1
- package/plugins/publishings/sspai-pub/dist/index.js +5 -3
- package/plugins/publishings/sspai-pub/dist/profile-check.js +3 -1
- package/plugins/publishings/substack-pub/dist/index.js +5 -3
- package/plugins/publishings/substack-pub/dist/profile-check.js +5 -3
- package/plugins/publishings/surfdash-pub/dist/index.js +2 -2
- package/plugins/publishings/threads-pub/dist/index.js +2 -2
- package/plugins/publishings/wechatmp-pub/dist/index.js +52 -33
- package/plugins/publishings/wechatmp-pub/dist/profile-check.js +5 -3
- package/plugins/publishings/wechatmp-pub/src/flow.ts +70 -33
- package/plugins/publishings/weibo-pub/dist/index.js +5 -3
- package/plugins/publishings/weibo-pub/dist/profile-check.js +5 -3
- package/plugins/publishings/x-pub/dist/index.js +5 -3
- package/plugins/publishings/x-pub/dist/profile-check.js +5 -3
- package/plugins/publishings/xhs-pub/dist/index.js +5 -3
- package/plugins/publishings/xhs-pub/dist/profile-check.js +5 -3
- package/plugins/publishings/xiaoyuzhou-pub/dist/index.js +5 -3
- package/plugins/publishings/xiaoyuzhou-pub/dist/profile-check.js +3 -1
- package/plugins/publishings/zenn-pub/dist/index.js +2 -2
- package/plugins/kk/scripts/daily-voice-style.zh.md +0 -70
|
@@ -7,17 +7,16 @@ description: >-
|
|
|
7
7
|
generate-side channel payloads (`social-write` + `daily-bundle-variants`) and the frozen
|
|
8
8
|
`bundle.json` that `kk-daily-publish3` consumes. It publishes nothing: every channel decision and
|
|
9
9
|
every send lives in the publish preset and the publish workflow, which is why this graph carries
|
|
10
|
-
no `xhs_*` / `wechat_*` / `publish_enabled` switch.
|
|
11
|
-
|
|
10
|
+
no `xhs_*` / `wechat_*` / `publish_enabled` switch. Production since the 2026-11-05 cutover (§8);
|
|
11
|
+
it still runs in voice2's namespace (work dir, store selections, prepare ledger) by design (§11).
|
|
12
12
|
|
|
13
13
|
vars:
|
|
14
14
|
|
|
15
15
|
# ---- voice3 additions (task 0324 R4) ----
|
|
16
16
|
# `auto_publish` launches publish3 nested when true; off by default exactly like voice2's
|
|
17
17
|
# publish_enabled, and the operator turns it on in the schedule entry after the shadow period.
|
|
18
|
-
# Card-series authoring/rendering (billed image generation).
|
|
19
|
-
|
|
20
|
-
cards_enabled: "false"
|
|
18
|
+
# Card-series authoring/rendering (billed image generation). Turned on by default for XHS 上传图文.
|
|
19
|
+
cards_enabled: "true"
|
|
21
20
|
# Card count (voice2's `xhs_cards`, minus the channel name): the card plan targets this many.
|
|
22
21
|
cards: "6"
|
|
23
22
|
auto_publish: "false"
|
|
@@ -67,19 +66,13 @@ vars:
|
|
|
67
66
|
cover_fallback: ""
|
|
68
67
|
# 0219 R3: image-gen vendor fallback for the XHS render; "" restores strict fail-fast.
|
|
69
68
|
xhs_fallback: "true"
|
|
70
|
-
# 2026-10-21 operator decision: OFF for now (was on since 2026-09-29). The plugin reported today's
|
|
71
|
-
# draft as saved (`草稿箱` 12 -> 13 plus a scoped `保存成功` toast) while the console showed the
|
|
72
|
-
# operator no draft, so the channel's success evidence is not trustworthy until that is resolved.
|
|
73
|
-
# Card-image fallback to the aspect-only request when the exact canvas is refused.
|
|
74
|
-
# launch-time switch and nothing else in the run depends on this target.
|
|
75
69
|
xhs_style: "xhs-knowledge"
|
|
76
70
|
xhs_provider: "minimax"
|
|
77
71
|
xhs_model: "image-01"
|
|
78
72
|
# The 合集 tag a channel payload carries is that channel's preset `options` (the shipped preset
|
|
79
73
|
# pins 「每日AI资讯」), not a generate-side var: voice3 does not know which channels exist.
|
|
80
74
|
plan_max_items: "20"
|
|
81
|
-
|
|
82
|
-
article_write_enabled: "true"
|
|
75
|
+
curate_enabled: "true"
|
|
83
76
|
script_write_enabled: "true"
|
|
84
77
|
plugins_path: ""
|
|
85
78
|
# Content-safety budget and platforms, forwarded to the nested kk-daily-safety state machine.
|
|
@@ -144,15 +137,14 @@ nodes:
|
|
|
144
137
|
kind: shell
|
|
145
138
|
options:
|
|
146
139
|
command: >-
|
|
147
|
-
kk stage daily-preflight plugins/kk/workflows/kk-daily-ai-
|
|
140
|
+
kk stage daily-preflight plugins/kk/workflows/kk-daily-ai-voice3.yaml
|
|
148
141
|
plugins/kk/workflows/kk-daily-safety.yaml
|
|
149
142
|
plugins/kk/workflows/kk-daily-publish3.yaml
|
|
150
143
|
&& kk daily prepare --workflow kk-daily-ai-voice2 --run-date "${vars.run_date}" --ledger-sync
|
|
151
144
|
--run "${vars.__runId}" --definition-digest "${vars.__definitionDigest}"
|
|
152
145
|
--setting window="${vars.window}" --setting language="${vars.language}" --setting vdriver="${vars.vdriver}"
|
|
153
146
|
--setting skip_review="${vars.skip_review}" --setting transcode_mp3="${vars.transcode_mp3}"
|
|
154
|
-
--setting cover_enabled="${vars.cover_enabled}" --setting
|
|
155
|
-
--setting article_write_enabled="${vars.article_write_enabled}"
|
|
147
|
+
--setting cover_enabled="${vars.cover_enabled}" --setting curate_enabled="${vars.curate_enabled}"
|
|
156
148
|
--setting script_write_enabled="${vars.script_write_enabled}" --setting plan_max_items="${vars.plan_max_items}"
|
|
157
149
|
--setting safety_max_revise="${vars.safety_max_revise}" --setting qc_min_quality="${vars.qc_min_quality}"
|
|
158
150
|
--setting qc_min_importance="${vars.qc_min_importance}" --setting qc_min_urgency="${vars.qc_min_urgency}"
|
|
@@ -232,7 +224,7 @@ nodes:
|
|
|
232
224
|
kind: shell
|
|
233
225
|
options:
|
|
234
226
|
command: >-
|
|
235
|
-
kk stage daily-plan "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.plan_max_items}" "${vars.
|
|
227
|
+
kk stage daily-plan "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.plan_max_items}" "${vars.curate_enabled}"
|
|
236
228
|
|
|
237
229
|
- id: qc-content
|
|
238
230
|
description: >-
|
|
@@ -295,249 +287,212 @@ nodes:
|
|
|
295
287
|
kk store select --topic ai-news --workflow kk-daily-ai-voice2 --run "${vars.__runId}"
|
|
296
288
|
--in "${vars.work_dir}/21-plan/${vars.run_date}_04_quality-control-content_candidates.json"
|
|
297
289
|
|
|
298
|
-
# ----
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
# answered a greeting with zero tool calls and exited 0 (0238 evidence). The engine has no node
|
|
303
|
-
# retry, so each producer carries a `-retry` sibling on a DIFFERENT tier (`agent_retry`, role
|
|
304
|
-
# reviewer) with the SAME input/expectFile; the primary becomes `onError: continue` and the sibling
|
|
305
|
-
# (no onError) is the loud gate. Downstream readers depend on BOTH, so the done+skipped mix of a
|
|
306
|
-
# successful primary still proceeds. Delete the siblings when spur grows an agent.run retry.
|
|
307
|
-
|
|
308
|
-
- id: plan-translate
|
|
309
|
-
description: "Translate the needsTranslation plan items into the output plan.json via agent.run; onError: continue — plan-translate-retry below is the loud gate (0238 R2)"
|
|
290
|
+
# ---- editorial pipeline: curate -> script-write (master) -> script -> editorial-render (0345) ----
|
|
291
|
+
|
|
292
|
+
- id: script-style
|
|
293
|
+
description: "Snapshot the shipped kk:news-editorial skill and zh style contract into the work dir (20-editorial/news-editorial/ + 24-script/<date>_08_script-write_style.md)"
|
|
310
294
|
dependsOn: [qc-content, pool-gate]
|
|
311
295
|
condition:
|
|
312
296
|
kind: shell
|
|
313
297
|
options:
|
|
314
298
|
# 0324 R3: the pool verdict is `pool-gate`'s token, never a repeated `kk store pool-count`.
|
|
315
|
-
command:
|
|
316
|
-
test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS
|
|
317
|
-
&& test "${vars.plan_translate_enabled}" = "true"
|
|
318
|
-
&& ! jq -e --argjson n "$(jq '.metadata.docs|length' "${vars.work_dir}/21-plan/${vars.run_date}_04_quality-control-content_candidates.json")" 'type=="array" and length==$n and all(.[];type=="object")' "${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json"
|
|
299
|
+
command: 'test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS'
|
|
319
300
|
action:
|
|
320
|
-
kind:
|
|
321
|
-
# 0238 R2: a stochastic executor no-op must not end the run here — the retry sibling decides.
|
|
322
|
-
onError: continue
|
|
301
|
+
kind: shell
|
|
323
302
|
options:
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
# ADR-115 error tier: keep this prompt <= 1000 chars (0133 R3; 0138 R4a copy discipline).
|
|
327
|
-
# The anchor is shared with plan-translate-retry so the two attempts cannot drift apart.
|
|
328
|
-
# 20261015 forensics: headless agy's terminal sandbox denies workspace writes for EVERY
|
|
329
|
-
# shell command (command() rules are promptless-but-sandboxed; unsandboxed() is dead), so
|
|
330
|
-
# the producer must deliver via the file-write tool; and the condition gate checks JSON
|
|
331
|
-
# validity (array, length == candidates docs, all objects) because a pi token-cap staged
|
|
332
|
-
# write once flowed 4/12 items downstream. Keep both when editing prompt or condition.
|
|
333
|
-
input: &plan-translate-input |
|
|
334
|
-
Read ${vars.work_dir}/21-plan/${vars.run_date}_04_quality-control-content_candidates.json; metadata.docs (Doc[]) is the plan.
|
|
335
|
-
For needsTranslation items adapt "title", "body" and "metadata.brief" into spoken simplified Chinese — keep every fact, number, name, quote, hedge (口播全长改编,不摘要不省略), body ≈0.6–0.7× source.
|
|
336
|
-
Titles read as news; keep product/model names and body URLs verbatim, use 「」 not ASCII quotes.
|
|
337
|
-
Copy discipline: reader-facing news copy — no scaffold labels (「可做角度」「为什么现在值得注意」「社区讨论」「背景」「潜在影响」「影响」), no hedging labels (「读者宜另行核实」「仍待验证」) — merge or drop.
|
|
338
|
-
Keep id/sourceUri/mediaType/metadata as-is; no comments/trailing commas.
|
|
339
|
-
Deliver with your file-write tool (headless agy sandbox blocks shell writes); the file must end as ONE valid JSON array — no split markers/placeholders.
|
|
340
|
-
Output the JSON array — same length and order — to ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json.
|
|
341
|
-
expectFile: ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json
|
|
342
|
-
allowAppend: false
|
|
303
|
+
command: >-
|
|
304
|
+
kk stage daily-script-style "${vars.work_dir}" "${vars.run_date}"
|
|
343
305
|
|
|
344
|
-
- id:
|
|
345
|
-
description:
|
|
346
|
-
|
|
347
|
-
VALID expectFile (missing or contract-violating JSON), retries the same input on a different
|
|
348
|
-
tier, and carries NO onError — a second miss fails the run loudly instead of letting an
|
|
349
|
-
untranslated or truncated plan flow downstream.
|
|
350
|
-
dependsOn: [plan-translate, pool-gate]
|
|
306
|
+
- id: curate
|
|
307
|
+
description: "0345 R7: curate QC candidates into kept translated plan.json + _03_curate_excluded.json via kk:news-editorial mode `curate`; onError: continue — curate-check/curate-fix/curate-final below validate and recover"
|
|
308
|
+
dependsOn: [qc-content, script-style, pool-gate]
|
|
351
309
|
condition:
|
|
352
310
|
kind: shell
|
|
353
311
|
options:
|
|
354
|
-
# 0324 R3: the pool verdict is `pool-gate`'s token, never a repeated `kk store pool-count`.
|
|
355
312
|
command: >-
|
|
356
313
|
test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS
|
|
357
|
-
&& test "${vars.
|
|
358
|
-
&& !
|
|
314
|
+
&& test "${vars.curate_enabled}" = "true"
|
|
315
|
+
&& ! (test -s "${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json" && test -s "${vars.work_dir}/21-plan/${vars.run_date}_03_curate_excluded.json")
|
|
359
316
|
action:
|
|
360
317
|
kind: agent.run
|
|
318
|
+
onError: continue
|
|
361
319
|
options:
|
|
362
|
-
role:
|
|
363
|
-
agent: ${vars.
|
|
364
|
-
|
|
320
|
+
role: scribe
|
|
321
|
+
agent: ${vars.agent}
|
|
322
|
+
timeoutMs: 600000
|
|
323
|
+
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
324
|
+
input: |
|
|
325
|
+
Follow mode `curate` in ${vars.work_dir}/20-editorial/news-editorial/SKILL.md (read references/selection.md and references/style-contract.zh.md first).
|
|
326
|
+
--in ${vars.work_dir}/21-plan/${vars.run_date}_04_quality-control-content_candidates.json (metadata.docs is the candidate Doc[]; don't edit it)
|
|
327
|
+
--out-plan ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json
|
|
328
|
+
--out-excluded ${vars.work_dir}/21-plan/${vars.run_date}_03_curate_excluded.json
|
|
329
|
+
Deliver both JSON files with your file-write tool (headless agy sandbox blocks shell writes).
|
|
365
330
|
expectFile: ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json
|
|
366
331
|
allowAppend: false
|
|
367
332
|
|
|
368
|
-
- id:
|
|
369
|
-
description: "
|
|
370
|
-
dependsOn: [qc-content,
|
|
333
|
+
- id: curate-check
|
|
334
|
+
description: "0345 R8: validate the curate split, unwrap any Content envelope, and dedup near-duplicate titles; writes _03_curate_errors.json on failure"
|
|
335
|
+
dependsOn: [qc-content, script-style, curate, pool-gate]
|
|
371
336
|
condition:
|
|
372
337
|
kind: shell
|
|
373
338
|
options:
|
|
374
|
-
|
|
375
|
-
command: >-
|
|
376
|
-
test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS
|
|
377
|
-
&& test "${vars.article_write_enabled}" = "true"
|
|
378
|
-
&& ! test -s "${vars.work_dir}/22-article/${vars.run_date}_06_article-write_body.md"
|
|
339
|
+
command: 'test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS'
|
|
379
340
|
action:
|
|
380
|
-
kind:
|
|
381
|
-
# 0238 R2: a stochastic executor no-op must not end the run here — the retry sibling decides.
|
|
341
|
+
kind: shell
|
|
382
342
|
onError: continue
|
|
383
343
|
options:
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
# ADR-115 error tier: keep this prompt <= 1000 chars. No title line: the canonical episode
|
|
387
|
-
# title is computed by daily-article-gen (0189 R4).
|
|
388
|
-
# The anchor is shared with article-write-retry so the two attempts cannot drift apart.
|
|
389
|
-
input: &article-write-input |
|
|
390
|
-
Read ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json — metadata.docs (Doc[]) is the translated plan; don't edit it.
|
|
391
|
-
Write vivid simplified-Chinese tech news for 咸话咸说之每日AI乱炖 (column 每日AI乱炖, host Robin). No title line. Open with exactly「这里是由Robin为你带来的咸话咸说之每日AI乱炖」。Never「我是咸话咸说」or an AI-production footer. Each ## section: what happened, why it matters, one concrete detail — a human reporter, not a telegram. Inline [来源:<label>](<sourceUri>). Close by tying the items together.
|
|
392
|
-
选题边界:只写技术内容;某条主线若属政治/外交或贸易管制/军事/公共政策争议/社会公共事件,跳过该条并在文末加一行「> 注:<N> 条条目因选题边界未写入:<id>(<原因>)、<id>(<原因>)」。
|
|
393
|
-
事实纪律:每个事实取自该条计划内容,不虚构、不引他处;数字与主体不得放大;引语只能归属其原句主语;保留「据报道/称/承诺」等限定词;导语/收束不加计划外程度词;材料不足就少写或不写,不凑数。
|
|
394
|
-
Narrative register — smooth transitions, no list-like bulleting, no scaffold labels (「可做角度」「背景」「潜在影响」), no hedging (「读者宜另行核实」「仍待验证」). 「」 quotes.
|
|
395
|
-
Output the markdown to ${vars.work_dir}/22-article/${vars.run_date}_06_article-write_body.md.
|
|
396
|
-
expectFile: ${vars.work_dir}/22-article/${vars.run_date}_06_article-write_body.md
|
|
397
|
-
allowAppend: false
|
|
344
|
+
command: >-
|
|
345
|
+
kk stage daily-curate-check "${vars.work_dir}" "${vars.run_date}"
|
|
398
346
|
|
|
399
|
-
- id:
|
|
400
|
-
description:
|
|
401
|
-
|
|
402
|
-
expectFile, retries the same input on a different tier, and carries NO onError — a second miss
|
|
403
|
-
fails the run loudly instead of publishing an article nobody wrote.
|
|
404
|
-
dependsOn: [article-write, pool-gate]
|
|
347
|
+
- id: curate-fix
|
|
348
|
+
description: "0345 R8: one targeted kk:news-editorial `curate --fix` pass on curate-check errors"
|
|
349
|
+
dependsOn: [curate-check, pool-gate]
|
|
405
350
|
condition:
|
|
406
351
|
kind: shell
|
|
407
352
|
options:
|
|
408
|
-
# 0324 R3: the pool verdict is `pool-gate`'s token, never a repeated `kk store pool-count`.
|
|
409
353
|
command: >-
|
|
410
354
|
test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS
|
|
411
|
-
&& test "${vars.
|
|
412
|
-
&& ! test -s "${vars.work_dir}/22-article/${vars.run_date}_06_article-write_body.md"
|
|
355
|
+
&& test -s "${vars.work_dir}/21-plan/${vars.run_date}_03_curate_errors.json"
|
|
413
356
|
action:
|
|
414
357
|
kind: agent.run
|
|
358
|
+
onError: continue
|
|
415
359
|
options:
|
|
416
360
|
role: reviewer
|
|
417
361
|
agent: ${vars.agent_retry}
|
|
418
|
-
|
|
419
|
-
|
|
362
|
+
timeoutMs: 600000
|
|
363
|
+
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
364
|
+
input: |
|
|
365
|
+
Follow mode `curate --fix` in ${vars.work_dir}/20-editorial/news-editorial/SKILL.md (read references/selection.md and references/style-contract.zh.md first).
|
|
366
|
+
--in ${vars.work_dir}/21-plan/${vars.run_date}_04_quality-control-content_candidates.json (metadata.docs is the candidate Doc[]; don't edit it)
|
|
367
|
+
--fix ${vars.work_dir}/21-plan/${vars.run_date}_03_curate_errors.json
|
|
368
|
+
--out-plan ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json
|
|
369
|
+
--out-excluded ${vars.work_dir}/21-plan/${vars.run_date}_03_curate_excluded.json
|
|
370
|
+
Deliver both corrected JSON files with your file-write tool.
|
|
371
|
+
expectFile: ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json
|
|
420
372
|
allowAppend: false
|
|
421
373
|
|
|
422
|
-
- id:
|
|
423
|
-
description:
|
|
424
|
-
|
|
425
|
-
Depends on the QC candidates (so the prose/translate nodes can be disabled without skipping
|
|
426
|
-
this node: a done dependency in the mix keeps it runnable) as well as on both authoring nodes
|
|
427
|
-
AND their retry siblings, and it carries the same candidates guard — a pool that filtered to
|
|
428
|
-
zero items must not build an empty article.
|
|
429
|
-
dependsOn: [qc-content, plan-translate, plan-translate-retry, article-write, article-write-retry, pool-gate]
|
|
374
|
+
- id: curate-final
|
|
375
|
+
description: "0345 R8: final curate validation; falls back to untranslated candidates with [] exclusions if still invalid"
|
|
376
|
+
dependsOn: [curate-check, curate-fix, pool-gate]
|
|
430
377
|
condition:
|
|
431
378
|
kind: shell
|
|
432
379
|
options:
|
|
433
|
-
# 0324 R3: the pool verdict is `pool-gate`'s token, never a repeated `kk store pool-count`.
|
|
434
380
|
command: 'test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS'
|
|
435
381
|
action:
|
|
436
382
|
kind: shell
|
|
437
383
|
options:
|
|
438
384
|
command: >-
|
|
439
|
-
kk stage daily-
|
|
385
|
+
kk stage daily-curate-check "${vars.work_dir}" "${vars.run_date}" --final
|
|
440
386
|
|
|
441
|
-
- id:
|
|
442
|
-
description: "Author the cover
|
|
443
|
-
|
|
444
|
-
# producers settle. `qc-content` stays in the list: a done dependency in the mix keeps this node
|
|
445
|
-
# runnable when the plan-authoring nodes are disabled (all-skipped deps skip a node).
|
|
446
|
-
dependsOn: [qc-content, plan-translate, plan-translate-retry, pool-gate]
|
|
387
|
+
- id: script-write
|
|
388
|
+
description: "Author the master script plan (intro/outro, lead/insight/card per doc id, cover, cards, social, excluded) from the curated plan via agent.run; onError: continue — a failed plan falls back to templates (F613, 0345 R9/R10)"
|
|
389
|
+
dependsOn: [script-style, curate-final, pool-gate]
|
|
447
390
|
condition:
|
|
448
391
|
kind: shell
|
|
449
392
|
options:
|
|
450
393
|
# 0324 R3: the pool verdict is `pool-gate`'s token, never a repeated `kk store pool-count`.
|
|
451
394
|
command: >-
|
|
452
395
|
test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS
|
|
453
|
-
&& test "${vars.
|
|
454
|
-
&& test
|
|
396
|
+
&& test "${vars.script_write_enabled}" = "true"
|
|
397
|
+
&& test "${vars.language}" = "zh"
|
|
398
|
+
&& ! test -s "${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json"
|
|
455
399
|
action:
|
|
456
400
|
kind: agent.run
|
|
457
|
-
# A bad or failed brief must never halt the run: the stage falls back to the format's default
|
|
458
|
-
# subject and keeps the same pinned format/style/provider/model.
|
|
459
401
|
onError: continue
|
|
460
402
|
options:
|
|
461
403
|
role: scribe
|
|
462
404
|
agent: ${vars.agent}
|
|
405
|
+
timeoutMs: 600000
|
|
463
406
|
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
464
407
|
input: |
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
Output
|
|
470
|
-
expectFile: ${vars.work_dir}/
|
|
408
|
+
Follow mode `write` in ${vars.work_dir}/20-editorial/news-editorial/SKILL.md (ADR-045: the kk:news-editorial skill owns selection, balance, style contract and the master output shape; read its references first).
|
|
409
|
+
--in ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json (don't edit it)
|
|
410
|
+
--excluded ${vars.work_dir}/21-plan/${vars.run_date}_03_curate_excluded.json
|
|
411
|
+
--out ${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json
|
|
412
|
+
Output only the JSON file.
|
|
413
|
+
expectFile: ${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json
|
|
471
414
|
allowAppend: false
|
|
472
415
|
|
|
473
|
-
- id:
|
|
474
|
-
description: "
|
|
475
|
-
dependsOn: [
|
|
476
|
-
|
|
416
|
+
- id: script-check
|
|
417
|
+
description: "0345 R4: dry-run the dailynews-gen validator on the script plan; writes _08_script-write_errors.json when it is missing or rejected"
|
|
418
|
+
dependsOn: [script-style, script-write, pool-gate]
|
|
419
|
+
condition:
|
|
477
420
|
kind: shell
|
|
478
421
|
options:
|
|
479
422
|
command: >-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
description: "Normalize the rendered cover (dimensions/format pins) so every consumer sees the same asset"
|
|
484
|
-
dependsOn: [cover]
|
|
423
|
+
test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS
|
|
424
|
+
&& test "${vars.script_write_enabled}" = "true"
|
|
425
|
+
&& test "${vars.language}" = "zh"
|
|
485
426
|
action:
|
|
486
427
|
kind: shell
|
|
428
|
+
onError: continue
|
|
487
429
|
options:
|
|
488
430
|
command: >-
|
|
489
|
-
kk stage daily-
|
|
431
|
+
kk stage daily-script-check "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}"
|
|
490
432
|
|
|
491
|
-
- id: script-
|
|
492
|
-
description: "
|
|
493
|
-
dependsOn: [
|
|
433
|
+
- id: script-write-fix
|
|
434
|
+
description: "0345 R4: one targeted kk:news-editorial `write --fix` pass on validator errors; onError: continue — still-rejected plans fall back to templates"
|
|
435
|
+
dependsOn: [script-check, curate-final, pool-gate]
|
|
494
436
|
condition:
|
|
495
437
|
kind: shell
|
|
496
438
|
options:
|
|
497
|
-
|
|
498
|
-
|
|
439
|
+
command: >-
|
|
440
|
+
test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS
|
|
441
|
+
&& test -s "${vars.work_dir}/24-script/${vars.run_date}_08_script-write_errors.json"
|
|
499
442
|
action:
|
|
500
|
-
kind:
|
|
443
|
+
kind: agent.run
|
|
444
|
+
onError: continue
|
|
501
445
|
options:
|
|
502
|
-
|
|
503
|
-
|
|
446
|
+
role: scribe
|
|
447
|
+
agent: ${vars.agent_retry}
|
|
448
|
+
timeoutMs: 600000
|
|
449
|
+
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
450
|
+
input: |
|
|
451
|
+
Follow mode `write --fix` in ${vars.work_dir}/20-editorial/news-editorial/SKILL.md (read its references first).
|
|
452
|
+
--in ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json (don't edit it)
|
|
453
|
+
--excluded ${vars.work_dir}/21-plan/${vars.run_date}_03_curate_excluded.json
|
|
454
|
+
Previous plan (may be absent): ${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json
|
|
455
|
+
--fix ${vars.work_dir}/24-script/${vars.run_date}_08_script-write_errors.json
|
|
456
|
+
--out ${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json (overwrite it with the full corrected plan)
|
|
457
|
+
Output only the JSON file.
|
|
458
|
+
expectFile: ${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json
|
|
459
|
+
allowAppend: false
|
|
504
460
|
|
|
505
|
-
- id:
|
|
506
|
-
description: "
|
|
507
|
-
|
|
508
|
-
# producers settle. `script-style` stays first in the list: a done dependency in the mix keeps
|
|
509
|
-
# this node runnable when the plan-authoring nodes are disabled (all-skipped deps skip a node).
|
|
510
|
-
dependsOn: [script-style, plan-translate, plan-translate-retry, article, pool-gate]
|
|
461
|
+
- id: editorial-judge
|
|
462
|
+
description: "0345 R11: advisory kk:content-judge evaluation of the script plan under the news-balance rubric; nothing depends on it for control flow"
|
|
463
|
+
dependsOn: [script-check, script-write-fix, curate-final, pool-gate]
|
|
511
464
|
condition:
|
|
512
465
|
kind: shell
|
|
513
466
|
options:
|
|
514
|
-
# 0324 R3: the pool verdict is `pool-gate`'s token, never a repeated `kk store pool-count`.
|
|
515
467
|
command: >-
|
|
516
468
|
test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS
|
|
517
|
-
&& test "${vars.
|
|
518
|
-
&& test "${vars.language}" = "zh"
|
|
519
|
-
&& ! test -s "${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json"
|
|
469
|
+
&& test -s "${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json"
|
|
520
470
|
action:
|
|
521
471
|
kind: agent.run
|
|
522
472
|
onError: continue
|
|
523
473
|
options:
|
|
524
|
-
role:
|
|
474
|
+
role: reviewer
|
|
525
475
|
agent: ${vars.agent}
|
|
476
|
+
timeoutMs: 600000
|
|
526
477
|
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
527
478
|
input: |
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
479
|
+
You are an LLM-as-judge evaluating a daily news script plan for the knowledge-kit pipeline.
|
|
480
|
+
Content to evaluate: ${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json
|
|
481
|
+
Plan docs reference: ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json
|
|
482
|
+
Rubric: news-balance
|
|
483
|
+
Output verdict to: ${vars.work_dir}/24-script/${vars.run_date}_08_editorial-judge_verdict.json
|
|
484
|
+
Load the rubric definition from plugins/kk/skills/content-judge/references/rubrics.md (section: news-balance) and the contract from plugins/kk/skills/content-judge/SKILL.md.
|
|
485
|
+
Evaluate the script plan against every criterion in news-balance (news-first, commentary-share, no-restatement, tech-depth, ordering).
|
|
486
|
+
Write the verdict JSON (with confidence HIGH | MEDIUM | LOW) to ${vars.work_dir}/24-script/${vars.run_date}_08_editorial-judge_verdict.json.
|
|
487
|
+
expectFile: ${vars.work_dir}/24-script/${vars.run_date}_08_editorial-judge_verdict.json
|
|
533
488
|
allowAppend: false
|
|
534
489
|
|
|
535
490
|
- id: script
|
|
536
491
|
description: >-
|
|
537
492
|
Compile the episode plan Doc[] into structured broadcast VoiceScript YAML Content. Depends on
|
|
538
|
-
`
|
|
493
|
+
`curate-final` so the node still runs when the plan-authoring nodes were disabled or skipped (the
|
|
539
494
|
builder falls back to templates) — but not when the whole content branch is skipped.
|
|
540
|
-
dependsOn: [
|
|
495
|
+
dependsOn: [curate-final, script-style, script-write, script-check, script-write-fix, pool-gate]
|
|
541
496
|
condition:
|
|
542
497
|
kind: shell
|
|
543
498
|
options:
|
|
@@ -549,6 +504,59 @@ nodes:
|
|
|
549
504
|
command: >-
|
|
550
505
|
kk stage daily-script "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.language}" "${vars.title}" "${vars.voice_profile}" "${vars.episode_max_minutes}" "${vars.vdriver}"
|
|
551
506
|
|
|
507
|
+
- id: editorial-render
|
|
508
|
+
description: "0345 R10: deterministically render the prose article body, cover brief, XHS card plan and social posts from the master script plan and curated plan"
|
|
509
|
+
dependsOn: [script, curate-final, pool-gate]
|
|
510
|
+
condition:
|
|
511
|
+
kind: shell
|
|
512
|
+
options:
|
|
513
|
+
command: 'test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS'
|
|
514
|
+
action:
|
|
515
|
+
kind: shell
|
|
516
|
+
options:
|
|
517
|
+
command: >-
|
|
518
|
+
kk stage daily-editorial-render "${vars.work_dir}" "${vars.run_date}" "${vars.cards_enabled}" "${vars.cards}"
|
|
519
|
+
|
|
520
|
+
- id: article
|
|
521
|
+
description: >-
|
|
522
|
+
Generate the dated daily article Content from the episode plan and rendered article body (daily-article-gen).
|
|
523
|
+
dependsOn: [qc-content, curate-final, editorial-render, pool-gate]
|
|
524
|
+
condition:
|
|
525
|
+
kind: shell
|
|
526
|
+
options:
|
|
527
|
+
# 0324 R3: the pool verdict is `pool-gate`'s token, never a repeated `kk store pool-count`.
|
|
528
|
+
command: 'test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS'
|
|
529
|
+
action:
|
|
530
|
+
kind: shell
|
|
531
|
+
options:
|
|
532
|
+
command: >-
|
|
533
|
+
kk stage daily-article "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}"
|
|
534
|
+
|
|
535
|
+
- id: cover
|
|
536
|
+
description: "Render the daily cover through the pinned daily-news presets (F614)"
|
|
537
|
+
dependsOn: [editorial-render, pool-gate]
|
|
538
|
+
condition:
|
|
539
|
+
kind: shell
|
|
540
|
+
options:
|
|
541
|
+
command: >-
|
|
542
|
+
test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS
|
|
543
|
+
&& test "${vars.cover_enabled}" = "true"
|
|
544
|
+
&& test ! -f "${vars.work_dir}/23-cover/${vars.run_date}_07_cover_cover.png"
|
|
545
|
+
action:
|
|
546
|
+
kind: shell
|
|
547
|
+
options:
|
|
548
|
+
command: >-
|
|
549
|
+
kk stage daily-cover "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.cover_provider}" "${vars.cover_model}" "${vars.cover_fallback}"
|
|
550
|
+
|
|
551
|
+
- id: cover-normalize
|
|
552
|
+
description: "Normalize the rendered cover (dimensions/format pins) so every consumer sees the same asset"
|
|
553
|
+
dependsOn: [cover]
|
|
554
|
+
action:
|
|
555
|
+
kind: shell
|
|
556
|
+
options:
|
|
557
|
+
command: >-
|
|
558
|
+
kk stage daily-cover-normalize "${vars.work_dir}" "${vars.run_date}"
|
|
559
|
+
|
|
552
560
|
# ---- content safety: a nested state machine (no sub-workflow action exists; ADR-031) ----
|
|
553
561
|
|
|
554
562
|
- id: safety
|
|
@@ -560,7 +568,7 @@ nodes:
|
|
|
560
568
|
runner strips, kk-workflow-stages.ts): without it `spur workflow run` refuses to start inside
|
|
561
569
|
an active run. voice3 always runs the gate: it is the only check between an LLM draft and a
|
|
562
570
|
published post.
|
|
563
|
-
dependsOn: [script]
|
|
571
|
+
dependsOn: [article, script]
|
|
564
572
|
action:
|
|
565
573
|
kind: shell
|
|
566
574
|
options:
|
|
@@ -729,7 +737,7 @@ nodes:
|
|
|
729
737
|
description: >-
|
|
730
738
|
Render timeline show notes from the episode plan — content, not publishing: the publish half
|
|
731
739
|
ships them as the episode variant's `metadata.showNotes`, and the link placeholders stay
|
|
732
|
-
unresolved until a send resolves them.
|
|
740
|
+
unresolved until a send resolves them.
|
|
733
741
|
dependsOn: [quality, pool-gate]
|
|
734
742
|
condition:
|
|
735
743
|
kind: shell
|
|
@@ -764,36 +772,11 @@ nodes:
|
|
|
764
772
|
options:
|
|
765
773
|
command: >-
|
|
766
774
|
kk stage daily-publish-prep "${vars.work_dir}" "${vars.run_date}" "${vars.podcast_artist}" "${vars.podcast_album}"
|
|
767
|
-
- id: cards-write
|
|
768
|
-
description: "Plan the card series across the episode's plan items via agent.run; onError: continue — a failed plan skips the card series, never the run"
|
|
769
|
-
dependsOn: [script, review, pool-gate]
|
|
770
|
-
condition:
|
|
771
|
-
kind: shell
|
|
772
|
-
options:
|
|
773
|
-
command: 'test "${vars.cards_enabled}" = "true" && test "$(cat ".spur/run/${vars.__runId}-pool-gate.status" 2>/dev/null)" = PASS'
|
|
774
|
-
action:
|
|
775
|
-
kind: agent.run
|
|
776
|
-
onError: continue
|
|
777
|
-
options:
|
|
778
|
-
role: scribe
|
|
779
|
-
agent: ${vars.agent}
|
|
780
|
-
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
781
|
-
input: |
|
|
782
|
-
Read ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json — a JSON array of news docs; don't edit it.
|
|
783
|
-
Plan the whole episode, not the lead item alone. Card 1 is the episode hook.
|
|
784
|
-
Write a card note: "title" (≤20 chars) and "body" (Chinese lead paragraph + 3-5 hashtags) — the stage appends one numbered line per image below it. 选题边界:公共事务主线不写入,只写技术内容。
|
|
785
|
-
Write exactly ${vars.cards} cards in plan order: card 1 "cover"; one "content" card per plan item, up to ${vars.cards} - 2 of them; the last "closing". Each card carries "role", "copy" (Chinese headline ≤12 chars), "points" (2-4 short Chinese bullets), "layout", "subject" (one concrete English visual scene), "sourcePoint" (that item's fact) and "itemId" (its "id").
|
|
786
|
-
Ground every field in that item — no invented facts. No writing, letters, numbers, logos or people; screens stay blank.
|
|
787
|
-
Output strictly valid JSON {"title": "...", "body": "...", "cards": [...]} to ${vars.work_dir}/25-xhs/${vars.run_date}_18_xhs_plan.json.
|
|
788
|
-
expectFile: ${vars.work_dir}/25-xhs/${vars.run_date}_18_xhs_plan.json
|
|
789
|
-
allowAppend: false
|
|
790
|
-
|
|
791
775
|
- id: cards-render
|
|
792
776
|
description: "Render the card series through the pinned xhs-card/xhs-knowledge presets, attach the episode cover last and pair every image with its numbered line (0235 note_scope=episode); onError: continue — the publish node names the missing series and stays soft"
|
|
793
|
-
dependsOn: [
|
|
794
|
-
#
|
|
795
|
-
#
|
|
796
|
-
# The pool guard is `pool-gate`'s alone in voice3 (0324 R3).
|
|
777
|
+
dependsOn: [editorial-render, review, pool-gate]
|
|
778
|
+
# Each card node keeps its own switch: without it a run with cards_enabled=false would
|
|
779
|
+
# re-package a stale same-day 25-xhs/ series. The pool guard is `pool-gate`'s alone in voice3 (0324 R3).
|
|
797
780
|
condition:
|
|
798
781
|
kind: shell
|
|
799
782
|
options:
|
|
@@ -807,31 +790,6 @@ nodes:
|
|
|
807
790
|
|
|
808
791
|
# ---- generate-side payloads and the frozen bundle (0324 R2/R3) ----
|
|
809
792
|
|
|
810
|
-
- id: social-write
|
|
811
|
-
description: >-
|
|
812
|
-
Author one short post per social platform (x, weibo, threads, linkedin) from the approved
|
|
813
|
-
plan, in zh, inside each platform's character cap. `daily-bundle-variants` truncates as a
|
|
814
|
-
backstop, so a missed cap degrades rather than fails; a missing file simply skips that
|
|
815
|
-
platform's variant.
|
|
816
|
-
dependsOn: [quality]
|
|
817
|
-
action:
|
|
818
|
-
kind: agent.run
|
|
819
|
-
onError: continue
|
|
820
|
-
options:
|
|
821
|
-
role: scribe
|
|
822
|
-
agent: ${vars.agent}
|
|
823
|
-
input: |
|
|
824
|
-
Read the approved episode plan at ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json.
|
|
825
|
-
Write four short zh posts, one per file:
|
|
826
|
-
- ${vars.work_dir}/26-social/x.md — at most 280 weighted characters (this feed counts CJK as 2, so ~140 汉字 or 280 Latin letters)
|
|
827
|
-
- ${vars.work_dir}/26-social/weibo.md — at most 2000 characters
|
|
828
|
-
- ${vars.work_dir}/26-social/threads.md — at most 500 characters
|
|
829
|
-
- ${vars.work_dir}/26-social/linkedin.md — at most 3000 characters
|
|
830
|
-
Each post: the day's single most interesting item, one concrete number or name from the
|
|
831
|
-
plan, no hashtag spam, no emoji, no "点击链接", no invented facts. Plain text, no markdown
|
|
832
|
-
headings. Deliver with your file-write tool; each file must be non-empty.
|
|
833
|
-
expectFile: ${vars.work_dir}/26-social/x.md
|
|
834
|
-
|
|
835
793
|
- id: bundle-variants
|
|
836
794
|
description: >-
|
|
837
795
|
Build the channel payloads from the run's own artifacts (0327 builders): `30-variants/<key>`
|
|
@@ -840,7 +798,7 @@ nodes:
|
|
|
840
798
|
F16: depends on every producer it reads (the 0324 file order alone was not a guarantee),
|
|
841
799
|
wipes stale variants first, and follows the cards/cover switches so a disabled producer's
|
|
842
800
|
variant is a skip, not a stale re-read.
|
|
843
|
-
dependsOn: [quality,
|
|
801
|
+
dependsOn: [quality, editorial-render, publish-prep, cover-normalize, cards-render, pool-gate]
|
|
844
802
|
condition:
|
|
845
803
|
kind: shell
|
|
846
804
|
options:
|
|
@@ -934,9 +892,12 @@ nodes:
|
|
|
934
892
|
--vars "{\"work_dir\":\"${vars.work_dir}\",\"run_date\":\"${vars.run_date}\",\"window\":\"${vars.publish_window}\",\"preset\":\"${vars.publish_preset}\",\"dummy\":\"${vars.publish_dummy}\",\"live_channels\":\"${vars.publish_live_channels}\"}"
|
|
935
893
|
|
|
936
894
|
- id: ledger
|
|
937
|
-
description:
|
|
895
|
+
description: >-
|
|
896
|
+
Backfill the voice3 ledger with every finished run it does not record yet (an in-run
|
|
897
|
+
`kk ledger append` of this run always refuses with `kk.ledger.run.running`; the scheduled
|
|
898
|
+
wrapper's post-run sync records this one). `|| true` — bookkeeping never fails a generation.
|
|
938
899
|
dependsOn: [generation-report, publish]
|
|
939
900
|
action:
|
|
940
901
|
kind: shell
|
|
941
902
|
options:
|
|
942
|
-
command: 'kk ledger
|
|
903
|
+
command: 'kk ledger sync --workflow kk-daily-ai-voice3 || true'
|