# 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 \" — 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//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//` 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 ``" to opt yourself in (this writes a local, personal `libs//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//` 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//` 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-`) 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//`. `.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//` 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//` 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 ``` 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//` | 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//` | **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//` (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//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//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//{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//` | 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 \" | Bootstraps a fresh, empty KB with this schema | `ckb-init` | | "Pull the ckb repo into \ 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//` | `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` |