ckb/.agents/skills/ckb-export-okf/SKILL.md
Michał Kopeć 3e303f8a65 Rename KB export/summary/sync skills with ckb- prefix
Rename four cascade-KB skills to a consistent ckb- namespace:
- export-okf        -> ckb-export-okf
- export-starlight  -> ckb-export-starlight
- project-summary   -> ckb-project-summary
- sync-changes      -> ckb-sync-changes

Update the name: frontmatter in each SKILL.md and all cross-references
in README.md, AGENTS.md, cascade-kb-init, and export-starlight. Historical
wiki/log.md entries are left unchanged as a record of past actions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 13:19:44 +02:00

181 lines
9.5 KiB
Markdown

---
name: ckb-export-okf
description: Export the local wiki/ knowledge base as an Open Knowledge Format (OKF) v0.1-conformant bundle at outputs/okf/, so any generic OKF tool can consume it. Use when the user asks to "export the wiki as OKF", "generate the OKF bundle", "export to OKF", "publish the OKF export", or "sync outputs/okf".
---
# Export to OKF skill
## Purpose
Regenerate `outputs/okf/` from the current `wiki/` tree as a bundle that
conforms to Google's Open Knowledge Format (OKF) v0.1 spec
(https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md),
so any generic OKF consumer (e.g. Google's reference graph visualizer) can
read this knowledge base without needing to understand this repo's richer,
more opinionated schema (`confidence`, `quality`, `retention`, `supersedes`,
dual-linking, the cascade layers). This is a one-way, on-demand export —
`wiki/` stays the authoritative source; `outputs/okf/` is always a derived
artifact of it, never edited by hand and never fed back in.
This skill only runs when explicitly invoked — it is deliberately not part
of the always-loaded `CLAUDE.md`/`AGENTS.md` Ingest/Lint workflows, so its
mapping ruleset doesn't tax every session's context.
## Trigger phrases
Use this skill when the user says things like:
- "export the wiki as OKF" / "export to OKF"
- "generate the OKF bundle" / "regenerate outputs/okf"
- "publish the OKF export"
- "sync outputs/okf with the wiki"
## How to run this skill
### Step 1 — Read the source tree
Read every file under `wiki/` (the whole tree, including `entities/`,
`graph/`, and any other subdirectories present). Note which filenames are
`index.md` or `log.md` at any depth (these are OKF's two reserved names) —
everything else is a concept document.
### Step 2 — Clear and rebuild `outputs/okf/`
`outputs/okf/` is a pure, fully-regenerated build artifact. Delete its
current contents (if any) and rebuild it from scratch by mirroring `wiki/`'s
directory structure 1:1 under `outputs/okf/`. Never hand-patch an existing
export — always regenerate the whole bundle, so it can't accumulate stale
files left over from wiki pages that were since renamed or removed.
Do not touch anything outside `outputs/okf/`. Do not run any `git`
commands — regenerating files is this skill's job; staging and committing
the result is a separate, explicit action left to the user.
### Step 3 — Transform concept documents (every file that isn't `index.md`/`log.md`)
For each such file, rewrite its frontmatter using this field mapping:
| wiki/ field | OKF output field | Rule |
|---|---|---|
| `type` | `type` | passthrough (required on both sides — every wiki page should already have one; if a page is somehow missing it, use `type: unknown` and flag it in the final report rather than skipping the file) |
| `resource` | `resource` | passthrough |
| `tldr` | `description` | rename |
| `last_updated` | `timestamp` | passthrough as-is (bare `YYYY-MM-DD` is a valid ISO 8601 date — do not fabricate a time-of-day that was never recorded) |
| *(none — derive)* | `title` | the first `# H1` heading in the body; if there is none, slugify the filename (e.g. `foo-bar.md` → "Foo Bar") |
| `confidence`, `quality`, `retention`, `supersedes`, `superseded_by`, `freshness_window_days` | same key names | passthrough unchanged, as OKF extension fields — OKF requires consumers to tolerate unrecognized keys, so these ride along as-is |
| `kb_schema_version` (only ever present on `wiki/index.md`) | *(omit)* | OKF's root `index.md` frontmatter is spec-limited to `okf_version` only; this key has no valid home in the bundle and is dropped, not relocated |
| *(none)* | `tags` | omit — there is no source field to derive it from; do not fabricate |
Then rewrite the body's links:
1. **Strip wikilinks.** Every dual-link in the source looks like
`[[Page Name]] / [Page Name](path.md)`. Delete the `[[...]]` half
(and the ` / ` separator if present), keep only the
`[text](path.md)` half. OKF has no wikilink concept.
2. **Rewrite repo-root-absolute intra-wiki links.** A link like
`/wiki/entities/foo.md` becomes `/entities/foo.md` — the OKF bundle
root is `outputs/okf/`, not the repo root, so the leading `/wiki`
segment must be stripped. Plain relative links (e.g.
`../entities/foo.md`) need no change, since the export mirrors
`wiki/`'s tree exactly.
3. **Leave `linked/<name>/...` and `libs/<name>/...` references
untouched.** These point outside `wiki/` and outside any
self-contained bundle — converting or inlining them is out of scope.
OKF explicitly tolerates broken links, so leaving these as
unresolvable-outside-the-repo references is spec-compliant. Count
how many of these you leave untouched, for the final report.
### Step 4 — Regenerate `index.md` files
**Root `outputs/okf/index.md`:** frontmatter contains *only*
`okf_version: "0.1"` — this is the one documented exception to "index.md
has no frontmatter" in the OKF spec. Body is a flat bullet list, one line
per linked page or subdirectory, in the form
`* [Title](path) - one-line description` (reuse each page's `description`,
i.e. the renamed `tldr`, as the description text). Drop the source
`wiki/index.md`'s "Use when" column entirely — it's a Claude-agent-only
lazy-loading optimization with no meaning to a generic OKF consumer — and
drop any prose sections (like the source's "## Entity Pages" paragraph).
**Every nested `index.md`** (`entities/index.md`, `graph/index.md`, and
any future topic-folder index): no frontmatter, ever. Strip the source's
explanatory prose and italic placeholder notes (e.g.
"*(No entities yet — populated on the next ingest.)*"), keeping only the
bullet list — an empty list is spec-valid if the directory has no pages
yet.
### Step 5 — Regenerate `log.md` files
For each `log.md` in the source tree (root and any subdirectory), reformat
its entries into OKF's convention: group entries by date under
`## YYYY-MM-DD` headers (date only, no time, newest date first), each
entry as a bullet:
```
* **Verb**: description with [links](/path/to.md) (source: original source text).
```
Map the source's `ACTION TYPE` to an OKF verb: `CREATE` → Creation,
`UPDATE` → Update, `DELETE` → Deprecation, `RESTRUCTURE` → Update (fallback
for anything else). Fold the source entry's `- **Source:**` line in as the
trailing parenthetical shown above rather than dropping it — it's useful
provenance information and OKF's format has room for free text after the
verb. Drop the `---` horizontal-rule separators between entries; they are
not part of OKF's log format.
### Step 6 — Handle non-reserved special pages
`wiki/error-book.md` and `wiki/overview.md` are not OKF reserved
filenames (only `index.md` and `log.md` are) — export them as ordinary
concept documents using the Step 3 rules like any other page. They should
already carry `type`/`tldr`/`last_updated` frontmatter; if you ever find
one that doesn't, that's a lint problem in the source wiki — flag it in
the report rather than silently patching the export.
### Step 7 — Validate the output bundle
Before reporting done, re-check the *generated* `outputs/okf/` bundle
against OKF's own conformance criteria (the same shape of check `CLAUDE.md`
§5 step 1 runs against the source wiki):
- Every non-reserved `.md` file has frontmatter with a non-empty `type`.
- The root `index.md`'s frontmatter contains only `okf_version` (or is
empty); every nested `index.md` has no frontmatter at all.
- Every `log.md` entry matches the `## YYYY-MM-DD` header pattern.
- Every intra-bundle link (i.e. every link you did NOT leave untouched in
Step 3.3) resolves to a file that actually exists in `outputs/okf/`. If
the rewrite in Step 3.2 produced a link that doesn't resolve, that's a
bug in this export, not an acceptable "broken link" — fix it before
reporting done, don't just note it as a warning.
### Step 8 — Report
Tell the user:
- How many concept documents were exported.
- How many `index.md`/`log.md` files were regenerated.
- How many `linked/`/`libs/` cross-cascade references were left
unconverted (Step 3.3), since those won't resolve if the bundle is ever
moved or shipped standalone.
- Any conformance issues found in Step 7 and whether they were fixed.
- A reminder that `outputs/okf/` has been regenerated on disk but not
staged or committed — that's a separate step for the user to take when
ready to publish the update.
## Edge cases
- **Empty `wiki/entities/` or `wiki/graph/`** (as of writing, both are
empty): still regenerate their `index.md` as an empty bullet list under
`outputs/okf/entities/` and `outputs/okf/graph/` — an empty index is
spec-valid, don't skip the directory entirely.
- **A wiki page missing `type`:** per Step 3, use `type: unknown` and flag
it in the report — this indicates the source wiki itself failed lint's
conformance check (see `CLAUDE.md` §5 step 1), which is worth surfacing
to the user rather than quietly masking it in the export.
- **A future `wiki/archived/` directory:** export it like any other
subdirectory (mirror the structure, apply the same per-file rules) —
OKF has no notion of archival status; `retention`/`freshness_window_days`
already ride along as extension fields for any consumer that cares.
- **Re-running the skill with no wiki changes since the last run** should
produce byte-identical output — if you notice non-determinism (e.g. from
arbitrary ordering when listing directory entries), sort filenames
alphabetically wherever you're generating a bullet list or walking a
directory, so re-runs are stable.