ckb/CHANGELOG.md
Michał Kopeć 6c0d70976c Add release channels: main, test, experimental
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>
2026-09-22 08:29:45 +02:00

18 KiB
Raw Blame History

Changelog & Schema Reference

Read this in: English | Polski

This file tracks two things: the page schema exactly as it stands today, and how this project arrived at its current version numbers.

There are two independent version numbers, and they are not the same thing:

Number Lives in Describes Who bumps it
kb_schema_version frontmatter of wiki/index.md the content contract — what a page may contain and what those fields mean ckb-upgrade (on a confirmed migration), ckb-module (additively, on install)
Template version VERSION the tooling layerAGENTS.md, the skills, the scripts, the docs ckb-upgrade, when it pulls a newer template

They move independently on purpose. You can take a newer set of skills without touching a single wiki page, and a wiki authored against an older schema keeps working — that is what the schema version is for.

Versioning policy. Bump the minor version for an additive change: a new optional field, a new optional body section, a new optional scaffold file. Bump the major version for a breaking one: changing or removing a required field, or changing an existing reserved filename convention. There has never been a major bump; every schema version to date has been additive, so any page written since 2026-07-13 is still valid today.


Contents

  1. Current page schema (1.5)
  2. KB schema version history
  3. Template version history
  4. Migrating between versions

Current page schema (kb_schema_version: "1.5")

Frontmatter — every non-reserved page

Every .md file under wiki/ except the reserved ones (index.md, log.md) carries YAML frontmatter. Only type is required; the rest are optional, and preferred where meaningful. The parser is deliberately simple — flat key: value pairs only, no nesting.

Field Required Meaning
type yes Open string: person, project, concept, library, decision, playbook, repository, component, … New values are always valid; readers tolerate unrecognised ones.
resource no Canonical URI of the authoritative external source this page describes, kept separate from the wiki's own commentary.
tldr no One-sentence summary optimised for LLM reading. This is what the index shows and what decides whether a page gets opened at all.
confidence no 0.01.0. Source corroboration. Set on write, decays if nothing reinforces it, raised by a new source that agrees.
quality no 0.01.0. Self-evaluation of the page's own structure and citations. Below 0.7 is flagged for review.
supersedes no Path to the older page this one replaces.
superseded_by no Path to the newer page that replaced this one. Always set both sides.
last_updated no YYYY-MM-DD. When the page last changed.
freshness_window_days no Days before lint flags the page as stale. Typical: 90 for a wiki page, 365 for a decision, 30 for a connector-indexed document.
retention no high / medium / low. A low page is archived (never deleted) after 2× its freshness window.
source_fingerprint no (1.5) Digest of the source this page was built from — sha256:<8 hex> for a local file, or etag:<value> / mtime:<iso8601> for a connector item.
source_checked no (1.5) YYYY-MM-DD — when that digest was last verified. Distinct from last_updated: a re-check that finds nothing changed advances this and leaves last_updated alone.

wiki/index.md alone carries kb_schema_version. It is a bundle-level declaration, not a per-page one — individual pages never carry it.

Frontmatter — decision pages

Pages with type: decision live in wiki/decisions/ as NNNN-slug.md and add:

Field Required Meaning
status yes proposed / accepted / rejected / superseded / reversed. The vocabulary is defined in wiki/decisions/index.md and validated by lint.
decided_on for accepted/rejected/reversed YYYY-MM-DD, the date the call was made.
decided_by when known Comma-separated names. Where genuinely unknown, write unknown rather than omitting the field — "we don't know who decided this" is itself worth recording.
affects no Comma-separated wiki paths this decision constrains.
review_on no YYYY-MM-DD to revisit. Lint reports these once the date passes.

Decision records are append-only. A decision is never rewritten to match a later change of mind: record a new one that supersedes it, and both stay on the record.

Reserved body sections

(New in 1.5.) Four ## headings mean the same thing on every page in every layer of the cascade. All are optional; where present, they mean exactly this and nothing else.

## Sources

Where the page came from. One bullet per source, each carrying a fingerprint:

## Sources

- `raw/archive/2026-09-21/kickoff-notes.md` — sha256:3f9a2c1e (checked 2026-09-21)

A freshness window is a guess that a source might have moved. A fingerprint is a fact about whether it did. Lint recomputes local digests and flags what actually changed, which is a different and more urgent finding than a page that has merely aged.

## Crux

Verbatim excerpts from those sources — evidence, never paraphrase — attributed to the source bullet they came from:

## Crux

> FDEs need the VDI *and* a Jira account before day one; the VDI request
> alone takes ten working days.
`raw/archive/2026-09-21/kickoff-notes.md`, under "Access"

Three to ten lines is the working range. A Crux approaching the length of the summary above it has stopped being evidence and become a second copy of the source. Two things follow from quoting rather than paraphrasing: a question can often be answered from the page instead of the archive, and drift becomes visible — a summary can wander from its source silently, a quote either still matches or it does not.

A page with no quotable source simply has no ## Crux. An empty or paraphrased one is worse than none, because it looks like evidence.

## Notes

