# Kb Save

> Save a synthesis/comparison/learning-path/self-test candidate from an existing query-session into the wiki as status:proposed (gated, two-phase publish). Use when, after a query, the user says "save that comparison/conclusion into the wiki / form a synthesis / save to the KB / keep this as a note". One-off facts, plain explanations, and restating an existing page are not saved.

- Skill: `iabstergo1/kb-save` (Agent Skill)
- Install (CLI): `npx skillmds@latest add iabstergo1/kb-save`
- Raw SKILL.md: https://api.skillmd.com/api/skills/iabstergo1/kb-save/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Iabstergo1 (https://skillmd.com/u/iabstergo1)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/iabstergo1/kb-save

---


# kb-save — explicit save (the second step of the query → save loop)

Acts on an existing query-session: check the save admission gate first, then write qualifying candidates as
`status: proposed` pages or a Review-Queue proposal. The execution layer is `scripts/pipeline.py`; this
skill only orchestrates, surfaces acceptance, and marks failure stops.

## 1. Triggers / Non-triggers

- **Triggers:** "save that comparison/conclusion into the wiki", "form a synthesis", "save to the KB", "keep this as a note", "write that query-session back".
- **Non-triggers:** one-off facts, plain explanations, translation, source-less speculation, restating an existing page; a direct write request with no query-session (first switch to `kb-query` or ask for a run_id); a new external source (use `ingest`).

## 2. Inputs

- `<run_id>`: the user-named query-session, or the most recent `kb-query` run_id. It must be one direct
  directory name under `query-sessions/`; separators, drive prefixes, `.`/`..`, and path traversal are
  rejected.
- Read: `pipeline-workspace/query-sessions/<run_id>/{question.md,answer.md,related_pages.json,candidate_write_set.json,evidence_refs.json}`; `write_authorizations.json` is created by the write guard.
- Read: `docs/skill-runtime/save-back-policy.md`, `docs/skill-runtime/schema.md`, `docs/skill-runtime/concept-resolution.md`, and the relevant vault pages.

## 3. Outputs

- Below the admission gate: refuse clearly with a reason; write nothing.
- Above the gate: the current direct-write path creates only **new** allowlisted candidate pages; all are `status: proposed` + `managed_by: pipeline`.
- Any existing target (pipeline or human), concept merge, or overwrite request fails closed: write `wiki/Review-Queue/<page>-proposal.md`, do not edit the target. kb-save does not fabricate an ingest workorder to gain overwrite authority.
- Update the query-session: record what was actually written + evidence, and write `decision.md`.

## 4. Dependencies

- CLI: `check-write --source kb-save --session`, `check-session --saved`; the finishing publish is decided by `lint`. `snapshot-page` and write-capable `resolve-concept` remain ingest-only until kb-save has a session overwrite baseline.
- **记账契约（会话作用域 + 内容身份）：** 写下的每个页面必须①列入本 session 的
  `candidate_write_set.json`（处理台账，与 ingest 的窗口 `--writes` 对等），②frontmatter 带
  `save_session: <run_id>`（内容身份——candidate 只记路径，同路径被其他会话重写时靠此标记
  fail-closed，绝不代发他会话内容）。`lint --source kb-save --session <run_id>` 以该会话
  candidate 集**同时决定发布范围与记账**，并与 `write_authorizations.json` 的 new-only 门票
  精确对账；路径缺失/非 proposed/身份不符/授权不符任一即 fail-closed，不得部分发布。历史/未保存/其他 run_id 的会话不得代记账，普通
  ingest 的 lint 也完全不读会话台账；`source_refs` 只定归属，不算记账。kb-save 批次不背
  ingest 阶段 E 义务（overview 重写/L7/topics-missing），vault 级不变量（A2 收编、渲染安全
  preflight）照常。
- **严格清单契约：** `candidate_write_set.json` 必须是非空、无重复、canonical vault 相对路径
  字符串列表；拒绝 `./`、`//`、`..`、反斜杠别名和非字符串值。`write_authorizations.json`
  每项只能含精确键 `{path, mode}`，`mode` 只能是 `"new"`，路径同样 canonical 且唯一；saved
  Q1 要求候选与授权路径一一对应。
