Decision log (VERSION 1.6.0, kb_schema_version 1.4): - wiki/decisions/ scaffold — numbered NNNN-slug.md records, own index (with status vocabulary) and log - type: decision adds status/decided_on/decided_by/affects/review_on; supersedes/superseded_by carry history and must be set on both sides - New ckb-decide skill: records decisions and answers what/why/who/when, what superseded what, and what is still open. Decision pages are append-only — a changed mind is a new superseding decision - Graph gains decided_by and affects edge types - ckb-ingest routes decisions found in raw material to this format; ckb-retrieve gains the decisions index as a cascade step Scriptified the mechanical skills: - ckb-export-okf/scripts/export_okf.py does the whole OKF transform (frontmatter remap, link rewriting, index/log regeneration, conformance validation); --check validates without writing - ckb-lint/scripts/lint_report.py does the read-only detection half (conformance, freshness, confidence, retention, decisions, orphans, graph, index/log, source.yaml); judgment calls stay with the model Also: removed the duplicate personal quiz skill, fixed stale cbk-quiz doc paths, gitignored __pycache__. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8.3 KiB
| name | description |
|---|---|
| ckb-export-okf | 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.
The whole transform — frontmatter remapping, link rewriting, index and log regeneration, conformance validation — is done by a deterministic Python script, not by reading and rewriting every page by hand. The mapping is a fixed ruleset over a wiki that will keep growing, and a mechanical transform like this belongs in code, not in per-page model reasoning. Nothing in this skill needs an LLM to run correctly; the model's job is to invoke the script and relay its report.
This skill only runs when explicitly invoked — it is deliberately not part
of the always-loaded CLAUDE.md/AGENTS.md Ingest/Lint workflows.
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 — Run the script
From the repository root:
python3 "<skill-dir>/scripts/export_okf.py"
Resolve <skill-dir> to this skill's own directory. Flags:
--check— build into a temporary directory, run the conformance checks, print the report, and write nothing tooutputs/. Use this when the user wants to know whether the wiki would export cleanly without touching the working tree (e.g. as part of a review, or before a lint pass).--out DIR— write somewhere other thanoutputs/okf(rarely needed).
The script deletes and rebuilds the output directory on every run, so the
bundle can never accumulate stale files from pages that were since renamed
or removed. It touches nothing outside the output directory and runs no
git commands.
The exit code is 0 when the generated bundle conforms and 1 when it does
not — the report always prints either way, so read it rather than relying on
the exit code alone.
Step 2 — Relay the script's report
The script prints, and you should summarize back to the user:
- Concept documents exported, and
index.md/log.mdfiles regenerated. - Wikilinks stripped and
/wiki/links rewritten to bundle-root paths. - How many
linked//libs/cross-cascade references were left unconverted — those won't resolve if the bundle is ever moved or shipped standalone, which is spec-compliant (OKF tolerates broken links) but worth stating. - Any
SOURCE ISSUE:lines. These are problems inwiki/itself, not in the export — most commonly a page with notype, which the bundle exports astype: unknown. Surface them; the fix belongs in the source wiki (runckb-lint), not in the export. - Any
NONCONFORMANT:lines. These are bugs in the export — an intra-bundle link that doesn't resolve, an index with the wrong frontmatter shape, a malformed log header. Do not report the run as successful when these appear; investigate the script rather than hand-patchingoutputs/okf/. - A reminder that
outputs/okf/has been regenerated on disk but not staged or committed — that's a separate step for the user when they're ready to publish the update. (outputs/okfis gitignored by default in this template, so "publish" usually means copying the bundle elsewhere rather than committing it in place.)
What the transform does (for context, not something you need to re-derive)
Concept documents (every .md that isn't index.md/log.md, including
overview.md, error-book.md, and query-gaps.md — only index.md and
log.md are OKF reserved names):
| wiki/ field | OKF output field | Rule |
|---|---|---|
type |
type |
passthrough; a page with no type exports as unknown and is reported as a source issue |
| (derive) | title |
the first # H1 in the body, else the slugified filename (foo-bar.md → "Foo Bar") |
tldr |
description |
rename |
resource |
resource |
passthrough |
last_updated |
timestamp |
passthrough as-is (bare YYYY-MM-DD is valid ISO 8601 — no time-of-day is fabricated) |
confidence, quality, retention, supersedes, superseded_by, freshness_window_days |
same keys | passthrough as OKF extension fields, which consumers must tolerate |
kb_schema_version |
(dropped) | the root index.md's frontmatter is spec-limited to okf_version; this key has no valid home in the bundle |
| (none) | tags |
omitted — no source field to derive it from |
Links: the [[Wikilink]] half of every dual-link is dropped, keeping the
markdown half (a bare wikilink with no markdown twin degrades to its plain
label). Root-absolute /wiki/entities/foo.md becomes /entities/foo.md,
since the bundle root is outputs/okf/, not the repo root. Relative links
need no change — the export mirrors wiki/'s tree exactly.
linked/<name>/... and libs/<name>/... references are left untouched and
counted.
Indexes: regenerated from the tree rather than transcribed from the
source, so they can't drift. The root index.md carries only
okf_version: "0.1" (the one documented exception to "index.md has no
frontmatter"); nested indexes carry none. Each body is an H1 plus a flat
* [Title](path) - description bullet list of that directory's direct
children, sorted by path, with each page's own description as the
description text. The source's "Use when" column and prose sections are
dropped — they are Claude-agent lazy-loading optimizations with no meaning
to a generic OKF consumer. An empty list is spec-valid.
Logs: entries are regrouped under ## YYYY-MM-DD headers (date only,
newest date first) as * **Verb**: [affected files] — description (source: ...).
CREATE → Creation, UPDATE → Update, DELETE → Deprecation, anything else
→ Update. The - **Source:** line rides along as the trailing parenthetical
rather than being dropped — it's provenance worth keeping. The ---
separators between entries are dropped; they aren't part of OKF's log format.
Validation runs against the generated bundle before the report prints:
every non-reserved page has a non-empty type; the root index has only
okf_version and nested indexes have no frontmatter; every log.md header
matches ## YYYY-MM-DD; and every intra-bundle link resolves to a file that
exists (cross-cascade linked//libs/ references are exempt by design).
Edge cases
- Empty
wiki/entities/orwiki/graph/: theirindex.mdis still regenerated, as an H1 with an empty bullet list. An empty index is spec-valid; the directory is never skipped. - A future
wiki/<newtopic>/subdirectory: handled automatically — the script discovers directories dynamically, mirrors them, and generates an index for each. No script changes needed. - A future
wiki/archived/: exported like any other subdirectory. OKF has no notion of archival status;retention/freshness_window_daysalready ride along as extension fields for any consumer that cares. - Non-markdown files in
wiki/(e.g.graph/edges.json): copied verbatim into the same relative position and listed in their directory's index. Dotfiles (.gitadd) are skipped. - Re-running with no wiki changes: produces byte-identical output — every directory walk and generated list is sorted. If a run is ever nondeterministic, that's a bug in the script, not expected behavior.
Licensed under the Apache License, Version 2.0 — see LICENSE at the repository root, or http://www.apache.org/licenses/LICENSE-2.0.