ckb/.agents/skills/ckb-upgrade/SKILL.md
Michał Kopeć 2c4d57acbc Add bilingual CHANGELOG with full schema and version history
Two version numbers exist in this project and are easy to confuse:
kb_schema_version (the content contract, in wiki/index.md) and VERSION
(the tooling layer). Until now neither had a written history, and the
page schema was documented in four places at three levels of detail.

CHANGELOG.md / CHANGELOG.pl.md consolidate both: the current schema in
full (frontmatter for all pages and for decisions, the three reserved
body sections, the closed edge vocabulary with a "since" column, the
reserved scaffold), then the schema history 1.1-1.5 and the template
history 1.0.0-1.8.0.

The history is reconstructed from git rather than from memory, so it
records what actually happened rather than a tidied version of it:

- There was never a schema 1.0; versioning began at 1.1 on 2026-07-13.
- Template 1.4.0 and 1.5.0 were never published — VERSION jumped from
  1.3.0 to 1.6.0 on 2026-09-01.
- Connector-backed libs shipped as tooling in 1.1.0, but the schema only
  recorded them at 1.2 nine days later. The schema column shows what was
  in effect after each release, with a footnote on the lag.

Registered with ckb-init (copied verbatim into a new KB) and ckb-upgrade
(taken wholesale from upstream rather than merged, since upstream is
authoritative about its own history). Cross-linked from both READMEs and
both MANUALs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 23:16:43 +02:00

429 lines
22 KiB
Markdown

