[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CVK6QMR16MSMS2MRG097GV":3,"skill-same:01M6CVK6QMR16MSMS2MRG097GV":75},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":46,"repositoryHtmlUrl":47,"repositoryHomepageUrl":6,"ownerHtmlUrl":48,"ownerBlogUrl":49,"ownerDescription":6,"updatedAt":50,"install":51,"resources":64},"01M6CVK6QMR16MSMS2MRG097GV","knowledge-persistence",null,"Persist session context into the structured docs\u002Fai knowledge files (OKF bundle; committed and pushed at the end). Use when the user says \"remember\", \"merk dir das\", \"save context\", \"persist knowledge\" or \"update knowledge file\", at a session checkpoint, or when an observation in this session contradicts docs\u002Fai\u002F or AGENTS.md. Do not use for reading the knowledge files at session start — that is plain bootstrapping.","georgernstgraf\u002Fopencode-helpers","georgernstgraf","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F115418377?v=4","01M6CVHJ34JS0CF98EFFN0FZ76","Georg Graf SPG","01M6CVHJ7VV5VK6RXY62SR0NE2",1,"MIT","https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf\u002Fopencode-helpers\u002Fblob\u002Fmain\u002Fskills\u002Fknowledge-persistence\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000021","资料检索与研究","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36],"knowledge","knowledge persistence","persistence","session","session context","files","workflow","documentation","opencode","docs","context","persist","structured","2026-11-10 10:12:30",false,"---\nname: knowledge-persistence\ndescription: Persist session context into the structured docs\u002Fai knowledge files\n  (OKF bundle; committed and pushed at the end). Use when the user says\n  \"remember\", \"merk dir das\", \"save context\", \"persist knowledge\" or \"update\n  knowledge file\", at a session checkpoint, or when an observation in this\n  session contradicts docs\u002Fai\u002F or AGENTS.md. Do not use for reading the\n  knowledge files at session start — that is plain bootstrapping.\nlicense: MIT\ncompatibility: opencode\nmetadata:\n  category: workflow\n  scope: documentation\n---\n\n# Knowledge Persistence Skill\n\n## Purpose\n\nThis skill extracts the agent's accumulated understanding from the current\nsession and persists it into a structured set of knowledge files on disk.\nThe files follow the **Open Knowledge Format (OKF) v0.2** — the full\nspecification is vendored alongside this skill in\n[OKF-SPEC.md](.\u002FOKF-SPEC.md).\nUse this skill at any checkpoint during or at the end of a productive\nsession, or when explicitly asked to \"save context\", \"persist knowledge\",\nor \"update knowledge file\".\n\nPersisting to disk is **not** the end of the skill: **every persistence run\nfinishes with its own commit and push** (SVN: `svn ci`) of the updated\nknowledge files, referencing the active issue. Knowledge that is written but\nnot committed does not exist for the next agent — the run is only complete\nonce the changes are on the trunk.\n\n## Target Structure\n\nEnsure the following directory and files exist relative to the project root.\nCreate any missing files. Never delete entries from HISTORY.md (it is\nan append-only archive). Do delete superseded entries from active files\nby relocating them to HISTORY.md. `hosts\u002F\u003Chost>\u002F` and `topics\u002F` are\ncreated lazily — only together with their first real content, never as\nempty scaffolding.\n\n`docs\u002Fai\u002F` is treated as an OKF **bundle**: every non-reserved `.md` file\nis a concept document carrying a YAML frontmatter envelope with the\nrequired `type` field plus the trust and lifecycle fields (see\n[FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md)). The reserved filenames\n`index.md` and `log.md` carry no (or only `okf_version`) frontmatter.\n\n```text\ndocs\u002Fai\u002F\n├── index.md        (OKF §8: progressive-disclosure index, okf_version)\n├── log.md          (OKF §9: per-run persistence log, date-grouped)\n├── HANDOFF.md      type: Handoff        — ONLY open tasks\n├── DECISIONS.md    type: Decisions      — fleet-wide decisions only\n├── ARCHITECTURE.md type: Architecture   — fleet map + host table\n├── CONVENTIONS.md  type: Conventions    — fleet-wide rules only\n├── PITFALLS.md     type: Pitfalls       — fleet-wide pitfalls only\n├── DOMAIN.md       type: Domain Notes\n├── STATE.md        type: State          — short fleet status + links\n├── HISTORY.md      type: History Archive — ONE file, append-only\n├── hosts\u002F\n│   ├── index.md                      (reserved index, no frontmatter)\n│   └── \u003Chost>\u002F\n│       ├── index.md                  (reserved index: role, OS, IPs, links)\n│       ├── chronik.md                type: Host Chronik (append-only)\n│       └── \u003Cthema>.md                type: Host Topic\n└── topics\u002F\n    ├── index.md                      (reserved index, no frontmatter)\n    └── \u003Cthema>.md                    type: Topic\n```\n\n**Scope split** (global vs. host vs. topic):\n\n- **Global category files** (`HANDOFF`, `DECISIONS`, `ARCHITECTURE`,\n  `CONVENTIONS`, `PITFALLS`, `DOMAIN`, `STATE`) hold what applies\n  **across hosts**: a rule every host follows, a decision that changes\n  the fleet, a structural map, a pitfall no single host owns.\n- **`hosts\u002F\u003Chost>\u002F`** holds what names **exactly one host** — its mail\n  chain, its ZFS pool, its boot quirks, its service layout.\n- **`topics\u002F\u003Cthema>.md`** holds what describes **several hosts as one\n  subsystem** — Telegram bots across the fleet, the VPN mesh, a search\n  stack with two instances, config tracking per host tree.\n- **`hosts\u002F\u003Chost>\u002Fchronik.md`** holds **dated session narratives** for\n  that host, append-only, newest first. It is not a category file: no\n  pruning, no reordering, no rewriting of past entries.\n\n`index.md` and `log.md` stay reserved at **every** level: the bundle\nroot, `hosts\u002F`, `topics\u002F` and each `hosts\u002F\u003Chost>\u002F` carry an `index.md`\nthat is a pure link list without frontmatter (`okf_version` only in the\nbundle root). `log.md` remains a single bundle-root file.\n\nLegacy files without frontmatter are tolerated (OKF conformance is\npermissive, OKF-SPEC.md §11) but MUST receive the envelope the next time\nthe skill touches them — no big-bang migration is required.\n\n**Active files** (must match current HEAD; no superseded entries):\nHANDOFF.md, DECISIONS.md, ARCHITECTURE.md, CONVENTIONS.md, PITFALLS.md,\nDOMAIN.md, STATE.md, and every non-`index.md`\u002Fnon-`log.md` concept file\nunder `hosts\u002F` and `topics\u002F`.\n\n**Historical files** (chronological sinks; superseded entries EXPECTED\nhere): HISTORY.md (one file, never split, never pruned) and the\n`hosts\u002F\u003Chost>\u002Fchronik.md` narratives (append-only).\n\n## Protocol\n\n### 1. Discovery\n\n- Start at `docs\u002Fai\u002Findex.md` (OKF §8 progressive disclosure) if it\n  exists; it lists what is present, including legacy files, and points\n  at `hosts\u002Findex.md` and `topics\u002Findex.md`.\n- If the session has a **host context** (an SSH target, a host-named\n  directory, `EDV\u002FDeployed\u002F\u003Chost>\u002F`, a hostname in the task), read\n  `hosts\u002F\u003Chost>\u002Findex.md` and the topic files it links before writing\n  anything. Read the neighbouring host bundles only when the session\n  compares hosts or the placement is unclear.\n- For a **multi-host subsystem**, read `topics\u002Findex.md` and the\n  matching `topics\u002F\u003Cthema>.md`, plus the host bundles it names.\n- Read all existing files in `docs\u002Fai\u002F` (including `hosts\u002F` and\n  `topics\u002F` subtrees) to understand what is already persisted. Files\n  WITHOUT frontmatter are legacy-but-valid; any file you end up editing\n  must first receive the OKF envelope (see [FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md),\n  \"Frontmatter Envelope\").\n- If the directory does not exist, create it (with `index.md` and\n  `log.md`).\n- If a file does not exist, create it with the template in\n  [FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md). A host or topic file is\n  only created when it will hold **at least two entries** — a single\n  fact joins the closest related topic file instead.\n\n### 2. Diff Against Session\n\n- Review the full conversation history of the current session.\n- For each knowledge file, identify facts, decisions, patterns, or status\n  changes that emerged during this session and are NOT yet in the file.\n- Ignore transient chatter, failed attempts that were fully superseded,\n  and speculative discussion that did not lead to a conclusion.\n\n### 2b. Observed Drift\n\nDrift is any observation **during** the session that contradicts a\nstatement in `docs\u002Fai\u002F` or `AGENTS.md`: a command output on a host, a file\nthat is not where the docs say, a documented command that returns nothing\nor something else. Documented commands (in `AGENTS.md`, runbooks, skill\ninstructions) count as statements — if they do not do what they promise,\nthat is drift.\n\n- Drift is handled **in the same session**, never left in the chat or in\n  agent-private memory.\n- Two outcomes, and the evidence decides which:\n  - **Correct it** — the observation is conclusive, so the statement is\n    fixed under the prune protocol (3b) with a reason of the form\n    `observed YYYY-MM-DD on \u003Chost>: \u003Cevidence>`.\n  - **Open a HANDOFF task** — the observation is real but not conclusive.\n    The task names file, line and evidence. A single observation is enough\n    for a task, not always for a new statement: writing a replacement\n    guess would swap one wrong statement for another.\n- A file carrying an observed contradiction counts as \"being updated\"\n  for 3b, even when the session otherwise adds nothing new to it.\n- Section 6 extends to **stale commands**, not just the bootstrap block:\n  a documented command that fails or misreports is drift as well.\n- What is *not* drift, and not worth a task: a host that has evidently\n  moved on (different version, renamed unit) when the docs never claimed\n  that state, and transient failures (network, rate limits) that say\n  nothing about the documented behaviour.\n\n### 3. Write Updates\n\n**Placement rules (binding, decide before writing):**\n\n1. The entry names **exactly one host** → `hosts\u002F\u003Chost>\u002F\u003Cthema>.md`\n   with the sections `# Überblick`, `# Betrieb`, `# Fallstricke`,\n   `# Entscheidungen` (empty sections may be omitted).\n2. The entry describes **several hosts as one subsystem** →\n   `topics\u002F\u003Cthema>.md`.\n3. The entry is a **fleet-wide** rule, decision, pitfall or structural\n   fact → the global category file (`CONVENTIONS.md`, `DECISIONS.md`,\n   `PITFALLS.md`, `ARCHITECTURE.md`, `DOMAIN.md`).\n4. The entry is a **dated session narrative** (\"on 2026-11-09 we\n   changed X on host Y, result Z\") → `hosts\u002F\u003Chost>\u002Fchronik.md`,\n   append-only, newest entry on top.\n5. The entry cannot be pinned to one host and is not fleet-wide\n   either → keep it in the global file and tag it, `tags: [host:…]`,\n   so the next run can split it out.\n6. A host or topic file is created only when it carries **at least\n   two entries**; otherwise the entry goes into the related topic file\n   rather than spawning a one-bullet file.\n\nThen:\n\n- Append new entries to the file chosen above.\n- Before appending to a collection file, check the concept-boundary\n  rules in [FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md) (\"Concept\n  Boundaries and Splitting\") — split instead of growing a file that\n  mixes entries with independent lifespans.\n- If an existing entry is now outdated, MOVE it to HISTORY.md (do not\n  leave superseded content in active files).\n- **Chronik exception:** entries in `hosts\u002F\u003Chost>\u002Fchronik.md` are never\n  moved to HISTORY.md and never edited after the fact — a correction is\n  a new dated entry that names the corrected one.\n- Never duplicate an entry that already exists.\n- Write only facts. One item per bullet. No preamble, no commentary,\n  no summaries at the top of the file.\n\n**Frontmatter maintenance (every touched file):**\n\n- On any edit, update `generated.at` to the current run's ISO 8601\n  UTC datetime (OKF §5.2).\n- When you verified an entry against the current codebase\u002Fconfig\n  **before** writing it, set `verified: { by: opencode\u002Fknowledge-persistence, at: \u003CISO> }`\n  (machine-confirmed trust tier, OKF §5.3). Never fabricate a\n  `human:` verification — only a human may add `by: human:\u003Cid>`.\n- **Moved or migrated knowledge inherits NO `verified`.** Text that was\n  relocated from another file (legacy flat file → host bundle, host →\n  topic) was not re-checked by this run, so the new file keeps only\n  `generated`. Only facts actually re-verified in this session get the\n  machine confirmation, and only for those entries.\n- Set `sources` with the active GitHub issue when the entry\n  references one (OKF §5.1); keep existing `sources` entries that\n  remain relevant.\n- Files are `status: stable` by default; per-entry lifecycle lives in\n  the entry text (`[ACTIVE until #NNN]`, HISTORY relocation), not in\n  the file-level `status` field.\n\n### 3b. Prune Superseded Entries\n\nPruning applies to **every active concept file** being updated,\nincluding `hosts\u002F\u003Chost>\u002F\u003Cthema>.md` and `topics\u002F\u003Cthema>.md`:\n\n- **Never pruned:** `hosts\u002F\u003Chost>\u002Fchronik.md` is append-only — old\n  entries stay, even when the described state has changed; a later entry\n  supersedes them in reading order. `HISTORY.md` stays **one** file and\n  is never split or pruned either.\n- **`index.md` files are regenerated, not pruned:** a link to a removed\n  concept disappears when the index is rebuilt (step 5b).\n\nFor each active file being updated, scan for entries that no longer\nmatch current reality:\n\n- Entries contradicted by current code or configuration.\n- Entries superseded by a later decision or implementation.\n- Entries describing a reverted or removed change.\n\nFor each superseded entry found:\n\n1. **Remove** it from the active file.\n2. **Append** it to `HISTORY.md` with a header:\n   `## YYYY-MM-DD (SUPERSEDED YYYY-MM-DD, origin: \u003CFILE>, reason: \u003Cwhy or #NNN>): \u003CTitle>`\n3. Include the original entry text below the header, plus one line\n   noting the origin file and the reason it was superseded.\n4. Leave a ONE-LINE pointer in the active file ONLY if a future reader\n   would otherwise re-discover the same pitfall; otherwise delete\n   cleanly.\n5. Bump `generated.at` on the active file and on `HISTORY.md`.\n\n**PITFALLS.md special case**: Distinguish between:\n- **(a) Permanent non-obvious constraints** (e.g., \"Room validates\n  PRAGMA table_info, PK must be NOT NULL\") — these stay in active\n  PITFALLS.md.\n- **(b) Bugs that were fixed** (e.g., \"clearText+typeText race, fixed\n  in #254\") — these MOVE to HISTORY.md once the fix ships. Their value\n  is historical, not advisory.\n\nThe same (a)\u002F(b) split applies inside a host bundle's `# Fallstricke`\nsection and a topic file — a fixed bug there also goes to HISTORY.md.\n\n**Status-tag convention**: For active-file entries with a known\nlifecycle (e.g., a workaround slated for removal), append an optional\ntrailing tag `[ACTIVE until #NNN]` so a future pruner knows to\nrelocate it.\n\n### 4. Rewrite `ARCHITECTURE.md` (if structural changes occurred)\n\n- Determine whether the session introduced any structural changes:\n  new\u002Fremoved\u002Frenamed commands, skills, knowledge files, hosts or\n  host subsystems, or significant changes to data flows, dependencies,\n  or component relationships.\n- If no structural changes occurred, skip this step and leave\n  `ARCHITECTURE.md` unchanged.\n- If structural changes did occur, **overwrite** `docs\u002Fai\u002FARCHITECTURE.md`\n  with the current system snapshot using the template in\n  [FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md).\n- Like STATE.md, this file is overwritten (not appended) because it\n  represents a point-in-time structural map, not a chronological log.\n\n### 5. Write `HANDOFF.md` and `STATE.md`\n\n- Check the task list maintained during this session.\n- If any tasks are still [PENDING] or [IN PROGRESS], write them to\n  `docs\u002Fai\u002FHANDOFF.md` using the template in\n  [FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md).\n- Include: the current branch, each open task with file paths and\n  line numbers where applicable, and any context the next agent\n  needs to avoid re-discovery.\n- If all tasks are complete, clear the file body and write only:\n  `No pending tasks. Last cleared: YYYY-MM-DD.`\n\n**HANDOFF.md contains ONLY open tasks** — no session narrative, no\n\"what was done\" log, no resolved items (those live in HISTORY.md or in\nthe host chronik).\n\n- **Host tagging (mandatory):** each task is prefixed with its host and\n  links the host bundle, e.g.\n  `1. [ ] murl: Rspamd-Migration — [hosts\u002Fmurl\u002Findex.md](hosts\u002Fmurl\u002Findex.md)`.\n  Tasks that span hosts are grouped under `Flotte` and link the\n  matching `topics\u002F\u003Cthema>.md`.\n\n**`STATE.md` is a short fleet status, not a session archive:**\n\n- one short paragraph for the overall picture,\n- one bullet per host with the current state and a link to\n  `hosts\u002F\u003Chost>\u002Fchronik.md`,\n- an \"open threads\" section that points at the host bundles instead of\n  repeating their detail.\n\nDated narratives never go into STATE.md — they belong in the host\nchronik. If a STATE bullet turns into a story, move the story and leave\nthe link.\n\n#### Escalation Rule\n\n- If an open task would require more than ~30 minutes of agent work,\n  do NOT put it in HANDOFF.md alone.\n- **GitHub-Projekte:** Create a GitHub issue:\n  `gh issue create --title \"\u003Ctitle>\" --body \"\u003Cbody>\"` — but only **after**\n  the Duplicate Check from the `issue-workflow` skill reports no matching\n  open issue (reuse that issue instead, and reference its number here). In\n  HANDOFF.md, reference only the issue number:\n  `1. [ ] See #42 — Refactor enrollment module to cursor pagination`\n- **SVN-Projekte ohne Issue-System** (z. B. `~\u002Fsvn\u002Fgeorg`, Deployed-Trees auf\n  murl\u002Fclaw): es existiert KEIN Issue-Tracking — solche Aufgaben bleiben\n  vollständig in HANDOFF.md (mit Datei-\u002FPfad-Angabe); kein `gh`-Aufruf.\n- This keeps HANDOFF.md small and actionable while large work is\n  properly tracked (via issues in GitHub, via HANDOFF.md in SVN).\n\n### 5b. Update `log.md` and regenerate `index.md`\n\n- **`log.md`** (OKF §9): append one date-grouped entry at the top of\n  the log (newest first) summarizing this run: for each updated file\n  an `**Update**` \u002F `**Creation**` \u002F `**Deprecation**` line linking\n  the concept. NO frontmatter in `log.md`.\n- **`index.md`** (OKF §8): regenerate from the current directory\n  state. Keep `okf_version: \"0.2\"` in the bundle-root frontmatter\n  (the only frontmatter an `index.md` may carry). Entries include the\n  concept's `description`. Skip files the run did not touch only to\n  note them as unchanged — the index always lists ALL files.\n- **Nested indexes:** `hosts\u002Findex.md`, `topics\u002Findex.md` and every\n  `hosts\u002F\u003Chost>\u002Findex.md` are reserved indexes too (no frontmatter).\n  They are regenerated whenever a concept below them is added, renamed\n  or removed: `hosts\u002Findex.md` lists the host bundles plus their\n  `chronik.md`, `topics\u002Findex.md` lists the topic files, and\n  `hosts\u002F\u003Chost>\u002Findex.md` carries role\u002FOS\u002FIPs on top and a link list of\n  the host's concept files below.\n\n### 6. Update `AGENTS.md`\n\n- Ensure the project-level `AGENTS.md` (in project root or `.opencode\u002F`)\n  contains the bootstrap instruction block. If it does not, append it.\n\n### 7. Comment on Active Issue (nur GitHub-Projekte; SVN: skip)\n\n- **Anwendbarkeit:** nur für GitHub- (bzw. Git-)Projekte. In SVN-Projekten\n  ohne Issue-System (`~\u002Fsvn\u002Fgeorg` etc.) diesen Schritt still überspringen.\n- If there is a known active GitHub issue for the current session, post a\n  brief comment summarizing what knowledge was persisted (files updated,\n  key additions). Example:\n  `gh issue comment 42 --body \"Knowledge persisted: added 3 entries to CONVENTIONS.md, updated STATE.md.\"`\n- **NEVER close, reopen, or change the state of any issue.** This skill\n  only adds comments for traceability.\n- If no active issue is known, skip this step silently.\n\n### 8. Commit and Push (mandatory)\n\n- **Git-Projekte:** Stage the knowledge files and create a commit that\n  references the active issue, e.g. `docs: persist knowledge (#42)`. Preserve\n  the repository's commit-message style, keep the issue reference, then push to\n  the trunk line. Never write an empty commit — if nothing changed, report\n  \"nothing to persist\" and stop.\n- If several commits are needed, that is fine; what is forbidden is leaving\n  knowledge changes uncommitted or unpushed.\n- **SVN-Projekte** (z. B. `~\u002Fsvn\u002Fgeorg`, Deployed-Trees): Analogon ist ein\n  `svn ci` mit klarer deutscher Commit-Message.\n- The commit may land **after** an issue is closed (e.g. STATE.md\u002FHANDOFF.md\n  record the closed state) — the knowledge commit is the follow-up that carries\n  those files to the trunk.\n- This skill still NEVER closes, reopens, or changes the state of an issue\n  (see step 7 and Constraints).\n\n### 9. Confirmation\n\n- After committing and pushing, list every file that was created or modified,\n  and for each show the number of entries added, updated, or removed.\n- Confirm the OKF state of every file **this run created or modified**\n  (parseable frontmatter, non-empty `type`; `index.md` regenerated;\n  `log.md` records this run — OKF-SPEC.md §11). List any remaining\n  legacy files (no frontmatter) with a one-line note that they are\n  tolerated and migrate on their next touch. Never migrate untouched\n  files just to make the confirmation pass — that would be the\n  big-bang migration this skill forbids.\n- **Run the bundle checker** where it is available:\n  `EDV\u002FToolset\u002Fokf-check --root docs\u002Fai`. It verifies conformance\n  (frontmatter, reserved filenames), that every `index.md` links all\n  concepts of its directory, and that links resolve. After a move or a\n  split, prove losslessness against the previous state:\n  `EDV\u002FToolset\u002Fokf-check --root docs\u002Fai --preserve-from \u003Cexported-old-tree>`.\n  The tool lives in the `~\u002Fsvn\u002Fgeorg` working copy; in other projects\n  skip it and state that it was not available, instead of hand-waving\n  conformance.\n- State the commit hash and that it was pushed.\n\n## Done when\n\n- [ ] `docs\u002Fai\u002Findex.md` and every file the run touches were read; on a host\n      context, the host bundle and its topic files as well.\n- [ ] Every fact, decision and status change of the session was diffed against\n      the files; observed drift is either corrected or filed as a HANDOFF task.\n- [ ] Every touched file carries the OKF envelope with a bumped `generated.at`;\n      superseded entries were moved to HISTORY.md, not deleted.\n- [ ] HANDOFF.md holds only open tasks (or `No pending tasks. Last cleared:\n      …`), and STATE.md was overwritten, not appended.\n- [ ] One `log.md` entry was appended and every affected `index.md` (root,\n      `hosts\u002F`, `topics\u002F`, each host) was regenerated.\n- [ ] OKF conformance is confirmed — `okf-check` run, or its unavailability\n      stated instead of hand-waved.\n- [ ] The changes are committed with the active issue reference and pushed\n      (SVN: `svn ci`), or \"nothing to persist\" was reported.\n\n## File Templates and Content Rules\n\nTemplates and per-file content rules for `docs\u002Fai\u002F` are in\n[FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md). Use the template for a file when\ncreating or overwriting it.\n\n## Constraints\n\n- **Commit + push is part of persistence.** Every run ends on the trunk: a\n  commit with the active issue reference, pushed (Git) or `svn ci` (SVN).\n  Uncommitted\u002Funpushed knowledge files violate this skill.\n- Write only verified facts from the session. Do not speculate.\n- Keep entries atomic: one fact, one bullet.\n- Active files: merge new entries, but DELETE superseded entries by\n  relocating them to HISTORY.md. Never leave stale content in active\n  files.\n- HISTORY.md: append-only. Never delete or modify existing entries.\n- Overwrite files: STATE.md, ARCHITECTURE.md, and HANDOFF.md are\n  overwritten on each persistence run (not appended).\n- If unsure whether something belongs in DECISIONS vs CONVENTIONS,\n  apply this test: \"Is this a one-time choice (DECISIONS) or an\n  ongoing rule to follow (CONVENTIONS)?\"\n- If unsure whether something belongs in DECISIONS vs ARCHITECTURE,\n  apply this test: \"Is this a chronological record of a choice\n  (DECISIONS) or a structural description of the current system\n  (ARCHITECTURE)?\"\n- If unsure whether an entry is still valid, apply this test:\n  \"Is this still true in the current codebase? If not, it belongs\n  in HISTORY.md, not the active file.\"\n- Active files stay lean through the prune protocol (step 3b); no\n  hard line limit is needed.\n- HISTORY.md is append-only and stays **one** file: never split it per\n  host and never relocate entries out of it. It grows over time — that\n  is accepted; keep new entries short instead of splitting the archive.\n- Placement is not a matter of taste: step 3's rules decide between\n  `hosts\u002F\u003Chost>\u002F`, `topics\u002F` and the global files. A host-named entry\n  in a global file is a defect (the `okf-check` placement lint warns on\n  it), and a fleet-wide rule buried in one host bundle is a defect too.\n- `hosts\u002F\u003Chost>\u002Fchronik.md` is append-only: never edit, reorder or\n  prune past narrative entries, and never move them to HISTORY.md.\n- **Issue Safety**: This skill is a documentation-only operation. It\n  must NEVER close, reopen, or change the state of any GitHub issue.\n  Issue lifecycle management is the exclusive responsibility of the\n  `issue-workflow` skill (continuous completion criteria or its `finish`\n  override mode). When invoked standalone, this\n  skill may only create new issues (Escalation Rule) or comment on\n  existing ones. — gilt diesbezüglich nur für GitHub-Projekte;\n  SVN-Projekte ohne Issue-System haben schlicht keine Issues (dann\n  entfällt der ganze Mechanik still).\n- **OKF Integrity**: `docs\u002Fai\u002F` is an OKF v0.2 bundle\n  ([OKF-SPEC.md](.\u002FOKF-SPEC.md)). The reserved filenames `index.md`\n  and `log.md` are never used for concept documents (`index.md` is\n  reserved at every directory level, `log.md` only at the bundle\n  root), `log.md` gets no frontmatter, and frontmatter `type` is always\n  present and non-empty. Unknown extra frontmatter keys are allowed\n  (producers may extend).\n- **No fabricated trust**: never write a `human:\u003Cid>` `verified` entry\n  on your own — machine-verified is the maximum an agent may claim.\n","# Knowledge Persistence Skill\n\n## Purpose\n\nThis skill extracts the agent's accumulated understanding from the current\nsession and persists it into a structured set of knowledge files on disk.\nThe files follow the **Open Knowledge Format (OKF) v0.2** — the full\nspecification is vendored alongside this skill in\n[OKF-SPEC.md](.\u002FOKF-SPEC.md).\nUse this skill at any checkpoint during or at the end of a productive\nsession, or when explicitly asked to \"save context\", \"persist knowledge\",\nor \"update knowledge file\".\n\nPersisting to disk is **not** the end of the skill: **every persistence run\nfinishes with its own commit and push** (SVN: `svn ci`) of the updated\nknowledge files, referencing the active issue. Knowledge that is written but\nnot committed does not exist for the next agent — the run is only complete\nonce the changes are on the trunk.\n\n## Target Structure\n\nEnsure the following directory and files exist relative to the project root.\nCreate any missing files. Never delete entries from HISTORY.md (it is\nan append-only archive). Do delete superseded entries from active files\nby relocating them to HISTORY.md. `hosts\u002F\u003Chost>\u002F` and `topics\u002F` are\ncreated lazily — only together with their first real content, never as\nempty scaffolding.\n\n`docs\u002Fai\u002F` is treated as an OKF **bundle**: every non-reserved `.md` file\nis a concept document carrying a YAML frontmatter envelope with the\nrequired `type` field plus the trust and lifecycle fields (see\n[FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md)). The reserved filenames\n`index.md` and `log.md` carry no (or only `okf_version`) frontmatter.\n\n```text\ndocs\u002Fai\u002F\n├── index.md        (OKF §8: progressive-disclosure index, okf_version)\n├── log.md          (OKF §9: per-run persistence log, date-grouped)\n├── HANDOFF.md      type: Handoff        — ONLY open tasks\n├── DECISIONS.md    type: Decisions      — fleet-wide decisions only\n├── ARCHITECTURE.md type: Architecture   — fleet map + host table\n├── CONVENTIONS.md  type: Conventions    — fleet-wide rules only\n├── PITFALLS.md     type: Pitfalls       — fleet-wide pitfalls only\n├── DOMAIN.md       type: Domain Notes\n├── STATE.md        type: State          — short fleet status + links\n├── HISTORY.md      type: History Archive — ONE file, append-only\n├── hosts\u002F\n│   ├── index.md                      (reserved index, no frontmatter)\n│   └── \u003Chost>\u002F\n│       ├── index.md                  (reserved index: role, OS, IPs, links)\n│       ├── chronik.md                type: Host Chronik (append-only)\n│       └── \u003Cthema>.md                type: Host Topic\n└── topics\u002F\n    ├── index.md                      (reserved index, no frontmatter)\n    └── \u003Cthema>.md                    type: Topic\n```\n\n**Scope split** (global vs. host vs. topic):\n\n- **Global category files** (`HANDOFF`, `DECISIONS`, `ARCHITECTURE`,\n  `CONVENTIONS`, `PITFALLS`, `DOMAIN`, `STATE`) hold what applies\n  **across hosts**: a rule every host follows, a decision that changes\n  the fleet, a structural map, a pitfall no single host owns.\n- **`hosts\u002F\u003Chost>\u002F`** holds what names **exactly one host** — its mail\n  chain, its ZFS pool, its boot quirks, its service layout.\n- **`topics\u002F\u003Cthema>.md`** holds what describes **several hosts as one\n  subsystem** — Telegram bots across the fleet, the VPN mesh, a search\n  stack with two instances, config tracking per host tree.\n- **`hosts\u002F\u003Chost>\u002Fchronik.md`** holds **dated session narratives** for\n  that host, append-only, newest first. It is not a category file: no\n  pruning, no reordering, no rewriting of past entries.\n\n`index.md` and `log.md` stay reserved at **every** level: the bundle\nroot, `hosts\u002F`, `topics\u002F` and each `hosts\u002F\u003Chost>\u002F` carry an `index.md`\nthat is a pure link list without frontmatter (`okf_version` only in the\nbundle root). `log.md` remains a single bundle-root file.\n\nLegacy files without frontmatter are tolerated (OKF conformance is\npermissive, OKF-SPEC.md §11) but MUST receive the envelope the next time\nthe skill touches them — no big-bang migration is required.\n\n**Active files** (must match current HEAD; no superseded entries):\nHANDOFF.md, DECISIONS.md, ARCHITECTURE.md, CONVENTIONS.md, PITFALLS.md,\nDOMAIN.md, STATE.md, and every non-`index.md`\u002Fnon-`log.md` concept file\nunder `hosts\u002F` and `topics\u002F`.\n\n**Historical files** (chronological sinks; superseded entries EXPECTED\nhere): HISTORY.md (one file, never split, never pruned) and the\n`hosts\u002F\u003Chost>\u002Fchronik.md` narratives (append-only).\n\n## Protocol\n\n### 1. Discovery\n\n- Start at `docs\u002Fai\u002Findex.md` (OKF §8 progressive disclosure) if it\n  exists; it lists what is present, including legacy files, and points\n  at `hosts\u002Findex.md` and `topics\u002Findex.md`.\n- If the session has a **host context** (an SSH target, a host-named\n  directory, `EDV\u002FDeployed\u002F\u003Chost>\u002F`, a hostname in the task), read\n  `hosts\u002F\u003Chost>\u002Findex.md` and the topic files it links before writing\n  anything. Read the neighbouring host bundles only when the session\n  compares hosts or the placement is unclear.\n- For a **multi-host subsystem**, read `topics\u002Findex.md` and the\n  matching `topics\u002F\u003Cthema>.md`, plus the host bundles it names.\n- Read all existing files in `docs\u002Fai\u002F` (including `hosts\u002F` and\n  `topics\u002F` subtrees) to understand what is already persisted. Files\n  WITHOUT frontmatter are legacy-but-valid; any file you end up editing\n  must first receive the OKF envelope (see [FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md),\n  \"Frontmatter Envelope\").\n- If the directory does not exist, create it (with `index.md` and\n  `log.md`).\n- If a file does not exist, create it with the template in\n  [FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md). A host or topic file is\n  only created when it will hold **at least two entries** — a single\n  fact joins the closest related topic file instead.\n\n### 2. Diff Against Session\n\n- Review the full conversation history of the current session.\n- For each knowledge file, identify facts, decisions, patterns, or status\n  changes that emerged during this session and are NOT yet in the file.\n- Ignore transient chatter, failed attempts that were fully superseded,\n  and speculative discussion that did not lead to a conclusion.\n\n### 2b. Observed Drift\n\nDrift is any observation **during** the session that contradicts a\nstatement in `docs\u002Fai\u002F` or `AGENTS.md`: a command output on a host, a file\nthat is not where the docs say, a documented command that returns nothing\nor something else. Documented commands (in `AGENTS.md`, runbooks, skill\ninstructions) count as statements — if they do not do what they promise,\nthat is drift.\n\n- Drift is handled **in the same session**, never left in the chat or in\n  agent-private memory.\n- Two outcomes, and the evidence decides which:\n  - **Correct it** — the observation is conclusive, so the statement is\n    fixed under the prune protocol (3b) with a reason of the form\n    `observed YYYY-MM-DD on \u003Chost>: \u003Cevidence>`.\n  - **Open a HANDOFF task** — the observation is real but not conclusive.\n    The task names file, line and evidence. A single observation is enough\n    for a task, not always for a new statement: writing a replacement\n    guess would swap one wrong statement for another.\n- A file carrying an observed contradiction counts as \"being updated\"\n  for 3b, even when the session otherwise adds nothing new to it.\n- Section 6 extends to **stale commands**, not just the bootstrap block:\n  a documented command that fails or misreports is drift as well.\n- What is *not* drift, and not worth a task: a host that has evidently\n  moved on (different version, renamed unit) when the docs never claimed\n  that state, and transient failures (network, rate limits) that say\n  nothing about the documented behaviour.\n\n### 3. Write Updates\n\n**Placement rules (binding, decide before writing):**\n\n1. The entry names **exactly one host** → `hosts\u002F\u003Chost>\u002F\u003Cthema>.md`\n   with the sections `# Überblick`, `# Betrieb`, `# Fallstricke`,\n   `# Entscheidungen` (empty sections may be omitted).\n2. The entry describes **several hosts as one subsystem** →\n   `topics\u002F\u003Cthema>.md`.\n3. The entry is a **fleet-wide** rule, decision, pitfall or structural\n   fact → the global category file (`CONVENTIONS.md`, `DECISIONS.md`,\n   `PITFALLS.md`, `ARCHITECTURE.md`, `DOMAIN.md`).\n4. The entry is a **dated session narrative** (\"on 2026-11-09 we\n   changed X on host Y, result Z\") → `hosts\u002F\u003Chost>\u002Fchronik.md`,\n   append-only, newest entry on top.\n5. The entry cannot be pinned to one host and is not fleet-wide\n   either → keep it in the global file and tag it, `tags: [host:…]`,\n   so the next run can split it out.\n6. A host or topic file is created only when it carries **at least\n   two entries**; otherwise the entry goes into the related topic file\n   rather than spawning a one-bullet file.\n\nThen:\n\n- Append new entries to the file chosen above.\n- Before appending to a collection file, check the concept-boundary\n  rules in [FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md) (\"Concept\n  Boundaries and Splitting\") — split instead of growing a file that\n  mixes entries with independent lifespans.\n- If an existing entry is now outdated, MOVE it to HISTORY.md (do not\n  leave superseded content in active files).\n- **Chronik exception:** entries in `hosts\u002F\u003Chost>\u002Fchronik.md` are never\n  moved to HISTORY.md and never edited after the fact — a correction is\n  a new dated entry that names the corrected one.\n- Never duplicate an entry that already exists.\n- Write only facts. One item per bullet. No preamble, no commentary,\n  no summaries at the top of the file.\n\n**Frontmatter maintenance (every touched file):**\n\n- On any edit, update `generated.at` to the current run's ISO 8601\n  UTC datetime (OKF §5.2).\n- When you verified an entry against the current codebase\u002Fconfig\n  **before** writing it, set `verified: { by: opencode\u002Fknowledge-persistence, at: \u003CISO> }`\n  (machine-confirmed trust tier, OKF §5.3). Never fabricate a\n  `human:` verification — only a human may add `by: human:\u003Cid>`.\n- **Moved or migrated knowledge inherits NO `verified`.** Text that was\n  relocated from another file (legacy flat file → host bundle, host →\n  topic) was not re-checked by this run, so the new file keeps only\n  `generated`. Only facts actually re-verified in this session get the\n  machine confirmation, and only for those entries.\n- Set `sources` with the active GitHub issue when the entry\n  references one (OKF §5.1); keep existing `sources` entries that\n  remain relevant.\n- Files are `status: stable` by default; per-entry lifecycle lives in\n  the entry text (`[ACTIVE until #NNN]`, HISTORY relocation), not in\n  the file-level `status` field.\n\n### 3b. Prune Superseded Entries\n\nPruning applies to **every active concept file** being updated,\nincluding `hosts\u002F\u003Chost>\u002F\u003Cthema>.md` and `topics\u002F\u003Cthema>.md`:\n\n- **Never pruned:** `hosts\u002F\u003Chost>\u002Fchronik.md` is append-only — old\n  entries stay, even when the described state has changed; a later entry\n  supersedes them in reading order. `HISTORY.md` stays **one** file and\n  is never split or pruned either.\n- **`index.md` files are regenerated, not pruned:** a link to a removed\n  concept disappears when the index is rebuilt (step 5b).\n\nFor each active file being updated, scan for entries that no longer\nmatch current reality:\n\n- Entries contradicted by current code or configuration.\n- Entries superseded by a later decision or implementation.\n- Entries describing a reverted or removed change.\n\nFor each superseded entry found:\n\n1. **Remove** it from the active file.\n2. **Append** it to `HISTORY.md` with a header:\n   `## YYYY-MM-DD (SUPERSEDED YYYY-MM-DD, origin: \u003CFILE>, reason: \u003Cwhy or #NNN>): \u003CTitle>`\n3. Include the original entry text below the header, plus one line\n   noting the origin file and the reason it was superseded.\n4. Leave a ONE-LINE pointer in the active file ONLY if a future reader\n   would otherwise re-discover the same pitfall; otherwise delete\n   cleanly.\n5. Bump `generated.at` on the active file and on `HISTORY.md`.\n\n**PITFALLS.md special case**: Distinguish between:\n- **(a) Permanent non-obvious constraints** (e.g., \"Room validates\n  PRAGMA table_info, PK must be NOT NULL\") — these stay in active\n  PITFALLS.md.\n- **(b) Bugs that were fixed** (e.g., \"clearText+typeText race, fixed\n  in #254\") — these MOVE to HISTORY.md once the fix ships. Their value\n  is historical, not advisory.\n\nThe same (a)\u002F(b) split applies inside a host bundle's `# Fallstricke`\nsection and a topic file — a fixed bug there also goes to HISTORY.md.\n\n**Status-tag convention**: For active-file entries with a known\nlifecycle (e.g., a workaround slated for removal), append an optional\ntrailing tag `[ACTIVE until #NNN]` so a future pruner knows to\nrelocate it.\n\n### 4. Rewrite `ARCHITECTURE.md` (if structural changes occurred)\n\n- Determine whether the session introduced any structural changes:\n  new\u002Fremoved\u002Frenamed commands, skills, knowledge files, hosts or\n  host subsystems, or significant changes to data flows, dependencies,\n  or component relationships.\n- If no structural changes occurred, skip this step and leave\n  `ARCHITECTURE.md` unchanged.\n- If structural changes did occur, **overwrite** `docs\u002Fai\u002FARCHITECTURE.md`\n  with the current system snapshot using the template in\n  [FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md).\n- Like STATE.md, this file is overwritten (not appended) because it\n  represents a point-in-time structural map, not a chronological log.\n\n### 5. Write `HANDOFF.md` and `STATE.md`\n\n- Check the task list maintained during this session.\n- If any tasks are still [PENDING] or [IN PROGRESS], write them to\n  `docs\u002Fai\u002FHANDOFF.md` using the template in\n  [FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md).\n- Include: the current branch, each open task with file paths and\n  line numbers where applicable, and any context the next agent\n  needs to avoid re-discovery.\n- If all tasks are complete, clear the file body and write only:\n  `No pending tasks. Last cleared: YYYY-MM-DD.`\n\n**HANDOFF.md contains ONLY open tasks** — no session narrative, no\n\"what was done\" log, no resolved items (those live in HISTORY.md or in\nthe host chronik).\n\n- **Host tagging (mandatory):** each task is prefixed with its host and\n  links the host bundle, e.g.\n  `1. [ ] murl: Rspamd-Migration — [hosts\u002Fmurl\u002Findex.md](hosts\u002Fmurl\u002Findex.md)`.\n  Tasks that span hosts are grouped under `Flotte` and link the\n  matching `topics\u002F\u003Cthema>.md`.\n\n**`STATE.md` is a short fleet status, not a session archive:**\n\n- one short paragraph for the overall picture,\n- one bullet per host with the current state and a link to\n  `hosts\u002F\u003Chost>\u002Fchronik.md`,\n- an \"open threads\" section that points at the host bundles instead of\n  repeating their detail.\n\nDated narratives never go into STATE.md — they belong in the host\nchronik. If a STATE bullet turns into a story, move the story and leave\nthe link.\n\n#### Escalation Rule\n\n- If an open task would require more than ~30 minutes of agent work,\n  do NOT put it in HANDOFF.md alone.\n- **GitHub-Projekte:** Create a GitHub issue:\n  `gh issue create --title \"\u003Ctitle>\" --body \"\u003Cbody>\"` — but only **after**\n  the Duplicate Check from the `issue-workflow` skill reports no matching\n  open issue (reuse that issue instead, and reference its number here). In\n  HANDOFF.md, reference only the issue number:\n  `1. [ ] See #42 — Refactor enrollment module to cursor pagination`\n- **SVN-Projekte ohne Issue-System** (z. B. `~\u002Fsvn\u002Fgeorg`, Deployed-Trees auf\n  murl\u002Fclaw): es existiert KEIN Issue-Tracking — solche Aufgaben bleiben\n  vollständig in HANDOFF.md (mit Datei-\u002FPfad-Angabe); kein `gh`-Aufruf.\n- This keeps HANDOFF.md small and actionable while large work is\n  properly tracked (via issues in GitHub, via HANDOFF.md in SVN).\n\n### 5b. Update `log.md` and regenerate `index.md`\n\n- **`log.md`** (OKF §9): append one date-grouped entry at the top of\n  the log (newest first) summarizing this run: for each updated file\n  an `**Update**` \u002F `**Creation**` \u002F `**Deprecation**` line linking\n  the concept. NO frontmatter in `log.md`.\n- **`index.md`** (OKF §8): regenerate from the current directory\n  state. Keep `okf_version: \"0.2\"` in the bundle-root frontmatter\n  (the only frontmatter an `index.md` may carry). Entries include the\n  concept's `description`. Skip files the run did not touch only to\n  note them as unchanged — the index always lists ALL files.\n- **Nested indexes:** `hosts\u002Findex.md`, `topics\u002Findex.md` and every\n  `hosts\u002F\u003Chost>\u002Findex.md` are reserved indexes too (no frontmatter).\n  They are regenerated whenever a concept below them is added, renamed\n  or removed: `hosts\u002Findex.md` lists the host bundles plus their\n  `chronik.md`, `topics\u002Findex.md` lists the topic files, and\n  `hosts\u002F\u003Chost>\u002Findex.md` carries role\u002FOS\u002FIPs on top and a link list of\n  the host's concept files below.\n\n### 6. Update `AGENTS.md`\n\n- Ensure the project-level `AGENTS.md` (in project root or `.opencode\u002F`)\n  contains the bootstrap instruction block. If it does not, append it.\n\n### 7. Comment on Active Issue (nur GitHub-Projekte; SVN: skip)\n\n- **Anwendbarkeit:** nur für GitHub- (bzw. Git-)Projekte. In SVN-Projekten\n  ohne Issue-System (`~\u002Fsvn\u002Fgeorg` etc.) diesen Schritt still überspringen.\n- If there is a known active GitHub issue for the current session, post a\n  brief comment summarizing what knowledge was persisted (files updated,\n  key additions). Example:\n  `gh issue comment 42 --body \"Knowledge persisted: added 3 entries to CONVENTIONS.md, updated STATE.md.\"`\n- **NEVER close, reopen, or change the state of any issue.** This skill\n  only adds comments for traceability.\n- If no active issue is known, skip this step silently.\n\n### 8. Commit and Push (mandatory)\n\n- **Git-Projekte:** Stage the knowledge files and create a commit that\n  references the active issue, e.g. `docs: persist knowledge (#42)`. Preserve\n  the repository's commit-message style, keep the issue reference, then push to\n  the trunk line. Never write an empty commit — if nothing changed, report\n  \"nothing to persist\" and stop.\n- If several commits are needed, that is fine; what is forbidden is leaving\n  knowledge changes uncommitted or unpushed.\n- **SVN-Projekte** (z. B. `~\u002Fsvn\u002Fgeorg`, Deployed-Trees): Analogon ist ein\n  `svn ci` mit klarer deutscher Commit-Message.\n- The commit may land **after** an issue is closed (e.g. STATE.md\u002FHANDOFF.md\n  record the closed state) — the knowledge commit is the follow-up that carries\n  those files to the trunk.\n- This skill still NEVER closes, reopens, or changes the state of an issue\n  (see step 7 and Constraints).\n\n### 9. Confirmation\n\n- After committing and pushing, list every file that was created or modified,\n  and for each show the number of entries added, updated, or removed.\n- Confirm the OKF state of every file **this run created or modified**\n  (parseable frontmatter, non-empty `type`; `index.md` regenerated;\n  `log.md` records this run — OKF-SPEC.md §11). List any remaining\n  legacy files (no frontmatter) with a one-line note that they are\n  tolerated and migrate on their next touch. Never migrate untouched\n  files just to make the confirmation pass — that would be the\n  big-bang migration this skill forbids.\n- **Run the bundle checker** where it is available:\n  `EDV\u002FToolset\u002Fokf-check --root docs\u002Fai`. It verifies conformance\n  (frontmatter, reserved filenames), that every `index.md` links all\n  concepts of its directory, and that links resolve. After a move or a\n  split, prove losslessness against the previous state:\n  `EDV\u002FToolset\u002Fokf-check --root docs\u002Fai --preserve-from \u003Cexported-old-tree>`.\n  The tool lives in the `~\u002Fsvn\u002Fgeorg` working copy; in other projects\n  skip it and state that it was not available, instead of hand-waving\n  conformance.\n- State the commit hash and that it was pushed.\n\n## Done when\n\n- [ ] `docs\u002Fai\u002Findex.md` and every file the run touches were read; on a host\n      context, the host bundle and its topic files as well.\n- [ ] Every fact, decision and status change of the session was diffed against\n      the files; observed drift is either corrected or filed as a HANDOFF task.\n- [ ] Every touched file carries the OKF envelope with a bumped `generated.at`;\n      superseded entries were moved to HISTORY.md, not deleted.\n- [ ] HANDOFF.md holds only open tasks (or `No pending tasks. Last cleared:\n      …`), and STATE.md was overwritten, not appended.\n- [ ] One `log.md` entry was appended and every affected `index.md` (root,\n      `hosts\u002F`, `topics\u002F`, each host) was regenerated.\n- [ ] OKF conformance is confirmed — `okf-check` run, or its unavailability\n      stated instead of hand-waved.\n- [ ] The changes are committed with the active issue reference and pushed\n      (SVN: `svn ci`), or \"nothing to persist\" was reported.\n\n## File Templates and Content Rules\n\nTemplates and per-file content rules for `docs\u002Fai\u002F` are in\n[FILE-TEMPLATES.md](.\u002FFILE-TEMPLATES.md). Use the template for a file when\ncreating or overwriting it.\n\n## Constraints\n\n- **Commit + push is part of persistence.** Every run ends on the trunk: a\n  commit with the active issue reference, pushed (Git) or `svn ci` (SVN).\n  Uncommitted\u002Funpushed knowledge files violate this skill.\n- Write only verified facts from the session. Do not speculate.\n- Keep entries atomic: one fact, one bullet.\n- Active files: merge new entries, but DELETE superseded entries by\n  relocating them to HISTORY.md. Never leave stale content in active\n  files.\n- HISTORY.md: append-only. Never delete or modify existing entries.\n- Overwrite files: STATE.md, ARCHITECTURE.md, and HANDOFF.md are\n  overwritten on each persistence run (not appended).\n- If unsure whether something belongs in DECISIONS vs CONVENTIONS,\n  apply this test: \"Is this a one-time choice (DECISIONS) or an\n  ongoing rule to follow (CONVENTIONS)?\"\n- If unsure whether something belongs in DECISIONS vs ARCHITECTURE,\n  apply this test: \"Is this a chronological record of a choice\n  (DECISIONS) or a structural description of the current system\n  (ARCHITECTURE)?\"\n- If unsure whether an entry is still valid, apply this test:\n  \"Is this still true in the current codebase? If not, it belongs\n  in HISTORY.md, not the active file.\"\n- Active files stay lean through the prune protocol (step 3b); no\n  hard line limit is needed.\n- HISTORY.md is append-only and stays **one** file: never split it per\n  host and never relocate entries out of it. It grows over time — that\n  is accepted; keep new entries short instead of splitting the archive.\n- Placement is not a matter of taste: step 3's rules decide between\n  `hosts\u002F\u003Chost>\u002F`, `topics\u002F` and the global files. A host-named entry\n  in a global file is a defect (the `okf-check` placement lint warns on\n  it), and a fleet-wide rule buried in one host bundle is a defect too.\n- `hosts\u002F\u003Chost>\u002Fchronik.md` is append-only: never edit, reorder or\n  prune past narrative entries, and never move them to HISTORY.md.\n- **Issue Safety**: This skill is a documentation-only operation. It\n  must NEVER close, reopen, or change the state of any GitHub issue.\n  Issue lifecycle management is the exclusive responsibility of the\n  `issue-workflow` skill (continuous completion criteria or its `finish`\n  override mode). When invoked standalone, this\n  skill may only create new issues (Escalation Rule) or comment on\n  existing ones. — gilt diesbezüglich nur für GitHub-Projekte;\n  SVN-Projekte ohne Issue-System haben schlicht keine Issues (dann\n  entfällt der ganze Mechanik still).\n- **OKF Integrity**: `docs\u002Fai\u002F` is an OKF v0.2 bundle\n  ([OKF-SPEC.md](.\u002FOKF-SPEC.md)). The reserved filenames `index.md`\n  and `log.md` are never used for concept documents (`index.md` is\n  reserved at every directory level, `log.md` only at the bundle\n  root), `log.md` gets no frontmatter, and frontmatter `type` is always\n  present and non-empty. Unknown extra frontmatter keys are allowed\n  (producers may extend).\n- **No fabricated trust**: never write a `human:\u003Cid>` `verified` entry\n  on your own — machine-verified is the maximum an agent may claim.\n",{"name":5,"license":15,"metadata":42,"description":7,"compatibility":32},{"scope":31,"category":30},"main","adef05bd2193559aced970b8591fc8182a916301","skills\u002Fknowledge-persistence",0,"https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf\u002Fopencode-helpers","https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf","https:\u002F\u002Fwww.spengergasse.at\u002F","2026-11-11 16:51:38",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add georgernstgraf\u002Fopencode-helpers --skill knowledge-persistence",{"tool":57,"command":58},"bunx","bunx skills add georgernstgraf\u002Fopencode-helpers --skill knowledge-persistence",{"tool":60,"command":61},"pnpm","pnpm dlx skills add georgernstgraf\u002Fopencode-helpers --skill knowledge-persistence","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf\u002Fopencode-helpers\u002Fblob\u002Fmain\u002Fskills\u002Fknowledge-persistence\u002FSKILL.md",true,[65,71],{"path":66,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":69,"sourceHtmlUrl":70},"FILE-TEMPLATES.md","REFERENCE","参考文档",21526,"https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf\u002Fopencode-helpers\u002Fblob\u002Fmain\u002Fskills\u002Fknowledge-persistence\u002FFILE-TEMPLATES.md",{"path":72,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":73,"sourceHtmlUrl":74},"OKF-SPEC.md",38202,"https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf\u002Fopencode-helpers\u002Fblob\u002Fmain\u002Fskills\u002Fknowledge-persistence\u002FOKF-SPEC.md",[76,94,121,138,153,165],{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":80,"categories":81,"keywords":87,"publishedAt":37},"01M6CVKZ762FN4SW18V26P65TD","teach","Teach the user a new skill or concept, within this workspace.","https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf\u002Fopencode-helpers\u002Fblob\u002Fmain\u002Fskills\u002Fteach\u002FSKILL.md",[82],{"categoryNo":83,"categoryName":84,"taxonomyType":85,"taxonomyTypeDesc":86},"01JBSEEDCAT000000000000039","教师与教育","PROFESSION","适用职业",[78,88,89,90,91,92,93],"false","new","concept","user","new skill","workspace",{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":37},"01M6CVKVT6ZVYN2XPESS5EGDKE","sync-upstream-skills","Re-transplant owned skills from their mattpocock upstream after a git pull, applying upstream content changes while preserving opencode-native frontmatter. Also checks for duplicate skill names and dangling cross-skill references. Use when the user says \"sync skills\", \"refresh from upstream\", \"pull matt's skills\", \"sync upstream\", \"update the transplanted skills\", or wants to bring the owned transplanted skills up to date. Do not use to add or rename a transplanted skill — that stays manual.","https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf\u002Fopencode-helpers\u002Fblob\u002Fmain\u002Fskills\u002Fsync-upstream-skills\u002FSKILL.md",[],[101,102,103,104,105,106,107,32,108,109,110,111,112,113,114,115,116,117,91,118,119,120],"sync","upstream","sync upstream","sync upstream skills","pull","references","refresh","duplicate skill","duplicate","frontmatter","native","changes","up","when","re","for","bring","content","use","git",{"skillNo":122,"name":123,"nameZh":6,"description":124,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":127,"publishedAt":37},"01M6CVKNEPEY1WA7E5FWQ85NJW","repograde","Grade student repositories with optional date filtering in single-repo or bulk mode. Use when the user says \"repograde\", \"grade the repos\", \"grade this repo since \u003Cdate>\", \"bewerte die Abgaben\", \"korrigiere die Repos\", or asks for a repo grading run over a class folder or a single student repository. Do not use for project grading with issues and PRs (use projectgrade) or for knowledge-check exams (use knowledge-assessment).","https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf\u002Fopencode-helpers\u002Fblob\u002Fmain\u002Fskills\u002Frepograde\u002FSKILL.md",[],[123,128,129,130,131,132,133,134,135,136,137,32],"single","student","repositories","with","mode","bulk","education","filtering","execution","repo",{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":144,"publishedAt":37},"01M6CVKF9MVFPHBH3W2D5ETEB6","projectgrade","Grade student project repositories based on Git commits, GitHub Issues, and Pull Requests. Use when the user says \"projectgrade\", \"grade the project\", \"bewerte das Projekt\", \"Projektarbeit benoten\", or asks for a holistic grading of a collaborative repository from inside it, based on commits, issues, reviews and PRs. Do not use for per-lesson assignments (use repograde) or for knowledge-check exams (use knowledge-assessment).","https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf\u002Fopencode-helpers\u002Fblob\u002Fmain\u002Fskills\u002Fprojectgrade\u002FSKILL.md",[],[140,105,134,145,130,146,129,147,148,120,149,32,150,136,151,152],"requests","git commits","project","github issues","github","pull requests","issues","commits",{"skillNo":154,"name":155,"nameZh":6,"description":156,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":157,"categories":158,"keywords":159,"publishedAt":37},"01M6CVKA8J284DZTBE7QRN45SG","lehrplan","Richtet österreichische HTL-Unterrichts-Repositorien ein und pflegt sie — drei Kernaufgaben: das gesetzliche Lehrplan-Material eines Ausbildungszweigs (z. B. WII, WIT, KIF) aus dem RIS beschaffen inklusive jährlichem Novellen-Check, den Lehrplan eines konkreten Gegenstands aus dem Gesetz extrahieren (mit Erläuterung pro Lernziel: was der Inhalt tatsächlich IST, plus praktische Anwendungen), und Semesterpläne interaktiv entwerfen. Use when der Nutzer 'Lehrplan', 'Unterrichtsvorbereitung prüfen', 'Lehrplan auf Novellen prüfen', 'RIS sync', 'Gesetzesmaterial holen', 'Lehrplan extrahieren', 'Jahrespläne neu ziehen', 'Erläuterungen ergänzen', 'Semesterplan erstellen\u002Füberarbeiten' oder 'Einheiten erstellen' sagt, oder wenn in einem Repo gearbeitet wird, das der lehrplan\u002F-Konvention folgt. Do not use for Prepared Lessons (create-lesson), Aufgaben im Kohortenordner (homework) oder Wissensüberprüfungen (knowledge-exam).","https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf\u002Fopencode-helpers\u002Fblob\u002Fmain\u002Fskills\u002Flehrplan\u002FSKILL.md",[],[155,160,161,162,163,101,164,134,137,32],"drei","material","pro","curriculum","check",{"skillNo":166,"name":167,"nameZh":6,"description":168,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":169,"categories":170,"keywords":172,"publishedAt":37},"01M6CVK3ED9F94R65AD5PG0RRH","knowledge-exam","Generate German knowledge-check exams and solution files from the taught material (class Git history + WebUntis Lehrstoff). Use when the user says \"Wissensüberprüfung erstellen\", \"Knowledge-Check generieren\", \"Prüfung schreiben\", \"create the knowledge check\", \"generate a mini-exam\" or \"make the exam for class X\", or asks for exam questions plus solutions from what was actually taught. Do not use for grading submissions (knowledge-assessment) or for assignments in the class folder (homework).","https:\u002F\u002Fgithub.com\u002Fgeorgernstgraf\u002Fopencode-helpers\u002Fblob\u002Fmain\u002Fskills\u002Fknowledge-exam\u002FSKILL.md",[171],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[24,173,174,161,164,134,29,120,175,32,176,177],"exam","knowledge exam","generate","history","german"]