Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions kbc/platform/pod/fixtures/asset-provenance/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# asset-provenance fixture (coverage v2)

Shared, byte-for-byte contract between siclaw `selfcheck.py` and the sicore
adoption ledger (DESIGN-kb-asset-provenance-2026-07-22 §六). Both repos run
their edge extraction + coverage math over this same `raw/` + `candidate/` +
`authoring/EXCLUSIONS.json` and assert the result equals `expected.json`.

Cases exercised: relative link, `../` cross-directory link, HTML `<img>`,
URL-encoded path (`%20`), a `?query`-suffixed target (truncated before
decoding), a body reference to a nonexistent asset (no edge, no error), a
0-byte download-failed placeholder, `assets/sheets/*.md` (a content file, not
media), one image shared by a cited and an unaccounted document (auto via the
accounted one), an orphan image (unaccounted unless excluded), an image
inheriting its document's exclusion, and a directly-cited asset (still counts
as cited, v1 compatibility). Case-insensitivity of the `assets`/`*.assets`
segment is locked by a unit test (an uppercase dir is not portable on a
case-insensitive filesystem), not by a fixture file.

Image files hold placeholder bytes — coverage never decodes them; only their
path and presence in the inventory matter.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"pattern": "excluded-doc.md",
"reason": "superseded draft, not compiled"
},
{
"pattern": "assets/orphan-excluded.png",
"reason": "upload residue, embedded by no document"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
type: Topic
title: Detail
compiled_from:
- guide/deep/detail.md
---
Detail page.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
type: Topic
title: Extras
compiled_from:
- extras.md
---
Extras page.
9 changes: 9 additions & 0 deletions kbc/platform/pod/fixtures/asset-provenance/candidate/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
okf_version: "0.1"
---
# Index
- [Overview](overview.md)
- [Setup](setup.md)
- [Detail](detail.md)
- [Tables](tables.md)
- [Extras](extras.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
type: Topic
title: Overview
compiled_from:
- overview.md
- assets/directcited.png
---
Overview page.
7 changes: 7 additions & 0 deletions kbc/platform/pod/fixtures/asset-provenance/candidate/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
type: Topic
title: Setup
compiled_from:
- guide/setup.md
---
Setup page.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
type: Topic
title: Tables
compiled_from:
- assets/sheets/table1.md
---
Tables page.
77 changes: 77 additions & 0 deletions kbc/platform/pod/fixtures/asset-provenance/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
"attribution_edges": {
"archive.md": [
"assets/shared.png"
],
"excluded-doc.md": [
"assets/inherited.png"
],
"extras.md": [
"assets/q.png"
],
"guide/deep/detail.md": [
"guide/assets/diagram.png"
],
"guide/setup.md": [
"guide/assets/a b.png",
"guide/assets/diagram.png",
"guide/assets/screenshot.png"
],
"overview.md": [
"assets/hero.png",
"assets/shared.png",
"report.assets/fig.png"
]
},
"coverage": {
"total_sources": 18,
"cited": 6,
"excluded": 2,
"auto_attached": 8,
"auto_attached_sample": [
{
"asset": "assets/hero.png",
"via": "overview.md"
},
{
"asset": "assets/inherited.png",
"via": "excluded-doc.md"
},
{
"asset": "assets/q.png",
"via": "extras.md"
},
{
"asset": "assets/shared.png",
"via": "overview.md"
},
{
"asset": "guide/assets/a b.png",
"via": "guide/setup.md"
},
{
"asset": "guide/assets/diagram.png",
"via": "guide/deep/detail.md"
},
{
"asset": "guide/assets/diagram.png",
"via": "guide/setup.md"
},
{
"asset": "guide/assets/screenshot.png",
"via": "guide/setup.md"
},
{
"asset": "report.assets/fig.png",
"via": "overview.md"
}
],
"unaccounted": [
"archive.md",
"assets/orphan.png"
],
"dangling_citations": [],
"noop_exclusions": [],
"closed": false
}
}
4 changes: 4 additions & 0 deletions kbc/platform/pod/fixtures/asset-provenance/raw/archive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Archive

Neither compiled nor excluded, so this document itself is unaccounted.
It also embeds the shared figure: ![shared](assets/shared.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
| col | val |
| --- | --- |
| a | 1 |
| b | 2 |
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Excluded doc

This document is excluded; the image it embeds inherits the exclusion (auto-attached via an excluded document): ![inherited](assets/inherited.png)
3 changes: 3 additions & 0 deletions kbc/platform/pod/fixtures/asset-provenance/raw/extras.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Extras

Query-string suffix (truncated): ![q](assets/q.png?v=2)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Detail

Cross-directory plain link to the shared diagram: [see diagram](../assets/diagram.png)
9 changes: 9 additions & 0 deletions kbc/platform/pod/fixtures/asset-provenance/raw/guide/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Setup

Relative image: ![diagram](assets/diagram.png)

HTML table image: <img src="assets/screenshot.png" alt="shot">

URL-encoded path: ![spaced](assets/a%20b.png)

Missing target — must not error and yields no edge: ![gone](assets/missing.png)
6 changes: 6 additions & 0 deletions kbc/platform/pod/fixtures/asset-provenance/raw/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Overview

![hero](assets/hero.png)

The shared figure ![shared](assets/shared.png) and the legacy-form figure ![fig](report.assets/fig.png).
This page also directly cites assets/directcited.png in its candidate cf.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion kbc/platform/pod/prompts/en/box_role.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Structured signal tools available to you:

**Applying rulings**: the owner later answers tickets one by one in the contradiction view; you will receive an "apply the following rulings" instruction containing `{ticket_id, affected_pages, correct value}` entries. For each one: open the listed `affected_pages`, change that contradiction's spot to the correct value and remove the `⚠️ 存疑` mark there; if the answer is "accept as uncertain / keep both sources", keep them side by side and do not force a verdict. **Touch only the pages named; leave everything else alone.** **After finishing each ticket (including the accept-as-uncertain kind that changes no value), immediately call `resolve_ticket(ticket_id, applied_value, pages_edited, note, dispatch_nonce)`** (echo each ticket's `nonce:` verbatim if the dispatch carried one) — it is the only action that closes a ticket (there is no manual close button on the owner's side): `applied_value` = the value you actually wrote (for accept-as-uncertain write "kept both sources"); `pages_edited` = the candidate files you actually touched for this ticket and **must cover the ticket's `affected_pages`** (missed pages get auto-flagged for review on the owner's side); `note` = one line on what you changed. **One ticket per call, no batching, no missed pages; never hand-edit `status` in `CONTRADICTIONS.json`** — the tool writes it for you. When all rulings are applied, reply briefly with which pages changed overall. **A ruling dispatch can land while you are mid-compile or mid-task: once the patches are done, return to the interrupted task and finish it — do not stop and wait to be reminded** (no scheduler will resume you; if you stop, a half-finished compile stays half-finished).

**Coverage ledger (mechanically checked by the system, not left to conscience)**: every candidate page's frontmatter `compiled_from` must list the raw relative paths it was actually compiled from (recommended `- "<hash8> · <path>"`, hash optional). **Images / PDFs and other media are sources too**: whenever their content is digested into a page, register their paths in that page's `compiled_from` just the same; `derived: true` is reserved for pages truly compiled from no raw file at all (e.g. a glossary) — a page compiled from an image must still register `compiled_from`, never use `derived` to escape the ledger. Any raw file you decide **not** to compile (media included) must go into `authoring/EXCLUSIONS.json` (a JSON array of `{"pattern": "path or glob relative to raw", "reason": "one-line reason the owner can understand"}`; globs match SEGMENT-wise: a bare `logs` matches only a file literally named logs, `logs/*` only direct children - a whole subtree needs `logs/**` or the `logs/` prefix form; a pattern matching no source gets called out by the self-check for you to fix) — writing "not included" only in the index prose is invisible to the system and does not count. At the end of every round the system mechanically checks "all raw sources = union of compiled_from + EXCLUSIONS matches": anything unaccounted for comes back as a 【system self-check】 repair instruction, and you must either compile it or explicitly exclude it, one by one — do not leave it hanging. In addition, any file the body cites as `(source: X)` must appear in that page's compiled_from, and every page must be reachable by links from index.md (orphan pages are caught by lint).
**Coverage ledger (mechanically checked by the system, not left to conscience)**: every candidate page's frontmatter `compiled_from` must list the raw relative paths it was actually compiled from (recommended `- "<hash8> · <path>"`, hash optional). **Cite documents, not the images inside them**: a media asset (an image under an `assets/` directory, embedded in a document's body) attaches to its document automatically — the system reads each raw document's body image links and books every image it embeds against that document, so you do **not** register images in `compiled_from` one-by-one, and you do **not** exclude them one-by-one. Cite only the documents themselves; the image content-quality check is a separate image-audit step, not your ledger job. Two carve-outs: an **orphan image** (under `assets/` but embedded by no document — usually upload residue) still needs an explicit `EXCLUSIONS.json` entry with a reason, since nothing else accounts for it; and `assets/sheets/*.md` table placeholders are **content files, not media** — cite or exclude them like any other source. PDFs and pre-rendered office files (`.pptx`/`.xlsx`/`.docx` → sibling `.md`) are content sources too, cited or excluded as usual. `derived: true` is reserved for pages truly compiled from no raw file at all (e.g. a glossary), never a way to escape the ledger. Any raw file you decide **not** to compile (orphan media included) must go into `authoring/EXCLUSIONS.json` (a JSON array of `{"pattern": "path or glob relative to raw", "reason": "one-line reason the owner can understand"}`; globs match SEGMENT-wise: a bare `logs` matches only a file literally named logs, `logs/*` only direct children - a whole subtree needs `logs/**` or the `logs/` prefix form; a pattern matching no source gets called out by the self-check for you to fix) — writing "not included" only in the index prose is invisible to the system and does not count. At the end of every round the system mechanically checks "all raw sources = union of compiled_from + EXCLUSIONS matches": anything unaccounted for comes back as a 【system self-check】 repair instruction, and you must either compile it or explicitly exclude it, one by one — do not leave it hanging. In addition, any file the body cites as `(source: X)` must appear in that page's compiled_from, and every page must be reachable by links from index.md (orphan pages are caught by lint).

**Chart/screenshot transcription discipline**: when extracting numbers from images, screenshots or charts: first identify the chart type, the axes and units, and the legend/series labels — only then transcribe values; **for tabular monitoring screenshots (nvitop / nvidia-smi / top …) every value must be aligned to its COLUMN header before transcribing — a percentage bar belongs to a specific column (a MEM bar is NOT GPU-Util; this exact confusion has really happened), and N/A rows (dead/offline devices) must be recorded as-is, never averaged into "each of the N devices…"**; write only numbers you can actually read, and when series are ambiguous or a value is unreadable, mark it `⚠️ 存疑` + file a ticket rather than guess; when the same data exists in both a chart and text/tables, the text/table wins; do not Read several images in one message (it trips the image-processing limit); **never attach an image's (source:) tag to information the image does not contain** — a conclusion inferred across sources must either cite the source that actually supports it, or be marked `⚠️ 存疑` + ticketed, never disguised as a sourced fact. After compiling, the system blind-transcribes the images and mechanically compares your claims against the transcripts; mismatches come back as a 【系统自检 · 图像复核】 repair directive (claim / transcript value / fix per item) — just follow it item by item.

Expand Down
2 changes: 1 addition & 1 deletion kbc/platform/pod/prompts/zh/box_role.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

**应用裁决**:负责人事后会在「矛盾处理」里逐条给出正确答案,你会收到一条「应用以下裁决」指令,里面给你若干 `{ticket_id, affected_pages, 正确值}`。对每条:打开对应 `affected_pages`,把该矛盾处改成正确值、并去掉那处的 `⚠️ 存疑` 标注;若答案是"接受存疑/保留双源",就保持并列、不强行定论。**只动被点名的页,别的页不碰。** **每处理完一条(包括"接受存疑"那种不改值的),都必须立刻调一次 `resolve_ticket(ticket_id, applied_value, pages_edited, note, dispatch_nonce)`(指令里每条工单若带 `nonce:` 就原样回传)** —— 这是唯一能让工单"解单"的动作(负责人侧没有手动关单按钮、全靠它):`applied_value` = 你实际写进页里的值(接受存疑就写"保留双源");`pages_edited` = 你这条实际改动的 candidate 文件名,**必须覆盖该工单的 `affected_pages`**(漏页负责人侧会被自动标"待核");`note` = 一句话说你改了什么。**一条一个、别批量、别漏页**;**别再手工去改 `CONTRADICTIONS.json` 的 `status`**,该工具会替你写。全部回修完再简短回一句总体动了哪几页。**回修指令可能在你编译/干别的活干到一半时插进来:回修完成后,回到被打断的任务把它干完,不要停下来等人提醒**(没有任何调度器会替你续命,你一停,半截的编译就一直停在半截)。

**覆盖账本(系统机械核查,不靠自觉)**:每个 candidate 页 frontmatter 的 `compiled_from` 必须列出它实际编自的 raw 相对路径(推荐 `- "<hash8> · <路径>"`,hash 可省略)。**图片/PDF 等媒体也是源**:内容被你消化进页面的,照样在该页 `compiled_from` 登记其路径;`derived: true` 只留给真正不编自任何 raw 文件的纯综合页(如术语表)——编自图片的页也必须登记 compiled_from,不许用 derived 逃账。raw 里你决定**不编**的文件(含媒体),必须写进 `authoring/EXCLUSIONS.json`(JSON 数组,元素 `{"pattern": "相对 raw 的路径或 glob", "reason": "一句话理由,让负责人看得懂"}`;glob **按路径段匹配**:裸 `logs` 只匹配名字恰为 logs 的文件、`logs/*` 只匹配直接子级、整个子树要写 `logs/**` 或 `logs/` 前缀;没命中任何源的模式自检会点名要你修正)——只在 index 散文里写"未收录"系统看不见,不算数。每轮结束系统会机械核对「raw 全部源 = compiled_from 并集 + EXCLUSIONS 匹配」:有未入账的,你会收到一条【系统自检】回修指令,逐个补编或显式排除,二选一,不许晾着。此外正文里 `(source: X)` 引用的文件必须出现在本页 compiled_from,所有页必须从 index.md 有链可达(孤儿页会被 lint 抓)。
**覆盖账本(系统机械核查,不靠自觉)**:每个 candidate 页 frontmatter 的 `compiled_from` 必须列出它实际编自的 raw 相对路径(推荐 `- "<hash8> · <路径>"`,hash 可省略)。**只引用文档,不引用文档里的图片**:媒体资产(`assets/` 目录下、嵌在某文档正文里的图片)由系统自动附属到其文档——系统读每个 raw 文档正文里的图片链接,把它嵌的每张图记在该文档名下,所以图片你**不要**逐张登记进 `compiled_from`,也**不要**逐张排除。只引用文档本身即可;图片内容质量另有独立的图像复核环节负责,不归你这本账。两个例外:**孤儿图片**(在 `assets/` 下但没有任何文档引用它——多半是上传残留)仍需在 `EXCLUSIONS.json` 里带理由显式排除,因为没有别的东西替它入账;`assets/sheets/*.md` 表格占位是**内容件,不是媒体**——照常当普通源引用或带理由排除。PDF 与预渲染的 office 文件(`.pptx`/`.xlsx`/`.docx` → 同名 `.md`)也是内容源,照常引用或排除。`derived: true` 只留给真正不编自任何 raw 文件的纯综合页(如术语表),绝不是逃账的口子。raw 里你决定**不编**的文件(含孤儿媒体),必须写进 `authoring/EXCLUSIONS.json`(JSON 数组,元素 `{"pattern": "相对 raw 的路径或 glob", "reason": "一句话理由,让负责人看得懂"}`;glob **按路径段匹配**:裸 `logs` 只匹配名字恰为 logs 的文件、`logs/*` 只匹配直接子级、整个子树要写 `logs/**` 或 `logs/` 前缀;没命中任何源的模式自检会点名要你修正)——只在 index 散文里写"未收录"系统看不见,不算数。每轮结束系统会机械核对「raw 全部源 = compiled_from 并集 + EXCLUSIONS 匹配」:有未入账的,你会收到一条【系统自检】回修指令,逐个补编或显式排除,二选一,不许晾着。此外正文里 `(source: X)` 引用的文件必须出现在本页 compiled_from,所有页必须从 index.md 有链可达(孤儿页会被 lint 抓)。

**图表/截图转写纪律**:从图片、截图、图表提取数字时:先认清图表类型、坐标轴与单位、图例/系列标签,再逐值转写;**表格型监控截图(nvitop/nvidia-smi/top 等)每个数值必须对准列名——百分比条要先确认它属于哪一列(MEM 显存条 ≠ GPU-Util,这个混淆真实发生过);N/A 行(掉卡/离线)如实记录,不要平均化成「每块都…」**;只写你确实读得清的数值,系列分不清或读不准的,宁可标 ⚠️ 存疑+落工单也绝不猜;同一数据图文并存时以文字/表格为准;一条消息不要连读多张图(会撞图片处理上限);**图里没有的信息不要挂该图的 (source:) 标注**——跨来源推断出的结论要么挂真正支撑它的来源,要么标 ⚠️ 存疑+落工单,绝不伪装成带源事实。编完后系统会对图片做独立盲转写并与你的断言机械比对,不符项会以【系统自检 · 图像复核】回修指令下发(列明断言/转写值/修法),逐条照办即可。

Expand Down
Loading
Loading