---
name: ckb-upgrade
description: Check the canonical Cascade KB template repo (https://git.wierzbowa.cloud/michal/ckb) for a newer schema/tooling version, and if one exists, upgrade this KB's template layer (AGENTS.md/CLAUDE.md, .agents/skills/, LICENSE, VERSION, README/MANUAL docs, base .gitignore rules) in place. Also checks wiki/index.md's own kb_schema_version for compatibility (including the case of an unversioned, pre-schema wiki) independently of the template layer, and — only with explicit confirmation — can migrate existing wiki/ content (backfilling missing frontmatter, adding missing scaffold files) up to the current schema while preserving every fact already collected. Use when the user asks to "upgrade the wiki", "upgrade this KB", "check for a newer template version", "update the KB schema", "pull in the latest skills", or "is there a new version of ckb". Distinct from ckb-sync-changes (reconciles this repo's OWN origin remote with its own history) and ckb-init (bootstraps a brand-new, empty KB) — this skill updates an EXISTING, populated KB's tooling layer (and, if asked, its content's schema conformance) from a separate upstream template source.
---
# Upgrade skill
## Purpose
A Cascade KB, once created, tends to drift from the canonical template as
the template gains new skills, fixes, or schema refinements. This skill
answers "am I behind, and if so, can I catch up?" without risking the
knowledge collected since. It treats a KB as having two layers, and checks
each **independently** — a KB can be behind on one, the other, both, or
neither:
- **Template layer** — the schema/tooling that defines *how* the KB
behaves: `AGENTS.md`/`CLAUDE.md`, `.agents/skills/*`, `LICENSE`,
`VERSION`, `README.md`/`README.pl.md`/`MANUAL.md`/`MANUAL.pl.md`/
`CHANGELOG.md`/`CHANGELOG.pl.md`, and the base `.gitignore` rules. Compared via the root `VERSION` file. Freely
upgradable — these files hold no project-specific content.
- **Content layer** — everything the KB has actually learned:
`wiki/entities/`, `wiki/graph/edges.json`, `wiki/index.md`'s entity rows,
`wiki/log.md`, `wiki/overview.md`, `wiki/error-book.md`, plus `raw/`,
`outputs/`, `workload/`. Compared via `wiki/index.md`'s own
`kb_schema_version` field (a KB predating that convention entirely
counts as "unversioned" and behind by default). This skill **never**
touches any of it automatically — a migration only ever runs after
explicit confirmation (see Step 3 and Step 7), and even then it only
ever adds/backfills structure, never rewrites the substance of what a
page says.
It's entirely possible to be behind on the content layer while current on
the template layer, or vice versa: a KB might already have the latest
`AGENTS.md`/skills but still carry `wiki/` pages ingested years ago under
an older (or no) schema version, or the reverse. This skill checks and
offers to fix both, separately.
## Schema versioning policy
`wiki/index.md` is the only wiki file that carries `kb_schema_version`.
Treat it as the version of the wiki content contract, not as a per-page
field.
Use schema versions as `MAJOR.MINOR`:
- Bump the **minor** version for backward-compatible additions: optional
frontmatter fields, optional reserved wiki scaffolds, new optional
subdirectories such as `wiki/projects/`, or additional optional
index/log conventions.
- Bump the **major** version for breaking changes: removing or renaming a
required field, changing the meaning of an existing required field,
removing an existing reserved filename convention, or changing cascade
lookup semantics in a way older tooling cannot safely interpret.
The root `VERSION` file tracks the template/tooling release, not just the
wiki schema. When a schema convention changes in the template repo, update
the relevant docs/skills and `VERSION` in the same template-layer change.
When migrating an existing KB's content layer, bump `wiki/index.md`'s
`kb_schema_version` only after the confirmed migration has actually
completed.
This is different from `ckb-sync-changes` (reconciles *this* repo's own
commit history with *its own* `origin` remote — same content, no template
comparison) and from `ckb-init` (bootstraps a brand-new, empty KB from the
template — nothing to preserve because there's no content yet). This skill
assumes you already have a populated KB and want to catch it up with
template improvements made elsewhere, without disturbing anything you've
collected unless you specifically ask it to reshape that content's
structure too.
## Trigger phrases
- "upgrade the wiki" / "upgrade this KB"
- "check for a newer template version" / "is there a new version of ckb"
- "update the KB schema" / "pull in the latest skills"
Do **not** use this for "sync changes" (that's `ckb-sync-changes` — this
repo's own `origin`) or for setting up a brand-new KB (that's `ckb-init`).
## How to run this skill
### Step 1 — Fetch the canonical template for comparison
Clone the canonical repo shallowly into a scratch location under `tmp/`
never touch this repo's own git remotes or history to do this comparison:
```bash
rm -rf tmp/ckb-upgrade-src
git clone --depth 1 https://git.wierzbowa.cloud/michal/ckb.git tmp/ckb-upgrade-src
```
If the clone fails (network, auth, unreachable host), report the raw
error and stop — this skill does not fall back to a cached or partial
check, and does not retry silently.
### Step 2 — Compare template (tooling) versions
Read `VERSION` at the repo root (treat a missing file as `0.0.0` — an
older KB that predates this convention) and
`tmp/ckb-upgrade-src/VERSION`. Compare as dotted-integer tuples
(`1.2.0` > `1.1.9`), not as plain strings — e.g.:
```bash
python3 -c "
local_v = tuple(int(x) for x in open('VERSION').read().strip().split('.'))
remote_v = tuple(int(x) for x in open('tmp/ckb-upgrade-src/VERSION').read().strip().split('.'))
print('newer' if remote_v > local_v else 'same-or-older')
"
```
Record the result (`template_upgrade_available`: yes/no) and continue to
Step 3 regardless — a "no" here does **not** end the skill, because the
wiki content schema (Step 3) is checked independently and may still be
behind.
### Step 3 — Compare the wiki content's own schema version
This is a **separate** check from Step 2, and can find something to do
even when Step 2 didn't. Read the `kb_schema_version` frontmatter field
from local `wiki/index.md`, and from
`tmp/ckb-upgrade-src/wiki/index.md` (the version new KBs are created with
today). Compare as `(major, minor)` tuples, e.g. `"1.2"` > `"1.1"`.
- **Local `wiki/index.md` has no `kb_schema_version` at all** — this is an
**unversioned** wiki: either it predates the convention entirely, or it
was hand-built without the standard frontmatter. Treat it as behind by
default, same as version `"0.0"`.
- **Local version is older than the template's** — behind.
- **Local version is the same or newer** — not behind; nothing to do for
content.
Record the result (`wiki_schema_upgrade_available`: yes/no, plus the two
version strings for reporting).
**If both `template_upgrade_available` and `wiki_schema_upgrade_available`
are "no"** → report "already up to date — template v`X`, wiki schema
v`Y`," clean up the scratch clone (Step 8), and stop.
### Step 4 — Diff the template layer only (if `template_upgrade_available`)
Skip this step entirely if Step 2 found no template upgrade — go straight
to Step 5 with just the wiki-schema finding to present, if any.
The template layer is exactly these paths — never anything under `wiki/`,
`raw/`, `outputs/`, `workload/`, `tmp/`, `libs/`, or `linked/`:
- `AGENTS.md` (and the `CLAUDE.md` symlink — recreate it if it's missing
or isn't a symlink to `AGENTS.md`; don't diff its content, it's just a
symlink)
- `LICENSE`
- `VERSION`
- `README.md`, `README.pl.md`, `MANUAL.md`, `MANUAL.pl.md`,
`CHANGELOG.md`, `CHANGELOG.pl.md` — whichever exist upstream (an older
local KB may not have some of these yet). Take the changelogs from
upstream wholesale rather than merging: they record the template's
history, which the upstream copy is authoritative about.
- `.agents/skills/<name>/**` for every skill folder present in
`tmp/ckb-upgrade-src/.agents/skills/`
- `.agents/modules/<name>/**` for every optional module present upstream
(see `ckb-module`). Upgrade the module *payload* freely — it is inert
template content. But **never delete a skill under `.agents/skills/`
just because it is absent upstream**: it may be a module-installed copy
that this KB deliberately enabled. Check `ckb.yaml` before treating any
skill as removed upstream. When an installed module's payload changes,
say so and suggest reinstalling it — the installed copies are now stale.
- The base ignore rules in `.gitignore` (`libs/`, `linked/`, `tmp/`,
regenerated `outputs/` subfolders, `.env`, etc.) — merged, never
replaced wholesale (see Step 6)
For every path in that list, diff the local copy against the scratch
clone's copy:
- **Doesn't exist locally, exists upstream** (e.g. a skill or doc added
since this KB was created) — no local content at risk; stage it as an
addition.
- **Identical** — nothing to do.
- **Differs** — this needs care. The difference might be a template
improvement worth taking, or it might be a deliberate local
customization — nothing here can tell those apart automatically,
especially for `AGENTS.md`, which the [manual](../../../MANUAL.md)
explicitly tells users they're free to edit. Never silently overwrite;
queue it for Step 5.
### Step 5 — Present findings and get decisions
Present whichever of the two findings apply (one or both):
```markdown
## Upgrade available
### Template: v<local> → v<remote> (only if template_upgrade_available)
**New files** (nothing local to lose, will be added):
- <path>
- ...
**Changed files** (local content differs from the template):
- <path><one-line summary of the change, e.g. "Step 7 reworded" or
"trigger phrases extended">
- ...
### Wiki content schema: v<local-or-"unversioned"> → v<remote> (only if wiki_schema_upgrade_available)
Your `wiki/` content was built against an older (or no) schema version.
This doesn't stop anything from working, but some pages may be missing
frontmatter fields the current schema expects (`tldr`, `confidence`,
`quality`, `retention`, etc.), or missing structural pieces (e.g. no
`wiki/graph/` folder yet). Nothing factual would be rewritten — only
structure and metadata would be backfilled.
```
For each **changed template file**, ask via `AskUserQuestion` — batched
into one question if the user wants to move fast, or one at a time if
they'd rather review each — with options **"Take the template version"**,
**"Keep my local version"**, or **"Show me the full diff first."**
Default recommendation for template files:
- Skill files (`.agents/skills/**`), `LICENSE`, `VERSION` — lean toward
"take the template version." These are rarely hand-edited and are
exactly the kind of thing that should stay in sync.
- `AGENTS.md`, `README*`, `MANUAL*` — don't default silently. Say plainly
that local customization is common in these files and ask explicitly
rather than nudging toward either choice.
If `wiki_schema_upgrade_available`, ask a **separate**, explicit question
— don't fold it into the template-file batch, since it's a different kind
of decision with different risk (it touches `wiki/`, which this skill
otherwise never does):
> "Would you like me to also upgrade all wiki-related folders and data to
> the new standard? I'll review every page under `wiki/`, add any missing
> scaffold files, and backfill missing frontmatter fields — without
> rewriting any of the actual knowledge you've collected. For a large
> wiki this can take a while. Options: **Yes, rebuild to the new
> standard** / **No, just the template files** / **Show me what's
> missing first, then decide.**"
These two decisions are independent — a user can accept the template
upgrade and decline the wiki migration, or vice versa.
### Step 6 — Apply the accepted template-layer changes
Only if `template_upgrade_available` and at least one item was accepted:
- Copy accepted **new** and **changed** files from `tmp/ckb-upgrade-src/`
over their local counterparts.
- For `.gitignore`, don't overwrite it — append any upstream base rules
not already present locally (line-by-line comparison), preserving every
existing local line, including custom ones the user added for their own
project.
- If `CLAUDE.md` isn't a symlink to `AGENTS.md` (or is missing), recreate
it as one.
- Leave every path outside the template layer completely untouched at
this step — `wiki/` changes, if any, happen only in Step 7.
- Update local `VERSION` to the template's new version last, only once
every other accepted change has been applied successfully.
### Step 7 — Rebuild wiki content to the new schema (only if confirmed in Step 5)
This is the one part of this skill that writes under `wiki/` — it only
ever runs after the explicit confirmation from Step 5, never
automatically, and never partially without saying so. Warn the user
before starting if `wiki/entities/` has many pages, since this is a
per-page pass, not instant.
**a. Fill structural gaps first.** Check for the standard `wiki/` scaffold
pieces and create any that are missing, using the same empty-template
shape `ckb-init` writes for a fresh KB (never overwrite one that already
exists, even if it looks sparse):
- `wiki/entities/index.md`, `wiki/graph/index.md`, `wiki/graph/edges.json`
- `wiki/error-book.md`, `wiki/overview.md`
- Any subdirectory under `wiki/entities/`-style groupings that's missing
its own `index.md` per the Recursive Index & Log Convention.
**b. Backfill frontmatter on every existing page**, per the schema in
`AGENTS.md` page schema. For each `.md` file under `wiki/` (excluding the reserved
`index.md`/`log.md`/`error-book.md`), check its frontmatter against the
schema and fix only what's missing — never touch a field that's already
present, and never alter the page's body text:
- **Missing `type`** — infer conservatively from the page's own content
and location (e.g. a page under `wiki/entities/` describing a person,
project, library, or concept). Don't silently guess: batch every
inferred `type` into one list and confirm it with the user before
writing, since `type` is the field lint treats as most load-bearing.
- **Missing `tldr`** — synthesize a one-sentence summary from the page's
actual content. Low-risk, mechanical — no need to ask per-page.
- **Missing `confidence` / `quality`** — don't invent a placeholder
number. Re-read the page fresh and score it the same way `ckb-ingest`
would score a newly-synthesized page (source corroboration for
confidence, structure/citations/consistency for quality).
- **Missing `last_updated`** — set to today, and note in the log entry
(Step 7d) that the date reflects this migration, not original
authorship.
- **Missing `freshness_window_days` / `retention`** — set a reasonable
default appropriate to the page's apparent topic, the same judgment call
`ckb-ingest` makes for newly-written pages.
- **Missing dual-linking** on an existing cross-reference (only a
`[[wikilink]]` where a `[markdown](path.md)` link should also exist, or
vice versa) — add the missing form. Don't invent new cross-references
that weren't already there in some form.
**b2. Schema 1.4 → 1.5: evidence sections.** Schema 1.5 added the reserved
body sections (`## Sources`, `## Crux`, `## Notes`), the
`source_fingerprint`/`source_checked` frontmatter fields, and the completed
edge vocabulary in `wiki/graph/index.md`. Migrating a 1.4 wiki:
- **`wiki/graph/index.md`** — replace its vocabulary section with the
template's table verbatim. Existing edges stay valid; 1.5 only added
verbs (`part_of`, `produces`, `configures`, `validates`, `implements`),
it removed none.
- **`## Sources` without fingerprints** — backfill a digest for every cited
file that still exists (`sha256sum <file> | cut -c1-8`), with
`source_checked` set to today. Where the cited file is **gone**, do not
quietly drop the bullet: leave it and flag the page, because a page whose
evidence has vanished is a finding the migration surfaced, not one it
should bury.
- **`## Crux`** — do **not** manufacture one. A Crux is verbatim source
text, and inventing quotes during a migration is precisely the failure
the section exists to make impossible. Pages gain a Crux when they are
next ingested or deliberately re-grounded, and a 1.5 page with no Crux is
fully conformant.
- **`## Notes`** — add an empty one to generated pages under
`libs/<name>/` so the protected affordance exists. Elsewhere, leave it
absent.
These are additive: a 1.4 page with none of them is valid 1.5, so this step
never blocks the version bump. Backfilling fingerprints is worth doing in
the same pass anyway, since it is mechanical and it is what makes `ckb-lint`
check 12 meaningful from that point on.
**c. Bump `wiki/index.md`'s `kb_schema_version`** to the template's
current value, once every page has been checked.
**d. Log every touched page** in `wiki/log.md`, per Rule B's format — this
is the one legitimate exception to this skill's normal "never writes to
`wiki/log.md`" behavior, and should say clearly in each entry that the
change was a schema-migration backfill, not new knowledge:
```markdown
## [YYYY-MM-DD HH:MM] - UPDATE (schema migration)
- **File Affected:** `wiki/entities/foo.md`
- **Description:** Backfilled missing `tldr`, `confidence`, `retention` during schema migration to v<new>. No content changes.
- **Source:** ckb-upgrade schema migration
---
```
**e. Suggest running "Lint" afterward** as an independent verification
pass, rather than re-implementing lint's own conformance checks here —
the two skills should agree on what "conformant" means.
### Step 8 — Clean up and report
```bash
rm -rf tmp/ckb-upgrade-src
```
Report a summary covering whichever tracks actually ran:
```markdown
## Upgrade report
**Template version:** v<old> → v<new> (or "already current")
**Added:** <N> file(s) — <paths, or "none">
**Updated:** <N> file(s) — <paths, or "none">
**Kept local (declined template version):** <N> file(s) — <paths, or "none">
**Wiki content schema:** v<old-or-"unversioned"> → v<new> (or "already current" / "declined")
**Scaffold files added:** <paths, or "none">
**Pages backfilled:** <N><paths, or "none">
**Types inferred and confirmed:** <list, or "none">
```
If anything actually changed, close with the same reminder pattern as
`ckb-ingest`/`ckb-lint`: review the diff, then say "sync changes" to
commit and push it to *this KB's own* `origin` — not the template repo
just checked against, which is typically a different remote for any KB
other than the template project itself.
## Edge cases
- **No `VERSION` file locally** — treat local version as `0.0.0`; any real
template version counts as newer. Mention in the report that this KB
predates version tracking.
- **No `kb_schema_version` in local `wiki/index.md` at all** — treat as
unversioned/behind by default (Step 3), and say so plainly in the
report rather than silently treating it as "version 0.0."
- **This KB's own `origin` *is* the template repo itself** (i.e. this is
the template project's own working copy) — the checks still work
(they'll usually report "already up to date" on both fronts since
you're comparing against yourself), but note this in the report so it's
clear why an "upgrade" against your own remote looks like a no-op.
- **Network/auth failure cloning the template repo** — report the raw
error, make no changes on either track, and clean up any partial
scratch clone.
- **A "changed" template file's difference looks trivial** — still
surface it for a decision; don't invent a heuristic for "safe to
auto-take," since the cost of a wrong guess (silently discarding a real
customization) is worse than one extra question.
- **User declines every changed template file** — still add any pure-new
files (nothing lost by doing so) and bump `VERSION`, since the KB
genuinely is now aware it's on the newer template version even if it
kept its own customized copies of specific files.
- **User confirms the wiki migration but the wiki is very large** — process
it in batches with progress updates rather than promising instant
completion; it's fine for this to be the longest-running part of the
skill.
- **User declines the wiki migration** — still bump nothing under `wiki/`,
including `kb_schema_version` — leave it exactly as found, so a future
run of this skill still detects it as behind rather than silently
considering it handled.
- **A page's inferred `type` is ambiguous even after inspection** — ask
the user directly for that page rather than guessing between two
plausible types; don't let one uncertain page block backfilling the
rest.
- **Uncommitted local changes already present before running this skill**
— proceed anyway (nothing here is destructive; every change lands as an
ordinary working-tree diff, reversible with `git checkout`), but mention
in the report that there was pre-existing uncommitted work, so the user
knows the diff they're about to review isn't only from this upgrade.
- **A skill folder was renamed or removed upstream** — don't delete the
corresponding local folder automatically (it might still be in active
use, or further customized locally); mention it in the report as
"removed upstream, left in place locally" and let the user decide
separately.
---
*Licensed under the Apache License, Version 2.0 — see [LICENSE](../../../LICENSE)
at the repository root, or <http://www.apache.org/licenses/LICENSE-2.0>.*