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>
806 lines
42 KiB
Markdown
806 lines
42 KiB
Markdown
# User Manual
|
|
|
|
*Read this in: **English** | [Polski](MANUAL.pl.md)*
|
|
|
|
This is the human-facing manual for working with a Cascade Knowledge Base
|
|
(this repo). It's written for the *person* using the wiki, not the agent —
|
|
for the agent's own operating rules, see [AGENTS.md](AGENTS.md) /
|
|
[CLAUDE.md](CLAUDE.md). For a feature-by-feature technical overview, see
|
|
[README.md](README.md). For the page schema in full and the version
|
|
histories behind it, see [CHANGELOG.md](CHANGELOG.md). This document is
|
|
task-oriented: "I want to do X — what do I say, and what happens?"
|
|
|
|
Everywhere below, "say" means typing it to whatever AI coding agent you're
|
|
using against this repo (Claude Code, or another agent that reads
|
|
`AGENTS.md`). You don't need exact wording — the trigger phrases shown are
|
|
examples, not magic words; the agent matches intent.
|
|
|
|
---
|
|
|
|
## Contents
|
|
|
|
1. [Creating or initialising a wiki](#1-creating-or-initialising-a-wiki)
|
|
2. [Adding knowledge](#2-adding-knowledge)
|
|
3. [Keeping it tidy](#3-keeping-it-tidy)
|
|
4. [Syncing — with yourself, and with other people](#4-syncing--with-yourself-and-with-other-people)
|
|
5. [Upgrading the template](#5-upgrading-the-template)
|
|
6. [Use cases](#6-use-cases)
|
|
7. [What's agent-generated vs. what you can edit](#7-whats-agent-generated-vs-what-you-can-edit)
|
|
8. [Quick reference](#8-quick-reference)
|
|
|
|
---
|
|
|
|
## 1. Creating or initialising a wiki
|
|
|
|
### If you're reading this inside an existing Cascade KB
|
|
|
|
Nothing to do — the structure already exists (`wiki/`, `raw/`, `outputs/`,
|
|
etc.). Skip to [§2](#2-adding-knowledge).
|
|
|
|
### Starting a brand-new one elsewhere
|
|
|
|
Say:
|
|
|
|
> "Set up a new wiki like this one in `~/projects/my-notes`."
|
|
|
|
This clones the *schema* only — the directory structure, the
|
|
`AGENTS.md`/`CLAUDE.md` behaviour file, and an empty `wiki/` scaffold — into
|
|
the target folder. It never copies this project's actual content (no
|
|
entities, no graph data, no notes). You get a fresh, empty KB, ready for its
|
|
first `raw/inbox/` drop. See `.agents/skills/ckb-init/SKILL.md`.
|
|
|
|
The template can come from two places: this repo's own files, or a fresh
|
|
shallow clone of the canonical template repo (or any fork/mirror URL you
|
|
name) pulled into a scratch folder. Say "pull the latest template and set
|
|
up a KB in \<folder\>" — or run it from outside any KB at all — and the
|
|
agent clones first, then builds the scaffold from that. The clone is
|
|
scratch only: the new KB gets its own git history (the agent asks before
|
|
running `git init`), not the template's.
|
|
|
|
If the target folder already looks like a KB (it has a `wiki/` or
|
|
`AGENTS.md` already), the agent will stop and ask before touching anything
|
|
— it won't silently overwrite an existing knowledge base.
|
|
|
|
### Building on top of someone else's wiki
|
|
|
|
A Cascade KB can sit on top of one or more *upstream* knowledge bases,
|
|
which stay entirely read-only. There are three ways to mount one:
|
|
|
|
- **Symlink** (another KB on your own machine, or one you maintain
|
|
elsewhere and want live-linked):
|
|
```bash
|
|
ln -s /path/to/other-kb ./linked/other-team
|
|
```
|
|
- **Git clone** (an external KB you want a frozen, version-controlled copy
|
|
of):
|
|
```bash
|
|
git clone https://github.com/org/external-kb ./libs/external-kb
|
|
```
|
|
Don't want to use git? Most git hosts also offer a "Download ZIP"
|
|
option on the repo's page — download it and unpack the contents
|
|
straight into `./libs/external-kb` instead. You end up with the same
|
|
frozen, read-only copy either way; the only difference is you won't be
|
|
able to `git pull` it later to refresh — to update it, just re-download
|
|
the ZIP and unpack it over the old contents.
|
|
- **Connector** (a live external source you *don't* want a full local
|
|
copy of — a SharePoint folder, a Google Drive folder, or another
|
|
connected source): create `libs/<name>/source.yaml` yourself:
|
|
```yaml
|
|
connector: sharepoint
|
|
location: "https://contoso.sharepoint.com/sites/Finance/Shared Documents/Reports"
|
|
description: "Finance team's shared reports folder"
|
|
```
|
|
then say "index external sources." The agent reads the config, connects
|
|
to whatever's available that session (a connected Microsoft 365/Google
|
|
Drive tool, or a plain URL fetch), and builds a short index of what it
|
|
finds — one entry per document — inside that same `libs/<name>/` folder.
|
|
See [§6](#6-use-cases) for a worked example and what the result looks
|
|
like.
|
|
|
|
Two things worth knowing up front about a connector source:
|
|
- **You don't have to build the index yourself.** `source.yaml` can add
|
|
an `index:` block pointing at an already-built index — a git repo, or
|
|
a shared resource — so you just fetch what someone else already
|
|
indexed instead of scanning the live source yourself. Every run checks
|
|
that location first: if there's already an index there, you get it; if
|
|
there isn't yet (the normal state before anyone's run this with write
|
|
access), that's not an error — whoever has write access is the one
|
|
whose next run creates and publishes it there for the first time.
|
|
- **Building/refreshing is opt-in per person, per source.** By default,
|
|
everyone is read-only for a connector source — nobody's agent will
|
|
scan the live connector on their behalf unless they've explicitly said
|
|
so. Say "make me the admin for `<source>`" to opt yourself in (this
|
|
writes a local, personal `libs/<name>/source.local.yaml` — never
|
|
committed, never seen by anyone else). This is deliberate: it lets one
|
|
or two people maintain a source for the whole team instead of everyone
|
|
redundantly re-scanning it.
|
|
- **You can set how often it should be refreshed.** Add an optional
|
|
`refresh_interval_days: 7` to `source.yaml` (it defaults to 30). A
|
|
folder that churns daily wants a shorter window than a quarterly
|
|
archive nobody touches. Both "index external sources" and "Lint" then
|
|
tell you when a source is overdue and by how much — which matters most
|
|
if you're read-only for it, since knowing *which* source has gone
|
|
stale is what lets you go ask the person who maintains it.
|
|
|
|
Either way, once it's mounted, just ask questions normally — the agent
|
|
checks your local `wiki/` first, then walks `linked/`, then `libs/`, and
|
|
uses whichever has the answer. You never edit files inside `linked/` or a
|
|
git-copy `libs/<name>/` directly; if something there is wrong or outdated,
|
|
you fix it by writing the corrected version into your own local `wiki/`,
|
|
which always wins. (A connector-backed `libs/<name>/` is the one place the
|
|
agent *does* write on your behalf — see [§6](#6-use-cases) — but only its
|
|
generated index, and only the build/refresh part if you're that source's
|
|
admin; `source.yaml` itself always stays yours to edit, never the agent's.)
|
|
|
|
---
|
|
|
|
## 2. Adding knowledge
|
|
|
|
This is the main way the wiki grows. There are two on-ramps:
|
|
|
|
### A. Drop material, then say "Ingest"
|
|
|
|
Put anything unprocessed into `raw/inbox/` — pasted notes, a `.txt`
|
|
transcript, a `links.txt` of URLs, a PDF, a messy scratch file. No need to
|
|
organise it first. Then say:
|
|
|
|
> "Ingest." (or "Sync the wiki" / "Update the wiki" — same thing)
|
|
|
|
Example:
|
|
|
|
> *You drop `meeting-2026-07-10.txt` (rough notes from a client call) into
|
|
> `raw/inbox/`, then say "Ingest."*
|
|
>
|
|
> The agent reads the file, extracts the people, decisions, and open
|
|
> questions mentioned, creates or updates entity pages under
|
|
> `wiki/entities/`, records relationships in `wiki/graph/edges.json`, adds
|
|
> the new pages to `wiki/index.md`, logs the change in `wiki/log.md`, and
|
|
> moves the original file to `raw/archive/2026-07-10/`. It finishes by
|
|
> reminding you to review the result and say "sync changes" once you're
|
|
> happy with it.
|
|
|
|
For a long transcript, the agent doesn't just write one summary page. It
|
|
pulls out the searchable question, the summary, the resolution, the systems
|
|
and people involved — and promotes individual passages to their own
|
|
findable sections when they'd otherwise be lost inside a summary. That last
|
|
part has a deliberate bar: a passage has to contain a genuinely specific
|
|
term (a flag, an error string, a clause, a version), run to a couple of
|
|
sentences at least, and be corroborated by something later in the material.
|
|
Otherwise it stays folded into the summary. Without that bar every
|
|
paragraph looks quotable and the wiki page ends up being the transcript
|
|
again, which defeats the point of ingesting it.
|
|
|
|
If `raw/inbox/` is empty, the agent scans `raw/` directly instead (still
|
|
skipping `raw/archive/`, which is already-processed history).
|
|
|
|
This is implemented by the `ckb-ingest` skill —
|
|
`.agents/skills/ckb-ingest/SKILL.md`.
|
|
|
|
### B. Just tell the agent something in conversation
|
|
|
|
You don't always need a file. If you tell the agent a fact worth keeping —
|
|
"actually, the deadline moved to September" — and it has lasting value, the
|
|
agent can file it straight into `wiki/` as a new page or an update to an
|
|
existing one, the same as it would from an ingested file.
|
|
|
|
### C. Let the agent tell you what's missing (Demand-Driven Context)
|
|
|
|
If you ask something the wiki can't answer, the agent doesn't just fail
|
|
silently — it identifies the gap and proposes a minimal page to fill it.
|
|
|
|
Example:
|
|
|
|
> **You:** "What's our policy on X?"
|
|
> **Agent:** "The wiki doesn't cover that yet. Want me to add a stub page
|
|
> for it, or can you paste/describe the policy and I'll write it up?"
|
|
|
|
You approve, paste the source, or drop it in `raw/inbox/` — the next
|
|
ingest incorporates it. This keeps the wiki demand-driven: it grows around
|
|
what you actually ask, not everything that could theoretically be written
|
|
down.
|
|
|
|
Durable misses can also be tracked in `wiki/query-gaps.md`. A good gap
|
|
entry is tiny: the question, where the agent looked, and the smallest
|
|
source or page that would make the answer available next time.
|
|
|
|
### D. Record a decision
|
|
|
|
When a call gets made — a technology choice, a process change, a policy —
|
|
say:
|
|
|
|
> "Record a decision: we're moving billing to Postgres. Alice and Bob
|
|
> decided it today, because the reporting queries were killing MySQL."
|
|
|
|
The agent writes a numbered record under `wiki/decisions/` with the decision,
|
|
who decided, when, the rationale, the alternatives, and what it affects. If
|
|
it replaces an earlier decision, it links the two in both directions and
|
|
marks the old one superseded — without touching the old page's reasoning.
|
|
Anything you leave out, it asks for in one round; if you're mid-flow, say so
|
|
and it records what you gave it and tells you which fields it left open.
|
|
|
|
Then ask about them however you like:
|
|
|
|
> "What did we decide about the billing database?"
|
|
> "Why do we use Postgres?"
|
|
> "Who decided that, and when?"
|
|
> "Which decisions are still just proposed?"
|
|
> "What superseded decision 3?"
|
|
|
|
The answer always comes with who and when attached, and says plainly when a
|
|
decision is proposed rather than accepted, or has since been superseded —
|
|
so you don't act on something that isn't in force. Implemented by the
|
|
`ckb-decide` skill.
|
|
|
|
Two things worth knowing:
|
|
|
|
- **Decisions are append-only.** "Actually, we changed our mind" creates a
|
|
*new* decision that supersedes the old one; it never edits the old one's
|
|
reasoning. That's deliberate — the history is the point. Genuine
|
|
transcription errors ("I said Alice, it was Anna") do get fixed in place.
|
|
- **A proposal is not a decision.** If it wasn't actually settled, it's
|
|
recorded as `proposed` with no decision date, and shows up when you ask
|
|
what's still open.
|
|
|
|
### E. Create a local project scope
|
|
|
|
When a topic, client, system, or initiative comes up often, ask:
|
|
|
|
> "Create a project scope for payments integration."
|
|
|
|
The agent creates or updates a plain Markdown page under `wiki/projects/`
|
|
listing the pages, entities, raw/archive files, connector indexes, and graph
|
|
areas that should be searched first for that scope. You still keep one
|
|
local wiki; this just gives repeated questions a better starting area.
|
|
|
|
---
|
|
|
|
## 3. Keeping it tidy
|
|
|
|
Say, whenever you like (there's no fixed schedule — do it after a big
|
|
ingest, or just periodically):
|
|
|
|
> "Lint."
|
|
|
|
This runs a health check across the whole wiki:
|
|
|
|
- pages missing required frontmatter (`type`) get flagged
|
|
- pages that haven't been touched in a while get flagged as stale
|
|
- confidence scores decay if nothing has reinforced them recently
|
|
- old, low-priority pages get archived to `wiki/archived/` (never deleted)
|
|
- contradicting pages get linked old→new (supersession)
|
|
- orphaned pages (nothing links to them) get backlinked or archived
|
|
- broken graph edges get fixed or removed
|
|
- missing/duplicate index and log entries get corrected
|
|
- connector-backed sources whose index is overdue for a refresh get
|
|
flagged, with how overdue they are — useful even if you're read-only for
|
|
that source, since it tells you who to chase
|
|
- **pages whose source has actually changed** get flagged — see below
|
|
- **quotes that no longer appear in the source they cite** get flagged
|
|
- recurring systemic issues get written into `wiki/error-book.md`
|
|
|
|
The last two are worth understanding, because they're the difference
|
|
between "this page is old" and "this page is wrong".
|
|
|
|
Every page records a fingerprint of the material it was built from. Staleness
|
|
by date is a guess: a page written a year ago may still be perfectly accurate.
|
|
A fingerprint is not a guess — the agent recomputes it and either the source
|
|
is byte-for-byte what the page was written against, or somebody edited it.
|
|
When a source changes, the page built on it goes to the top of the list,
|
|
ahead of anything that has merely aged.
|
|
|
|
Pages also quote their sources directly, in a `## Crux` section — a few
|
|
verbatim lines carrying the actual claim, underneath the agent's summary of
|
|
it. Two things follow from that. When you ask a question, the agent can often
|
|
answer from the quote instead of re-reading the whole source, and show you the
|
|
words rather than its paraphrase of them. And when a quote stops matching its
|
|
source, that's a page asserting, in quotation marks, something its evidence no
|
|
longer says — the strongest finding lint produces, and the agent will never
|
|
"fix" it by quietly editing the quote to match.
|
|
|
|
The detection half runs as a read-only Python script
|
|
(`scripts/lint_report.py`), so the same wiki always produces the same
|
|
findings list — the agent reads that report and then does the parts that
|
|
need judgment (supersession, ambiguous orphans, error-book entries, and
|
|
deciding what to fix versus what to hand back to you). It fixes what it
|
|
safely can on its own, and reports the rest for you to decide. Like Ingest, it finishes by reminding you to review and sync.
|
|
Implemented by the `ckb-lint` skill —
|
|
`.agents/skills/ckb-lint/SKILL.md`.
|
|
|
|
### Starting over: resetting to a clean template
|
|
|
|
Sometimes you want the *shape* of a knowledge base without its contents —
|
|
typically because this repo doubles as the template you hand to other
|
|
people, and it has accumulated decisions, workload summaries and entity
|
|
pages that shouldn't ship with it.
|
|
|
|
> "Reset the wiki." / "Make this a clean template."
|
|
|
|
This is the one command in this repo that **deletes knowledge on purpose**,
|
|
so it is built to be hard to trigger by accident:
|
|
|
|
1. **It looks for a restore point first.** If your working tree is dirty it
|
|
stops and offers to commit, because after a reset anything committed is a
|
|
`git checkout` away and anything uncommitted is simply gone. It can also
|
|
tag the commit (`pre-reset-<date>`) so you don't have to keep a hash in
|
|
your head.
|
|
2. **It asks how far to go.** Six tiers, chosen individually: wiki knowledge,
|
|
workload history, `raw/` source material, `outputs/`, external sources,
|
|
and installed modules. Only the first is on by default. `libs/`,
|
|
`linked/` and modules default to *no* — `linked/` holds symlinks into
|
|
other people's knowledge bases, and it will remove a link but never
|
|
follow one.
|
|
3. **It counts before it asks.** You get an inventory — how many pages, how
|
|
many decision records (listed by number and title), how many graph edges,
|
|
plus anything marked `retention: high` — and one line on what survives.
|
|
4. **It wants a typed phrase**, not a "yes". And if you change the scope in
|
|
your reply, it re-counts and asks again, because you agreed to a number
|
|
and the number moved.
|
|
5. **It verifies afterwards**, running lint before telling you it worked.
|
|
|
|
What it restores is exactly what `ckb-init` would create: same directories,
|
|
same scaffold files, same `kb_schema_version`. Emptying the content doesn't
|
|
roll back the schema.
|
|
|
|
What it never touches, with or without confirmation: the template layer
|
|
(`AGENTS.md`, `.agents/`, `LICENSE`, `VERSION`, the docs) and `src/`, which
|
|
holds independent code repositories this command has no business deleting.
|
|
|
|
One deliberate quirk: unlike every other skill, this one does **not** write a
|
|
`workload/` session note — that entry would be the first thing in a directory
|
|
it has just emptied. It tells you so in its report.
|
|
|
|
Implemented by the `ckb-reset` skill —
|
|
`.agents/skills/ckb-reset/SKILL.md`.
|
|
|
|
---
|
|
|
|
## 4. Syncing — with yourself, and with other people
|
|
|
|
There are two entirely different kinds of "sync" here — don't confuse
|
|
them:
|
|
|
|
| | Ingest / Lint | Sync changes |
|
|
|---|---|---|
|
|
| **Layer** | Content (what the wiki knows) | Git (whose disk has which files) |
|
|
| **What it touches** | `wiki/`, `raw/` | The repo's commit history and `origin` remote |
|
|
| **Say** | "Ingest" / "Lint" | "Sync changes" |
|
|
|
|
### Reconciling with `origin` (git-level sync)
|
|
|
|
Say:
|
|
|
|
> "Sync changes."
|
|
|
|
This commits whatever local changes you have (e.g. from a recent Ingest or
|
|
Lint pass), pulls down anything new from `origin`, merges the two, and —
|
|
if there's a conflict — walks you through it file by file, asking you to
|
|
keep your version, keep the remote version, or supply merged text for each
|
|
conflicting block. Once everything's resolved, it pushes.
|
|
|
|
If this repo has never been connected to a remote, the agent will ask you
|
|
to paste the URL first:
|
|
|
|
> **Agent:** "This repo has no `origin` remote configured. Paste the URL
|
|
> of the remote repository and I'll add it as `origin`."
|
|
>
|
|
> **You:** `https://git.wierzbowa.cloud/michal/ckb`
|
|
|
|
For *this* Cascade KB, that source repo —
|
|
[git.wierzbowa.cloud/michal/ckb](https://git.wierzbowa.cloud/michal/ckb) —
|
|
is the canonical, always-up-to-date copy. If you're not sure whether your
|
|
local checkout is current, that's the place to check against.
|
|
|
|
You don't have to `git clone` it to get a working copy, either — if you'd
|
|
rather not use git at all, download it as a ZIP from that page and unpack
|
|
it locally; you'll have the exact same files and can point your agent at
|
|
the unpacked folder right away. The one thing you'll be missing is a
|
|
configured `origin`, so "sync changes" and "upgrade the wiki" won't have
|
|
anything to push to or compare against yet — run `git init` in the
|
|
unpacked folder and add the URL above as `origin` (`git remote add origin
|
|
https://git.wierzbowa.cloud/michal/ckb`) whenever you're ready for those.
|
|
|
|
From then on, "sync changes" reconciles against that remote. This is how
|
|
multiple people share one wiki: everyone ingests/edits locally, and "sync
|
|
changes" is how each person's changes reach everyone else — and how theirs
|
|
reach you. Implemented by the `ckb-sync-changes` skill —
|
|
`.agents/skills/ckb-sync-changes/SKILL.md`.
|
|
|
|
The agent also nudges you about this automatically: at the start and end
|
|
of a working session it does a quick, read-only check for anything
|
|
uncommitted or unpushed, and tells you if "sync changes" is worth running
|
|
— it never pushes on its own without you asking.
|
|
|
|
### Building a shared cascade (KB-level sync)
|
|
|
|
If instead of *one shared wiki* you want *your own wiki that builds on
|
|
someone else's* — e.g. your team's KB overlaying the company-wide KB — that
|
|
isn't git sync at all; that's the `linked/`/`libs/` mounting described in
|
|
[§1](#building-on-top-of-someone-elses-wiki). Each person/team keeps their
|
|
own local `wiki/` (which always wins), and upstream KBs update on their own
|
|
schedule, independently.
|
|
|
|
---
|
|
|
|
## 5. Upgrading the template
|
|
|
|
This is a different kind of "keeping current" from anything in
|
|
[§4](#4-syncing--with-yourself-and-with-other-people): that section is
|
|
about *your own KB's own remote* — sharing your content with your
|
|
collaborators. This section is about catching your KB's *tooling* up with
|
|
improvements made to the canonical Cascade KB template itself, wherever
|
|
your KB originally came from (`ckb-init`, a clone, a fork, or a KB that's
|
|
been around long enough to predate some of these conventions).
|
|
|
|
Say:
|
|
|
|
> "Upgrade the wiki." / "Check for a newer template version."
|
|
|
|
### Which channel you're pulling from
|
|
|
|
The template repo keeps three branches, and by default you get the stable
|
|
one:
|
|
|
|
| Branch | What it is | Who should be on it |
|
|
|---|---|---|
|
|
| `main` | **Stable** — the released template | You, unless you have a reason not to be |
|
|
| `test` | **Release candidate** — validated before it reaches `main` | You're helping validate a release, or you need a fix that's landed but not shipped |
|
|
| `experimental` | **Development** — active work, may be broken or reverted | You're developing the template itself |
|
|
|
|
To use a different one, just say which:
|
|
|
|
> "Upgrade from the test branch." / "Check experimental for updates." /
|
|
> "Switch this KB back to the stable channel."
|
|
|
|
Whichever you pick sticks — it's recorded in `ckb.yaml`, so the next upgrade
|
|
stays on the same channel rather than quietly pulling you back to `main`. The
|
|
same goes at creation time: *"initialize from the experimental branch"*.
|
|
|
|
One thing to watch. If you're tracking `test` or `experimental`, your KB can
|
|
sit on a version `main` hasn't released yet. Checking against `main` then
|
|
finds nothing newer — the agent will tell you you're **ahead**, not that
|
|
you're up to date, because those are different situations. Going back to
|
|
`main` from there is a *downgrade*: it can remove skills and roll the schema
|
|
back below what your pages are written against. You'll be asked to confirm
|
|
explicitly, and it's refused outright if your content would stop conforming
|
|
to its own declared schema.
|
|
|
|
### What gets checked
|
|
|
|
Two entirely separate things get checked, and either, both, or neither
|
|
might turn something up:
|
|
|
|
- **The template/tooling layer** — `AGENTS.md`/`CLAUDE.md`, every skill
|
|
under `.agents/skills/`, `LICENSE`, `VERSION`, and the `README`/`MANUAL`
|
|
docs. Compared against the canonical repo's own `VERSION` file.
|
|
- **Your wiki content's own schema version** — the `kb_schema_version`
|
|
field in `wiki/index.md`, compared against what the template currently
|
|
expects. A KB can be fully current on tooling but still carry `wiki/`
|
|
content built years ago under an older (or entirely missing)
|
|
`kb_schema_version` — or the reverse.
|
|
|
|
**If nothing's behind on either front**, you'll just get "already up to
|
|
date — template vX, wiki schema vY," and nothing changes.
|
|
|
|
**If the template layer is behind**, you'll see a breakdown of what's new
|
|
(nothing local to lose) versus what's *changed* (a template file whose
|
|
local copy differs — which could be a genuine template improvement, or
|
|
could be a customization you made on purpose, e.g. to `AGENTS.md`). You
|
|
get asked, file by file or all at once, to take the template version, keep
|
|
yours, or see the full diff first — nothing gets silently overwritten.
|
|
|
|
**If your wiki content's schema is behind** (including the common case of
|
|
an older KB with no `kb_schema_version` at all — an "unversioned" wiki),
|
|
you'll get a distinct, explicit question:
|
|
|
|
> **Agent:** "Your `wiki/` content was built without a `kb_schema_version`
|
|
> (or an older one). Would you like me to also upgrade all wiki-related
|
|
> folders and data to the new standard?"
|
|
|
|
If you say yes, the agent:
|
|
- adds any missing scaffold pieces (e.g. a `wiki/graph/index.md` that
|
|
never existed if your KB predates the graph feature),
|
|
- backfills missing frontmatter on existing pages — `tldr`, `confidence`,
|
|
`quality`, `retention`, and so on — **without rewriting anything you've
|
|
actually written**; only structure and metadata get added, never the
|
|
substance of a page,
|
|
- confirms with you before assigning a `type` to any page where it isn't
|
|
obvious,
|
|
- logs every touched page in `wiki/log.md` as a migration entry so it's
|
|
clear the change was structural, not new knowledge,
|
|
- and bumps `kb_schema_version` once done.
|
|
|
|
If you say no, nothing under `wiki/` is touched at all — not even
|
|
`kb_schema_version` — so the next time you run this, it's still correctly
|
|
flagged as behind rather than silently considered handled. These two
|
|
decisions (template layer, wiki content) are independent: you can accept
|
|
one and decline the other.
|
|
|
|
Like Ingest and Lint, this finishes by reminding you to review the result
|
|
and run "sync changes" against *your own* `origin` — the template repo it
|
|
just checked against is a separate remote for any KB other than the
|
|
template project's own working copy. Implemented by the `ckb-upgrade`
|
|
skill — `.agents/skills/ckb-upgrade/SKILL.md`.
|
|
|
|
---
|
|
|
|
## 6. Use cases
|
|
|
|
### Ask questions
|
|
|
|
Just ask, in plain language:
|
|
|
|
> "What do we know about the Q3 migration risk?"
|
|
|
|
The agent reads `wiki/index.md` first to find relevant pages. If a matching
|
|
project scope exists under `wiki/projects/`, it searches that scope first.
|
|
Then it checks one-line `tldr` fields, runs exact local search for literal
|
|
tokens when needed, expands context around matching sections, walks the
|
|
knowledge graph for connected facts, and falls back to `linked/`/`libs/` if
|
|
the local wiki has nothing. You get an answer grounded in what's actually
|
|
written down, not a guess.
|
|
|
|
Two things about that worth knowing as a user:
|
|
|
|
- **It searches `raw/inbox/` too.** Something you dropped in this morning
|
|
and haven't ingested yet can still answer your question. The agent will
|
|
tell you when an answer came from un-ingested material, which doubles as
|
|
a nudge that "Ingest" is overdue.
|
|
- **Answers carry their own caveats.** If the page behind an answer is past
|
|
its freshness window, scored low on confidence, or was read from a cached
|
|
connector index instead of a live check, the answer says so next to the
|
|
claim. If two pages disagree and neither has been marked superseded yet,
|
|
you'll hear about that too. The point is that you never have to go read
|
|
the frontmatter yourself to know how much to trust what you just got.
|
|
|
|
### Ask who knows something
|
|
|
|
> "Who knows about the checkpoint restore path?" / "Who owns the billing
|
|
> service?"
|
|
|
|
These are answered from the knowledge graph directly rather than by
|
|
keyword-searching for names. Ingest records an expertise or ownership edge
|
|
when the source material actually shows someone answering questions on a
|
|
topic or holding declared responsibility for it — not from having attended
|
|
a meeting or from a job title. If nobody has a recorded edge yet, the agent
|
|
falls back to who the archived sources show answering that kind of question
|
|
and tells you it's inferring rather than reporting.
|
|
|
|
When there is still no answer, the agent should tell you what is missing
|
|
and either add/propose a short entry in `wiki/query-gaps.md` or suggest the
|
|
smallest source to drop into `raw/inbox/`.
|
|
|
|
### Learn from the wiki
|
|
|
|
**Quick test of what you know** — say:
|
|
|
|
> "Quiz me on the onboarding process."
|
|
|
|
You'll be asked how many questions and what format (open / multiple
|
|
choice), then run through them one at a time with immediate feedback and a
|
|
running score. Nothing is saved afterward — it's a one-off check.
|
|
`.agents/skills/ckb-quiz/SKILL.md`.
|
|
|
|
**A proper course, spread over time** — say:
|
|
|
|
> "Teach me the wiki." / "Teach me about the supplier onboarding process."
|
|
|
|
The first call plans a curriculum: it asks whether you want one session or
|
|
a series, how long each session should be and how often, and whether you'd
|
|
like a calendar `.ics` file with reminders. It then chunks the material into
|
|
session-sized portions (erring toward one more short session rather than
|
|
cramming) and shows you the plan before saving anything. Later, saying
|
|
"next lesson" (or similar) picks up where you left off, teaching using a
|
|
different technique each time — Socratic questions, analogies, worked
|
|
examples, teach-back, mnemonics — and briefly checking what stuck before
|
|
moving on, re-teaching anything shaky. Plans and progress live under
|
|
`outputs/teaching/<topic>/`. `.agents/skills/ckb-teach-me/SKILL.md`.
|
|
|
|
**A guided reading order without a full course** — say:
|
|
|
|
> "Onboard me on the payments integration." / "Where do I start with X?"
|
|
|
|
You get a short overview plus an ordered reading list — foundations first,
|
|
then the topic, then what builds on it — built by walking the knowledge
|
|
graph outward. Read-only; nothing is saved. `.agents/skills/ckb-onboard-me/SKILL.md`.
|
|
|
|
### Generate documents / share knowledge outside the wiki
|
|
|
|
**A quick top-level snapshot** — say:
|
|
|
|
> "Give me a project summary." / "Where do things stand?"
|
|
|
|
Regenerates `PROJECT-OVERVIEW.md` at the repo root: a one-to-two-page
|
|
overview, current state, open actions with status, risks, and assumptions
|
|
— entirely synthesised from the current wiki. It's fully overwritten each
|
|
time, so it always reflects what the wiki says *right now*.
|
|
`.agents/skills/ckb-project-summary/SKILL.md`.
|
|
|
|
**A machine-readable export for other tools** — say:
|
|
|
|
> "Export the wiki as OKF."
|
|
|
|
Produces an [Open Knowledge Format](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
|
|
bundle at `outputs/okf/`, consumable by generic OKF tooling (e.g. a graph
|
|
visualiser) without needing to understand this wiki's own richer schema.
|
|
`.agents/skills/ckb-export-okf/SKILL.md`.
|
|
|
|
**A human-readable documentation website** — say:
|
|
|
|
> "Export the wiki to Starlight." / "Build a docs site from the wiki."
|
|
|
|
Produces an Astro + Starlight-ready site at `outputs/starlight/` — real
|
|
pages, real navigation, something you could host and hand to someone who's
|
|
never seen the wiki. `.agents/skills/ckb-export-starlight/SKILL.md`.
|
|
|
|
**A Word doc, slide deck, or PDF from what's in the wiki** — no dedicated
|
|
skill for this, but it's a normal ask:
|
|
|
|
> "Turn the wiki page on our pricing model into a one-page Word doc I can
|
|
> send to legal."
|
|
|
|
The agent reads the relevant wiki page(s) and uses its general document
|
|
skills (`docx`, `pptx`, `pdf`) to produce the file — the wiki is the source
|
|
of truth, the document is a one-off derived artifact.
|
|
|
|
### Add information
|
|
|
|
Covered in full in [§2](#2-adding-knowledge) — the short version: drop it
|
|
in `raw/inbox/` and say "Ingest," or just tell the agent in chat if it's
|
|
small enough to state directly.
|
|
|
|
### Index an external source
|
|
|
|
Say:
|
|
|
|
> "Index external sources." (or "index libs," "refresh the external
|
|
> index")
|
|
|
|
This walks every `libs/<name>/` that has a `source.yaml` (see
|
|
[§1](#building-on-top-of-someone-elses-wiki)) and builds a short index of
|
|
what it finds — one entry per document, plus an overview page — entirely
|
|
inside that same `libs/<name>/` folder. Nothing under `wiki/` is touched.
|
|
|
|
Example:
|
|
|
|
> *You create `libs/finance-reports/source.yaml`:*
|
|
> ```yaml
|
|
> connector: sharepoint
|
|
> location: "https://contoso.sharepoint.com/sites/Finance/Shared Documents/Reports"
|
|
> description: "Finance team's shared reports folder"
|
|
> refresh_interval_days: 7
|
|
> ```
|
|
> *then say "Index external sources."*
|
|
>
|
|
> The agent connects using whatever's available that session (a connected
|
|
> Microsoft 365 tool, in this case), lists the documents in that folder,
|
|
> reads enough of each to write a short summary, and creates
|
|
> `libs/finance-reports/index.md` (an overview of the source) plus one
|
|
> page per document under `libs/finance-reports/entities/`, cross-linked
|
|
> via `libs/finance-reports/graph/edges.json`. It logs everything in
|
|
> `libs/finance-reports/log.md` — a log that's entirely separate from
|
|
> `wiki/log.md`, since this index is scoped to that one connector rather
|
|
> than blended into your main wiki. It finishes by reminding you to review
|
|
> the result and say "sync changes" once you're happy with it.
|
|
|
|
If a connector needs authorizing (e.g. a SharePoint or Google Drive
|
|
connection that isn't set up yet), the agent tells you which one and where
|
|
to authorize it, then continues with any other configured sources rather
|
|
than stopping the whole run. Run "index external sources" again any time
|
|
the source has changed — it refreshes existing entries in place rather
|
|
than duplicating them, and never deletes a page for a document that's
|
|
disappeared from the source (it flags it instead, so a later "Lint" pass
|
|
archives it naturally). Implemented by the `ckb-index-external` skill —
|
|
`.agents/skills/ckb-index-external/SKILL.md`.
|
|
|
|
**Who's allowed to build it, and where it's shared.** By default, nobody
|
|
has write access to a connector source until they say so — this keeps a
|
|
team of, say, ten people from all redundantly scanning the same SharePoint
|
|
folder. Say:
|
|
|
|
> "Make me the admin for finance-reports."
|
|
|
|
This writes a personal `libs/finance-reports/source.local.yaml` with
|
|
`access: write` — never committed, never seen by your teammates. Anyone
|
|
without that file is read-only for that source: if they say "index
|
|
external sources," the agent won't touch the live connector on their
|
|
behalf at all — it just reports what's already indexed (or tells them
|
|
plainly that nothing has been indexed yet and who to ask).
|
|
|
|
If the finance team wants everyone reading the *same* index rather than
|
|
each maintaining their own local copy of it inside their own KB, the admin
|
|
adds an `index:` block to the shared `source.yaml`:
|
|
|
|
```yaml
|
|
index:
|
|
store: git
|
|
location: "https://github.com/finance-team/index-cache.git"
|
|
# ref: main — optional: pin a branch, tag, or subpath within that store
|
|
```
|
|
|
|
The very first time anyone runs "index external sources" after that block
|
|
is added, `https://github.com/finance-team/index-cache.git` is empty —
|
|
that's expected, not an error. Every run checks it first: read-only users
|
|
just see "nothing published yet, ask the admin"; the admin's run is what
|
|
actually creates it there, since a write-access run always rebuilds from
|
|
the live connector and pushes the result to that location, whether or not
|
|
anything was there before. From then on, whenever *anyone* says "index
|
|
external sources," the agent first fetches whatever's already published
|
|
there — read-only users stop right there; the admin also rebuilds from the
|
|
live connector and pushes the refreshed index back to that same location,
|
|
so the next person's fetch picks it up. Leave the `index:` block out
|
|
entirely (the simplest setup, and the right default for a single small
|
|
team) and the index just lives
|
|
directly inside `libs/finance-reports/` in this KB's own repo, shared the
|
|
normal way via "sync changes" — exactly like the plain example above.
|
|
|
|
---
|
|
|
|
## 7. What's agent-generated vs. what you can edit
|
|
|
|
The short version: **the local `wiki/` always wins** in the cascade, which
|
|
means it's *your* wiki — you're never locked out of editing it directly.
|
|
"Agent-managed" below means the agent treats itself as responsible for
|
|
keeping that content *structurally* correct (frontmatter, index, log,
|
|
graph) — not that you're forbidden from touching it. If you hand-edit a
|
|
wiki page, it's good practice to run "Lint" afterward so the index/log/
|
|
graph stay in sync with what you changed.
|
|
|
|
There is one exception that runs the other way. On any page the agent
|
|
*regenerates* — a connector index, a code map — everything you write is
|
|
normally lost on the next rebuild. So every such page ends with a `## Notes`
|
|
section that no skill will ever touch:
|
|
|
|
```markdown
|
|
## Notes
|
|
|
|
<!-- Yours. Never rewritten by any skill. -->
|
|
```
|
|
|
|
Write whatever you want there — that this document is obsolete, that the
|
|
person named in it has left, who to actually ask. It is carried across
|
|
rebuilds byte-for-byte. Anything you write *above* that heading on a
|
|
generated page will be overwritten.
|
|
|
|
| Location | Who normally writes it | Notes |
|
|
|---|---|---|
|
|
| `raw/inbox/`, loose files in `raw/` | **You, only** | The agent only reads, archives, and moves things here — it never originates content in `raw/` itself. |
|
|
| `raw/archive/<date>/` | Agent | Auto-filed copy of what you dropped in `raw/inbox/`, organised by ingestion date. Don't hand-file here — let Ingest do it, so the date and pairing with the log entry stay accurate. |
|
|
| `linked/<name>/` | **You** (you create the symlink) | Points at another KB's real files, which live and get edited *in that other repo* — never here. The agent must never write inside `linked/`. |
|
|
| `libs/<name>/` (git-copy, no `source.yaml`) | **You** (you `git clone`) | A frozen copy of an external KB. Update it by re-pulling that repo yourself, not by hand-editing files here. The agent must never write inside it. |
|
|
| `libs/<name>/source.yaml` (connector) | **You, only** | Declares the connector, location, optionally how often it should be refreshed (`refresh_interval_days:`), and optionally where a shared/pre-built index lives (`index:`). The agent reads it but never writes it — same as anything else upstream. |
|
|
| `libs/<name>/source.local.yaml` (connector) | **You** (or the agent, only when you explicitly ask to become/stop being that source's admin) | Per-person, per-machine `access: write`/`read` setting — never committed, never seen by anyone else. Absent = read-only, the default. |
|
|
| `libs/<name>/{index.md,entities/,graph/,log.md}` (connector) | Agent-generated, **you can freely edit** | The agent's own index of that one connector's source, built/refreshed by "Index external sources" — but only if you have `access: write` locally; read-only users just get a fetched copy. Structurally the same deal as the main `wiki/` row below — feel free to correct an entry by hand, then run "Lint" (it now also checks connector-backed indexes, respecting the same read/write split). Scoped entirely to that connector; never blended into `wiki/`. **Only `## Notes` survives a rebuild** — put anything you want to keep there. |
|
|
| `wiki/decisions/` | Agent-generated, **edit with care** | Same as the rest of `wiki/` mechanically, but these are append-only by convention: correct a typo or a misattributed name freely, and don't rewrite a decision's context or rationale to match a later view — record a superseding decision instead, so the history survives. |
|
|
| `wiki/` (pages, `index.md`, `overview.md`, `log.md`, `error-book.md`, `entities/`, `graph/`) | Agent-generated, **you can freely edit** | This is the one place the agent both writes and expects you might too. Feel free to correct a page by hand — just keep the frontmatter fields intact (or update `last_updated`), and run Lint afterward if you touched something the index/graph/log reference. |
|
|
| `outputs/okf/`, `outputs/starlight/` | Agent, **fully regenerated** | Don't hand-edit — these are gitignored build artifacts, silently overwritten the next time you export. If something's wrong, fix the wiki page it came from and re-export. |
|
|
| `outputs/teaching/<topic>/` | Agent, semi-persistent state | `plan.md`/`progress.md` the teaching skill reads and writes across sessions. You can look at them any time; hand-editing is possible but may confuse "what's next" tracking — safer to tell the agent what you want changed and let it update the files. |
|
|
| `PROJECT-OVERVIEW.md` (repo root) | Agent, **fully regenerated** | Overwritten in full each time you ask for a project summary. Don't hand-edit it — edit the wiki pages it's synthesised from instead, then regenerate. |
|
|
| `workload/YYYY-MM-DD_summary.md` | Agent (appended each session) | A running journal of what happened each day. You can read, edit, or trim it freely — it's a log for continuity, not a machine-critical file. |
|
|
| `AGENTS.md` / `CLAUDE.md` | **You** (rarely) | This is the system prompt that defines how the agent behaves in this repo. Edit it if you want to change a global rule — e.g. the frontmatter schema, the logging format, or the directory contract. Changes apply from the next session onward. |
|
|
| `.agents/skills/*/SKILL.md` | **You** (advanced/optional) | Each file defines one on-demand capability. You can create new ones or edit existing ones by following the pattern of the ones already here — this isn't required for normal use, but nothing stops you. |
|
|
| `LICENSE`, `VERSION`, `README*`, `MANUAL*` | Agent, **you can edit** | Part of the same template layer as `AGENTS.md` — kept in sync by `ckb-upgrade` when you accept a template update. `ckb-upgrade` will always ask before touching `LICENSE`'s copyright line or any of these if your local copy differs from the template's, since customization here (e.g. your own project name or license holder) is expected, not a mistake. |
|
|
|
|
---
|
|
|
|
## 8. Quick reference
|
|
|
|
| Say... | What happens | Skill |
|
|
|---|---|---|
|
|
| "Set up a new wiki like this one in \<folder\>" | Bootstraps a fresh, empty KB with this schema | `ckb-init` |
|
|
| "Pull the ckb repo into \<folder\> and set up the wiki" | Clones the template repo to a scratch dir, then bootstraps an empty KB from it | `ckb-init` |
|
|
| "Ingest" / "Sync the wiki" / "Update the wiki" | Processes `raw/inbox/` into structured `wiki/` pages | `ckb-ingest` |
|
|
| "Record a decision: ..." / "we decided ..." | Writes a numbered decision record under `wiki/decisions/` | `ckb-decide` |
|
|
| "What did we decide about X" / "who decided X" / "what's still open" | Answers from the decision records, with who/when/status attached | `ckb-decide` |
|
|
| "Lint" | Health-checks the wiki, auto-fixes what it safely can | `ckb-lint` |
|
|
| "Reset the wiki" / "Make this a clean template" | **Destructive.** Deletes accumulated knowledge and restores the empty scaffold, after an inventory and a typed confirmation | `ckb-reset` |
|
|
| "Sync changes" / "Sync with git" | Commits, pulls, resolves conflicts, pushes to `origin` | `ckb-sync-changes` |
|
|
| "Quiz me on X" | One-off scored knowledge test | `ckb-quiz` |
|
|
| "Teach me the wiki" / "Teach me about X" | Plans and runs a spaced-out course with progress tracking | `ckb-teach-me` |
|
|
| "Onboard me on X" / "Where do I start with X" | Short guided reading order through the graph | `ckb-onboard-me` |
|
|
| "Give me a project summary" | Regenerates `PROJECT-OVERVIEW.md` | `ckb-project-summary` |
|
|
| "Export the wiki as OKF" | Machine-readable export at `outputs/okf/` | `ckb-export-okf` |
|
|
| "Export the wiki to Starlight" | Human-readable docs site at `outputs/starlight/` | `ckb-export-starlight` |
|
|
| "Upgrade the wiki" / "Check for a newer template version" | Checks template + wiki schema versions against the canonical repo, upgrades what you accept | `ckb-upgrade` |
|
|
| "Index external sources" / "Index libs" | Builds/refreshes a self-contained index for each connector-backed `libs/<name>/` | `ckb-index-external` |
|
|
| Just ask a question | Answers from the wiki, using the index/TLDR/graph cascade, with caveats when a source is stale or contested | `ckb-retrieve` |
|
|
| "Who knows about X" / "Who owns X" | Answers from expertise/ownership edges in the graph | `ckb-retrieve` |
|