Human-authored, and protected. No skill may rewrite, reflow, summarise or drop this section; regeneration preserves it byte-for-byte.

## Notes

<!-- Yours. Never rewritten by any skill. -->

This matters most on pages the agent regenerates — connector indexes, code maps — where everything else is discarded and rebuilt on the next run. It is the only place an annotation survives. Decision pages deliberately have no ## Notes: nothing regenerates them, and an append-only record with a freely editable annotation block invites exactly the retroactive revision the append-only rule exists to prevent.

Edge vocabulary

Relationships live in wiki/graph/edges.json (and each connector index's own graph/edges.json). The vocabulary is closed, and each verb is defined by the question it answers — if a proposed edge answers none of them, it belongs in the page's prose instead.

Verb Question it answers Since
part_of Where does this live? What is it a piece of? 1.5
uses What does this reach for at runtime? 1.1
depends_on What breaks if I change this? 1.1
produces Where does this output come from? 1.5
configures What changes this thing's behaviour? 1.5
validates What checks, tests, or judges this? 1.5
implements What contract must this honour? 1.5
caused Why did this happen? 1.1
contradicts What disagrees with this, unresolved? 1.1
supersedes What replaced this, and what did it replace? 1.1
decided_by Who made this call? 1.4
affects What does this decision constrain? 1.4
has_expertise_in Who can answer questions on this? 1.3
owns Who is responsible for this? 1.3
mentioned_in Which source document discusses this? 1.2 (lib indexes only)

Record one direction per relationship — part_of, supersedes, depends_on and uses are canonical, and the inverse is not stored as a second edge. Record edges only from demonstrated evidence; an absent edge beats a fabricated one, and a padded graph degrades retrieval rather than improving it (in-degree is used as a ranking signal).

Reserved scaffold

Path Since Purpose
wiki/index.md 1.1 Routing table; the only page carrying kb_schema_version
wiki/overview.md 1.1 High-level map of the KB
wiki/log.md 1.1 Reverse-chronological change log for wiki/
wiki/error-book.md 1.1 Systemic issues with root cause and fix
wiki/entities/ 1.1 Typed entity pages
wiki/graph/ 1.1 edges.json plus the vocabulary in index.md
wiki/query-gaps.md 1.2 Questions the wiki could not answer, driving demand-driven ingest
wiki/projects/ 1.2 Optional local query scopes
wiki/decisions/ 1.4 Numbered, append-only decision records, with their own log.md

Every subdirectory that groups pages carries its own index.md, so navigation stays lazy.


KB schema version history

1.5 — 2026-09-21 · evidence, fingerprints, and a completed edge vocabulary

Adopted from an analysis of trailhq/Graft, a context layer for coding agents that keeps a derived code graph in sync via content hashes rather than dates, and protects a user-authored block on every regenerated node. Graft's store is disposable and regenerable; this one is not, so most of its design does not transfer — but several mechanisms do, and two of them closed real gaps here.

Added:

  • ## Crux — verbatim source excerpts alongside the synthesis. Lets ckb-retrieve ground an answer without a round-trip to the archive (when the fingerprint still matches), and makes drift detectable.
  • ## Notes — human-authored and protected everywhere. This closed a real gap: ckb-index-external regenerates connector pages wholesale, so an annotation written there was previously destroyed on the next refresh.
  • ## Sources — formalised as a reserved section with one fingerprinted bullet per source. Previously an informal convention that ckb-retrieve relied on but no skill actually specified.
  • source_fingerprint / source_checked frontmatter.
  • Edge verbs part_of, produces, configures, validates, implements. part_of fixed a live inconsistency: ckb-code-map had been writing it since template 1.7.0 while the schema never declared it.

Changed:

  • wiki/graph/index.md rewritten as a question-per-verb table with conventions on edge direction and evidence.
  • ckb-ingest gained a blast-radius step: before writing, walk the graph backwards from touched entities to find what the incoming material confirms, extends or contradicts, and name the owners of affected pages. Ingest had been additive-first, which is how a wiki accumulates two pages that quietly disagree.
  • ckb-retrieve fuses graph in-degree as one ranked list among several, weighted below 1.0 — centrality is a prior, not evidence.
  • Rule E (session start) now runs lint_report.py --quick alongside git status: a deterministic one-line knowledge-rot signal costing no model tokens.
  • Lint gained checks 12 (fingerprint drift), 13 (crux verbatimness) and 14 (the protected-## Notes rule).

Compatibility: fully additive. A 1.4 page with none of the new sections or fields is valid 1.5. A migration will never manufacture a ## Crux — inventing quotes is precisely the failure that section exists to prevent.

1.4 — 2026-09-01 · decision records

Added: type: decision pages under wiki/decisions/ as NNNN-slug.md, with status, decided_on, decided_by, affects, review_on; the decided_by and affects edge verbs; wiki/decisions/index.md and its own log.md; the append-only rule. Answers "why is it like this", "who decided", and "what changed that decision" as direct lookups instead of a full-text guess. Owned by the ckb-decide skill.

1.3 — 2026-08-06 · people-to-topic edges

Added: the has_expertise_in and owns edge verbs, making "who knows about X" and "who owns X" a graph lookup rather than a full-text search. Recorded only from demonstrated evidence — attending a meeting is not expertise, and a job title is not ownership.

1.2 — 2026-07-29 · query scopes, gaps, and connector-backed libs

Added: wiki/projects/ (optional local query scopes grouping related pages, sources and graph areas); wiki/query-gaps.md (failed searches recorded as future ingest targets); raw/archive/<YYYY-MM-DD>/ as the agent-maintained filing destination; connector-backed libs/<name>/ with a user-authored source.yaml, an agent-owned generated index, and the mentioned_in edge verb used inside those indexes.

1.1 — 2026-07-13 · initial schema

The first versioned contract, shipped with the initial commit. Established the frontmatter field set (type, resource, tldr, confidence, quality, supersedes/superseded_by, last_updated, freshness_window_days, retention), the core edge verbs (uses, depends_on, caused, contradicts, supersedes), the wiki/ scaffold, the cascade priority rule, and the recursive index-and-log convention.

There was never a 1.0: versioning began with the first published schema.


Template version history

The tooling layer — AGENTS.md/CLAUDE.md, the skills, the scripts, the docs. Independent of the content schema above.

Version Date What landed Schema
1.9.0 2026-09-22 Release channels: main/test/experimental branches, branch-aware ckb-init and ckb-upgrade, template: block in ckb.yaml 1.5
1.8.0 2026-09-21 Seven ideas adopted from Graft: crux/notes/fingerprints, --quick lint mode, in-degree ranking, ingest blast radius, completed edge vocabulary → 1.5
1.7.0 2026-09-20 Opt-in modules (.agents/modules/, ckb-module, ckb.yaml); the software module with ckb-code-map and ckb-spec; ckb-reset; OpenSpec docs 1.4
1.6.1 2026-09-01 Fixed false-positive broken-edge findings in the lint graph check 1.4
1.6.0 2026-09-01 ckb-decide; detection half of lint moved into lint_report.py; OKF export moved into export_okf.py → 1.4
1.3.0 2026-08-06 Rank fusion, dedupe and rerank in ckb-retrieve; expertise and ownership lookups → 1.3
1.2.1 2026-07-29 AGENTS.md compressed — workflows moved out into skills, leaving a small always-loaded rule set 1.2
1.2.0 2026-07-29 Project scopes, query gaps, source-verified retrieval → 1.2
1.1.0 2026-07-20 Connector-backed libs/ with self-contained external source indexing (ckb-index-external) 1.1 *
1.0.0 2026-07-17 First tagged template: full skill set, LICENSE, MANUAL, bilingual docs 1.1

* Connector-backed libs shipped as tooling in 1.1.0, but the schema only recorded them — the source.yaml contract, the generated index shape, the mentioned_in verb — at 1.2, nine days later. The two numbers catching up with each other like this is normal, and is why the schema column shows what was in effect after each template release rather than what the release was about.

Versions 1.4.0 and 1.5.0 were never published — the template jumped from 1.3.0 to 1.6.0 on 2026-09-01.


Release channels

The template repo keeps three branches, and the version histories above track main only:

Branch What it is Who should track it
main Stable — the released template Everyone, by default
test Release candidate — validated before merging to main Anyone helping validate a release
experimental Development — active work, may be broken or reverted People developing the template itself

The branch a KB tracks lives in ckb.yaml:

template:
  repo: https://git.wierzbowa.cloud/michal/ckb.git
  branch: main

ckb-init writes it, ckb-upgrade reads it as the default and updates it when you switch. No ckb.yaml and no template: block both mean main.

One consequence worth knowing: a KB that took tooling from test or experimental can sit on a VERSION that main has not released yet. Comparing it against main then finds nothing newer — which is true, but is not the same as "up to date", and ckb-upgrade reports it as "ahead" rather than as current. Moving such a KB back to main is a downgrade: it can remove skills and lower kb_schema_version below what local pages are written against. It requires an explicit confirmation, and is blocked outright where the schema would drop below the content's own declared contract.


Migrating between versions

Say "upgrade the wiki" or "check for a newer template version". To use a different channel, name it: "upgrade from the test branch", "check experimental", "switch back to stable". The ckb-upgrade skill checks the canonical template repo, updates the tooling layer in place, and — separately, and only after you explicitly confirm — migrates existing wiki/ content up to the current schema while preserving every fact already collected.

The two halves are deliberately separate. Taking newer skills never rewrites your pages, and a content migration is never silent: it reports what it intends to change, batches anything it had to infer (such as a missing type) for your confirmation, and logs every touched page in wiki/log.md marked as a schema-migration backfill rather than new knowledge.

Because every schema version so far has been additive, an older wiki keeps working unmigrated. Migration is worth doing to make the newer checks meaningful — backfilled fingerprints are what give lint anything to verify — not because anything is broken without it.


Version & License

Current template version: VERSION. Current schema version: the kb_schema_version field in wiki/index.md. Licensed under the Apache License 2.0.