The template repo now keeps three branches with fixed meanings — main is
stable, test is the release candidate, experimental is development — and
ckb-init/ckb-upgrade can source from any of them instead of only main.
Selection is per-invocation, in words the user already uses ("initialize
from the test branch", "check experimental for updates", "switch back to
stable"), and sticky: the resolved repo and branch are written to a
template: block in ckb.yaml. Without persistence, a KB bootstrapped from
experimental would be silently pulled back to main by its next upgrade.
A missing file or missing block both mean main, so every KB predating
this convention behaves exactly as before.
One consequence needed explicit handling. A KB tracking test or
experimental can sit on a VERSION main has not released yet, so comparing
it against main finds nothing newer — which the version check would have
reported as "up to date". That is true and misleading. ckb-upgrade now
reports it as "ahead", and treats a move back to main as a downgrade:
explicitly confirmed, with the specific losses named, and blocked
outright where kb_schema_version would drop below what local pages are
already written against.
ckb-module is told not to clobber the template: block — a module install
that silently reset a KB's channel would change what its next upgrade
pulls, which is not a module's business.
Documented in both READMEs, both MANUALs and both CHANGELOGs. VERSION
1.8.0 -> 1.9.0; kb_schema_version stays 1.5, since this is tooling rather
than a content contract.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Clears the 3 wiki/log.md entries recording the schema 1.4 -> 1.5 migration.
That was the entirety of Tier 1 content: no entity pages, project scopes,
decision records or graph edges existed to remove.
Only wiki/log.md changed. The other scaffold files already matched what
ckb-init produces at schema 1.5, and edges.json/overview.md keep their
existing last_updated dates because those dates are accurate — bumping them
would assert changes that did not happen.
Rule B would normally require a wiki/log.md entry for a change inside wiki/,
but writing "emptied the log" into the log it just emptied defeats the
reset. The record is in workload/2026-09-22_summary.md instead, and the
migration itself remains documented in CHANGELOG.md and in commits 474630e
and 2c4d57a.
Tier 2 (workload summaries), the template layer, schema 1.5 and template
version 1.8.0 are all preserved. Lint: 0 findings.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Records the cancelled reset (inventory run, nothing deleted) and the
fast-forward merge of graft-ideas into main pushed to both remotes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
Graft keeps a derived, disposable code graph in sync with a content hash
rather than a calendar, and keeps a protected block on every regenerated
node. This KB is the opposite kind of store — durable, curated, built from
material that cannot be regenerated — but several of Graft's mechanisms
port cleanly, and two of them close real gaps here.
Schema 1.5 is additive: every 1.4 page remains valid.
1. `## Crux` — verbatim source excerpts alongside the synthesis. A summary
can drift silently; a quote either still matches its source or it does
not. Lets `ckb-retrieve` ground an answer without a round-trip to the
archive, and makes drift mechanically detectable.
2. `## Notes` — human-authored and protected everywhere. Closes a real
gap: `ckb-index-external` regenerates connector pages wholesale, so an
annotation written there was previously destroyed on the next refresh.
3. `source_fingerprint`/`source_checked` — a digest of the material a page
was built from. Freshness by date says a page has aged; a fingerprint
says whether its evidence moved. Most valuable for connector-backed
libs, where documents change with no notice.
4. `lint_report.py --quick` — a deterministic one-line session-start
signal, wired into Rule E next to the existing `git status` check.
5. In-degree as a rank-fusion signal in `ckb-retrieve`, weighted below 1.0:
centrality is a prior, not evidence.
6. Blast radius — a new `ckb-ingest` step walking the graph backwards from
touched entities to find what the incoming material contradicts, before
writing anything. Ingest was additive-first, which is how a wiki
accumulates two pages that quietly disagree.
7. Edge vocabulary in `wiki/graph/index.md` rewritten as a question per
verb, and completed: `part_of` was written by `ckb-code-map` but never
declared. Added `produces`, `configures`, `validates`, `implements`.
Lint gains checks 12 (fingerprint drift), 13 (crux verbatimness) and 14
(the protected-Notes rule), verified against a synthetic fixture covering
stale digests, missing sources, fabricated quotes and paraphrased evidence.
Not adopted: the gitignored regenerable store, the MCP server and CLI
daemon, tree-sitter parsing, statusline hooks, telemetry.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Empty the KB back to the shape ckb-init creates: remove decision records
D-0001 and D-0002, the single graph edge, all five workload summaries and
the generated outputs/okf/ tree, then restore the empty scaffold with
kb_schema_version held at 1.4.
The decisions status-vocabulary table is preserved verbatim, since
ckb-decide and ckb-lint both validate against it. Lint reports 0 findings.
Restore point for the pre-reset content: tag pre-reset-2026-09-20 (0c06cb6).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Commit all in-flight work — ckb-module and ckb-reset skills, the
.agents/modules/ scaffold, OPENSPEC docs, decision records D-0001 and
D-0002, graph edges and workload summaries — so the reset that follows
is fully recoverable.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Graph edge endpoints use project-root-absolute paths per Rule C
(`/wiki/entities/foo.md`), while the `known` page set is keyed on paths
relative to `wiki/`. check_graph compared them directly, so every
conformant edge was reported as pointing at a missing page. Add the
`/wiki/`-stripped form to the candidate set, matching the normalisation
the decision-record check already performs.
Bump VERSION 1.6.0 -> 1.6.1.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
Sets up the layered wiki/linked/libs knowledge base described in
CLAUDE.md/AGENTS.md, with a frontmatter schema, recursive index/log
convention, and conformance lint checks aligned with Google's Open
Knowledge Format. Adds two on-demand Claude Code Skills: export-okf
(regenerate an OKF-conformant bundle at outputs/okf/) and sync-changes
(reconcile this repo's git history with its origin remote, surfacing
conflicts to the user).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>