- **信任边界：** `write_authorizations.json` 是本机协作流程的可审计账本，不是密码学证明或
  防手工伪造边界。只允许 `check-write` 生成/追加；不得手写、补票或把它描述成防篡改机制。
- Protocols: `save-back-policy.md` (admission gate), `schema.md` (page structure), `concept-resolution.md` (concept resolution).
- Write discipline matches `ingest`: never hand-write derived files (`aliases.md` retired — aliases in frontmatter). A candidate that would create or merge a concept is proposed to Review-Queue in the current new-only mode; never hand-create a duplicate concept. **新建 topic/comparison/synthesis 用中文文件名（与 `title` 一致，如 `comparisons/<甲> vs <乙>.md`）并带 `source_refs` 溯源；正文走高信息密度的学术散文、句式有起伏、结构由 purpose 与内容自然决定（不再有强制小节标题，D-4）；发布正文不嵌源图（D-1）——见 `ingest` 的 `write-pages.md`「写作风格」与「页面文件名用中文」。**

## 5. Persisted artifacts

- `pipeline-workspace/query-sessions/<run_id>/decision.md`: why saved / which pages written / which evidence cited / why no existing concept was polluted.
- `candidate_write_set.json`: updated to the pages actually/intended written.
- `evidence_refs.json`: completed with the evidence actually used.
- `write_authorizations.json`: generated by `check-write`, one `{path, mode: "new"}` per candidate.
- vault proposed pages or `wiki/Review-Queue/*-proposal.md`.

## 6. CLI commands

```text
python scripts/pipeline.py check-write --source kb-save --session <run_id> --path <vault-rel-path>
python scripts/pipeline.py check-session --id <run_id> --saved
```

After saving, prompt the user to run `python scripts/pipeline.py lint --source kb-save --session <run_id>`
(the finishing gate first re-checks the saved-mode session contract, then lints/promotes **only the pages
listed in that session's `candidate_write_set.json`**); do not bypass two-phase publish.

## 7. Workflow

| Sub-unit | Input | Output | Acceptance | Persisted | Failure stop |
|---|---|---|---|---|---|
| S1 read session | run_id | session content + related pages | required files present, JSON parses | — | session missing |
| S2 admission | session + save-back-policy | save/refuse decision | at least one gate condition holds and evidence_refs non-empty | `decision.md` draft | below the gate |
| S3 resolve concepts | candidate concepts | Review-Queue proposal | do not hand-create/merge concepts in new-only mode | proposal | concept write requested |
| S4 write proposed | candidate pages | new proposed pages or a proposal | `check-write --source kb-save --session` ALLOW before create; existing target always proposal | vault / Review-Queue + authorization ledger | check-write DENY |
| S5 session self-check | write result | check-session --saved result | passes the saved-mode contract | full session dir | self-check fails |
| S6 publish prompt | proposed pages | lint handoff note | user knows lint decides promotion | chat summary | on lint failure hand to kb-review |

## 8. Failure stops / recovery

query-session missing or incomplete; `evidence_refs.json` empty; below `save-back-policy`; `check-write`
DENY; target already exists; concept write requested; `check-session --saved` fails. **Recovery:** keep `decision.md` + the session as the durable record; a DENY becomes
a `Review-Queue` proposal handed to `kb-review`. A legacy saved session with no
`write_authorizations.json` fails closed: if every candidate target is still absent, rerun `check-write`
once per candidate before creating pages; if any target already exists, do not retro-authorize it—route
the intended change to Review-Queue/`kb-review`, or start a fresh session with an unused new path. Never
hand-fill the authorization ledger.

## 9. Acceptance criteria

- When not saving, no change under `wiki/`, with a stated reason.
- When saving, every written page is `status: proposed` + `managed_by: pipeline`.
- Direct concept create/merge is unsupported in kb-save new-only mode; route it to Review-Queue.
  `resolve-concept` remains the ingest-only write path, and no duplicate canonical_id may be created.
- `decision.md` written; `candidate_write_set.json` / `evidence_refs.json` updated.
- Every candidate has a matching new-page entry in `write_authorizations.json`.
- `python scripts/pipeline.py check-session --id <run_id> --saved` passes.
- Prompted the finishing `lint` to decide promotion; a lint failure goes to `kb-review`.

