Compare commits

...

2 commits

Author SHA1 Message Date
c998489c9a Reset wiki to clean template scaffold
Empty the KB back to the shape ckb-init creates: remove decision records
D-0001 and D-0002, the single graph edge, all five workload summaries and
the generated outputs/okf/ tree, then restore the empty scaffold with
kb_schema_version held at 1.4.

The decisions status-vocabulary table is preserved verbatim, since
ckb-decide and ckb-lint both validate against it. Lint reports 0 findings.

Restore point for the pre-reset content: tag pre-reset-2026-09-20 (0c06cb6).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-20 17:59:14 +02:00
0c06cb64ab Restore point before wiki reset
Commit all in-flight work — ckb-module and ckb-reset skills, the
.agents/modules/ scaffold, OPENSPEC docs, decision records D-0001 and
D-0002, graph edges and workload summaries — so the reset that follows
is fully recoverable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-20 17:56:41 +02:00
34 changed files with 1534 additions and 195 deletions

View file

@ -0,0 +1,68 @@
# `software` module
Opt-in. Install with "install the software module"; remove with "uninstall the
software module". Nothing in here is active until installed — the skills below
live in this folder, not in `.agents/skills/`, precisely so their descriptions
stay out of context for knowledge bases that don't document software.
## What it assumes
You are building software, and this KB holds the knowledge *about* it. The code
itself lives in `src/<repo>/` as plain clones — **gitignored**, each with its own
remote and its own history. One KB can hold several.
The code is not part of the KB's history and may be absent entirely from a fresh
clone. That is deliberate, and it is why the module writes a `type: repository`
entity page for every repo: remote URL, default branch, language, build command,
path, owner. **That page is the durable artifact; the clone is a convenience.**
## What it adds
| Skill | Does |
|---|---|
| `ckb-code-map` | Reads a `src/<repo>` clone and writes it into `wiki/entities/` as a repository page plus component pages, stamped with the commit it was generated from so staleness is detectable. |
| `ckb-spec` | Owns KB-root specs, delegates per-repo specs to OpenSpec, and bridges both into `wiki/` — archived changes become decision records, current specs become `type: spec` pages. |
Plus: `src/` and `openspec/` scaffold, a routing block in `AGENTS.md`, `.gitignore`
rules for `src/*`, and the `repository`/`component`/`spec` types.
## Two spec levels
Specs live at **both** levels, and the split is the point:
- **`openspec/` at the KB root** — what and why, across repos. Cross-cutting
contracts that no single repo owns. Served by `ckb-spec` directly, because a
root `openspec/` is not a normal OpenSpec install: there is no code beneath it.
- **`src/<repo>/openspec/`** — how this repo implements it. OpenSpec's native
case: travels with the code, rides along in the repo's own PRs. Served by
OpenSpec's own instructions; `ckb-spec` defers to them and says so plainly when
the CLI isn't installed rather than improvising a replacement.
The levels are linked by `implements:` / `implemented_by:` frontmatter, which
becomes graph edges. This exists so that two spec levels produce a **lint signal**
when they disagree, instead of two silently divergent truths. A KB-root spec with
no implementer, or a repo-level spec whose parent was archived, is a finding.
## What it does not do
- **`src/` is not a cascade layer.** It is primary evidence, like `raw/archive/`.
`ckb-retrieve` may open and cite it to verify a claim; it never answers "what is
entity X", and `ckb-ingest` does not treat code as inbox material. Without this
rule every ingest would turn your codebase into wiki pages.
- **It does not commit or push `src/` repos.** They are separate repos with
separate remotes. `ckb-sync-changes` never `git add`s under `src/`.
## Setting up OpenSpec
See [OPENSPEC.md](../../../OPENSPEC.md) ([Polski](../../../OPENSPEC.pl.md)) for
install steps, the daily propose → apply → archive loop, and the reason
`openspec init` must never run at the KB root.
## Design record
- [D-0001](../../../wiki/decisions/0001-opt-in-file-based-kb-modules.md) — why modules are files in the repo.
- [D-0002](../../../wiki/decisions/0002-software-module-design.md) — why gitignored clones, both spec levels, hybrid vendoring.
---
*Licensed under the Apache License, Version 2.0 — see [LICENSE](../../../LICENSE).*

View file

@ -0,0 +1,23 @@
## MODULE: software
This KB documents software being built here. Source repos live in `src/<repo>/`
as **gitignored plain clones**, each with its own remote and history.
- `src/` is **evidence, not a cascade layer.** `ckb-retrieve` may open and cite
code to verify a claim; it never answers "what is entity X", and `ckb-ingest`
never treats code as inbox material.
- **Never `git add` under `src/`.** Those are separate repos. `ckb-sync-changes`
reports each one's dirty/ahead state separately and commits none of them.
- Every repo has a `type: repository` page in `wiki/entities/` — the durable
record, since the clone may be absent from a fresh checkout.
- Specs live at two levels: `openspec/` at the KB root (cross-cutting, owned by
`ckb-spec`) and `src/<repo>/openspec/` (per-repo, owned by OpenSpec itself).
They link via `implements:` / `implemented_by:`.
| User intent | Skill |
|---|---|
| Map or refresh a `src/` repo into wiki entities | `ckb-code-map` |
| Write, sync, or bridge specs (either level) | `ckb-spec` |
Module-contributed page types: `repository`, `component`, `spec`. Additional
optional frontmatter: `repo`, `commit`, `spec_id`, `implements`, `implemented_by`.

View file

@ -0,0 +1,7 @@
# Source repos are independent git clones with their own remotes — never part of
# this KB's history. Knowledge about them lives in wiki/entities/ instead.
src/*
!src/.gitadd
!src/README.md
# KB-root cross-cutting specs ARE tracked — they are knowledge, not code.
!openspec/

View file

@ -0,0 +1,59 @@
# Cascade KB module manifest — read by `ckb-module` on install/uninstall.
# See wiki/decisions/0001-opt-in-file-based-kb-modules.md for why modules are
# files in the repo rather than native agent plugins.
name: software
title: Software / source-code KB
version: 1.0.0
requires_kb_schema: "1.5"
summary: >
Turns this knowledge base into one that documents software you are building:
source repos live as gitignored plain clones in src/, and OpenSpec drives
iterative development at both KB-root and per-repo level.
# Skills copied into .agents/skills/ on install, removed on uninstall.
# .claude/skills is a symlink to .agents/skills, so there is no second copy.
skills:
- ckb-code-map
- ckb-spec
# Directories created on install. Never removed on uninstall — they may hold
# the user's clones and specs.
scaffold:
- path: src/
from: scaffold/src-README.md
as: src/README.md
note: Drop zone for source repos, one clone per subdirectory.
- path: openspec/
from: scaffold/openspec/
note: KB-root, cross-cutting specs spanning multiple src/ repos.
# Appended to AGENTS.md between the module markers, removed on uninstall.
agents_fragment: fragments/agents-routing.md
# Appended to .gitignore between the module markers, removed on uninstall.
gitignore_fragment: fragments/gitignore.snippet
# Frontmatter this module contributes to the page schema. Additive: the base
# schema tolerates these whether or not the module is installed.
schema_additions:
types:
- repository # one src/ repo: remote, branch, language, build, owner
- component # a module/service/package inside a repo
- spec # a capability spec, KB-root or repo-level
fields:
- repo # /wiki/entities/<repo>.md this page belongs to
- commit # commit hash the page was generated from
- spec_id # OpenSpec capability id
- implements # repo-level spec -> the KB-root spec it implements
- implemented_by # KB-root spec -> repo-level specs implementing it
# External dependency. The module reports its absence rather than substituting
# its own workflow — see wiki/decisions/0002-software-module-design.md.
depends_on:
- name: openspec
scope: src-repo-level-only
check: "command -v openspec"
optional: true
note: >
Required only for per-repo specs. The KB-root spec layer is served by
ckb-spec itself and works without the CLI.

View file

@ -0,0 +1,17 @@
# KB-root specs
Cross-cutting capability specs — the ones that span several `src/` repos and that
no single repo owns. Managed by the `ckb-spec` skill.
* `specs/<capability>.md` — current truth. What the system, as a whole, does.
* `changes/<change-id>/` — a proposed delta, not yet true.
* `changes/archive/` — applied or rejected changes. Immutable; often worth a
matching decision record under `wiki/decisions/`.
Specs for how *one* repo implements a capability belong in that repo, at
`src/<repo>/openspec/`, where OpenSpec's own tooling manages them and they travel
with the code. Link the two with `implements:` / `implemented_by:` — both sides,
always.
Unlike `src/`, this directory **is** tracked in the KB's git history: it is
knowledge, not code.

View file

@ -0,0 +1,15 @@
# `src/`
Source repositories for the software this knowledge base documents. One clone
per subdirectory, each an independent git repo with its own remote.
**Everything here except this file is gitignored.** Clones are never committed to
the KB. A fresh clone of this KB will have an empty `src/` — that is expected.
What survives is the knowledge: every repo has a `type: repository` page under
`wiki/entities/` recording its remote, default branch, language, build command
and owner, so you can re-clone from the wiki alone. Run `ckb-code-map` after
adding a repo here to create or refresh that page.
Per-repo specs live in `src/<repo>/openspec/` and travel with that repo, not with
this KB. Cross-cutting specs live in the KB root's `openspec/`.

View file

@ -0,0 +1,174 @@
---
name: ckb-code-map
description: Read a source repository under src/ and write what it IS into wiki/entities/ — a `type: repository` page (remote, default branch, language, build and test commands, owner) plus `type: component` pages for its significant modules/services, cross-linked into the graph and stamped with the commit they were generated from so staleness is detectable. Use when the user says "map the code", "map src/<repo>", "refresh the code map", "index the repo", "add this repo to the wiki", or after cloning a new repo into src/. Distinct from `ckb-ingest` (which processes raw/inbox/ material and never reads code) and from reading code to answer a question (that is `ckb-retrieve` using src/ as evidence). Part of the opt-in `software` module.
---
# Code map skill
## Purpose
`src/` clones are gitignored: they are not in this KB's history and may be
absent entirely from a fresh checkout. So the *knowledge* about a repository
has to live in `wiki/`, or it doesn't survive.
This skill produces that knowledge. It is deliberately **not** a code-to-prose
dump — a wiki page restating what any reader could get by opening the file is
pure liability, because it goes stale silently. What this skill records is what
you cannot get by reading one file: how to obtain the repo, how to build and
test it, what its pieces are, who owns it, and how those pieces connect to
entities the wiki already knows about.
## Trigger phrases
- "map the code" / "map `src/<repo>`" / "index the repo"
- "refresh the code map" / "the code map is stale"
- "add this repo to the wiki" / "I cloned a new repo into src"
## Scope rule
Reads `src/`. Writes only `wiki/`. Never writes, commits, or pushes anything
inside `src/` — those are independent repos with their own remotes.
## How to run this skill
### Step 0 — Confirm the module is installed and the repo exists
Check `ckb.yaml` lists the `software` module. If `src/` is empty or the named
repo isn't there, say so and stop — don't guess which repo was meant when
several are present, ask.
### Step 1 — Gather the facts that don't come from reading code
From inside the repo, cheaply:
```bash
git -C src/<repo> remote -v
git -C src/<repo> rev-parse --abbrev-ref HEAD
git -C src/<repo> rev-parse --short HEAD
git -C src/<repo> log -1 --format=%cI
git -C src/<repo> status --short
```
Then read the manifest and entry docs — `README`, `package.json`, `pyproject.toml`,
`go.mod`, `Cargo.toml`, `Makefile`, CI config. Build and test commands come from
here, not from inference.
**Do not run the build, the tests, or any script from the repo** to find out what
it does. Mapping is a read-only activity.
### Step 2 — Identify components, and be ruthless about what counts
A component is a part of the system a person would name in conversation: a
service, a CLI, a published package, a long-lived subsystem. A directory is not
automatically a component. **Ten honest component pages beat a hundred mirroring
the folder tree** — the second kind makes the wiki look thorough while making it
useless to search.
If you cannot write a one-sentence `tldr` for a candidate that says what it *does*
(not where it lives), it isn't a component. Leave it out.
### Step 3 — Consult the cascade before creating anything
Per the cascade rule, check whether pages already exist for this repo or its
components — in `wiki/` first, then `linked/`, then `libs/`. Refreshing an
existing page is the normal case, not the exception: update it, keep its history,
and don't renumber or re-slug it just because a directory was renamed.
### Step 4 — Write the repository page
`wiki/entities/<repo-slug>.md`:
```markdown
---
type: repository
tldr: One sentence on what this software does — not "the repo for X".
resource: https://git.example.com/me/thing
repo: thing
commit: a1b2c3d
confidence: 0.9
quality: 0.8
last_updated: YYYY-MM-DD
freshness_window_days: 90
retention: high
---
# thing
**Remote:** `git@git.example.com:me/thing.git` · **Default branch:** `main`
· **Local path:** `src/thing` · **Mapped at:** `a1b2c3d` (YYYY-MM-DD)
## What it is
Two or three sentences. What problem it solves and for whom.
## Getting it
git clone git@git.example.com:me/thing.git src/thing
## Build and test
<the actual commands, from the manifest not invented>
## Components
* [[thing-api]] / [thing-api](/wiki/entities/thing-api.md) — <tldr>
## Specs
KB-root specs this repo implements, and the repo-level specs that implement them.
Written by `ckb-spec`; leave the section here even when empty.
## Sources
`src/thing` at `a1b2c3d`, mapped YYYY-MM-DD. README, `pyproject.toml`, CI config.
```
The `commit` field and the **Mapped at** line are what make this page auditable —
they let a reader and `ckb-lint` tell how far the page has drifted from the code.
Never write them from memory; take them from Step 1.
### Step 5 — Write component pages
Same shape, `type: component`, with `repo: <repo-slug>` pointing home. Keep them
thin and link upward to the repository page and sideways to whatever the wiki
already knows — a component that talks to a system with an existing entity page
should link to it rather than re-describing it.
### Step 6 — Graph, indexes, log
- `wiki/graph/edges.json``part_of` (component → repository), `depends_on`
(repo/component → an external library or a system that has a page), `owns`
(person → repo, **only** on stated ownership, never inferred from commit counts).
- `wiki/entities/index.md` — add or refresh a row per page.
- `wiki/log.md` — one entry per run, per Rule B, naming the repo and commit.
### Step 7 — Report
State the repo and commit mapped, pages created vs. refreshed, components
deliberately skipped and why, anything you couldn't determine (no build command
in the manifest — say so rather than inventing one), and whether the working tree
was dirty at map time (a map taken from uncommitted work is fine, but should be
labelled as such). Close with the standard reminder: on disk, not committed.
## Edge cases
- **Dirty working tree** — map it, but record the commit *plus* a note that
uncommitted changes were present. Don't refuse, and don't silently pretend the
tree was clean.
- **Repo with no remote** (local-only) — record `resource:` as absent and say
plainly in **Getting it** that this repo exists only locally. That's a real
finding: a gitignored, remote-less repo is one disk failure from gone.
- **Monorepo** — one repository page, components per package. Don't create a
repository page per package.
- **Several repos, user said "map the code"** — ask which, or offer to do all;
don't pick one.
- **Repo that's mostly vendored/generated code** — map what's authored here. Note
the vendored portion once, on the repository page.
- **A component page already exists as `type: concept`** from an earlier ingest —
don't create a duplicate. Update the existing page and change its type, noting
the change in the log entry.
---
*Licensed under the Apache License, Version 2.0 — see [LICENSE](../../../../LICENSE)
at the repository root, or <http://www.apache.org/licenses/LICENSE-2.0>.*

View file

@ -0,0 +1,192 @@
---
name: ckb-spec
description: Own the KB-root `openspec/` layer (cross-cutting capability specs spanning several src/ repos), delegate per-repo specs to OpenSpec's own installed workflow inside src/<repo>/openspec/, and bridge both into wiki/ — archived change proposals become numbered decision records, current specs become `type: spec` entity pages, and the two levels link via implements/implemented_by. Use when the user says "write a spec", "propose a change", "what specs do we have", "archive this change", "sync the specs", "which spec covers X", or "wire OpenSpec into the wiki". Part of the opt-in `software` module. Distinct from `ckb-decide` (records decisions directly; this skill feeds it from archived specs) and `ckb-code-map` (records what the code IS; this skill records what it SHOULD DO).
---
# Spec skill
## Purpose
A code map says what the software *is*. A spec says what it is *supposed to do*
and a change proposal says what should become true next. This skill owns that
axis, across two levels that deliberately differ:
| Level | Holds | Owned by |
|---|---|---|
| `openspec/` at the KB root | Cross-cutting capabilities and contracts spanning several `src/` repos. The *what* and *why*. | **This skill.** A root `openspec/` has no code beneath it and no single repo governing it, so OpenSpec's own repo-shaped workflow doesn't serve it. |
| `src/<repo>/openspec/` | How one repo implements those capabilities. The *how*. | **OpenSpec itself.** This is its native case: specs travel with the code and ride along in the repo's own PRs. |
The split is the point, and so is the risk it creates: two places a statement can
live is two places it can diverge. The `implements` / `implemented_by` links
below exist so divergence becomes a **lint finding** rather than a silent second
source of truth. Maintaining those links is not optional bookkeeping — it is the
reason the two-level arrangement is safe.
## Trigger phrases
- "write a spec" / "add a capability" / "what specs do we have" / "which spec covers X"
- "propose a change" / "draft a change proposal" / "archive this change"
- "sync the specs" / "wire OpenSpec into the wiki" / "are the specs in sync"
## Scope rule
Writes `openspec/` at the KB root, and `wiki/`. Inside `src/<repo>/` it reads
freely and writes **only** through OpenSpec's own workflow, on the user's
explicit instruction. It never commits or pushes a `src/` repo.
## KB-root specs
### Layout
```
openspec/
├── README.md # what this layer is for
├── specs/
│ └── <capability>.md # one capability, current truth
└── changes/
├── <change-id>/ # proposed delta, not yet true
└── archive/ # applied changes, immutable
```
### A KB-root capability spec
```markdown
---
type: spec
spec_id: billing-invoicing
tldr: One sentence stating the capability, in the present tense, as a contract.
status: active
implemented_by: /src/billing/openspec/specs/invoicing.md, /src/portal/openspec/specs/invoice-view.md
affects: /wiki/entities/billing.md
confidence: 0.9
quality: 0.8
last_updated: YYYY-MM-DD
freshness_window_days: 180
retention: high
---
```
Body: **Purpose** (why this capability exists), **Requirements** (each one
testable — "the system SHALL ..." beats "the system should be fast"),
**Out of scope**, **Implementations** (which repos, dual-linked), **Sources**.
Write requirements a reader can disprove. A requirement nobody can fail is not a
requirement, and a spec full of them reads as thorough while constraining nothing.
### Writing one
1. Check `openspec/specs/` for an existing capability on the subject. Extend it
rather than creating a near-duplicate — two overlapping specs is the failure
this layer exists to prevent.
2. Check the cascade (`wiki/``linked/``libs/`) for what the KB already
knows about the subject, and link to it rather than restating it.
3. Write the spec, then a `type: spec` mirror page under `wiki/entities/` (or
link the spec file directly from the relevant entity page — prefer one home
plus links over two copies of the text).
4. Log it per Rule B and update `wiki/entities/index.md`.
## Per-repo specs
**Delegate.** If `src/<repo>/openspec/` exists, follow the instructions OpenSpec
installed there — do not substitute a workflow of your own, and do not "improve"
its file format to match this KB's conventions. That repo's specs are governed by
OpenSpec upstream; divergence there breaks its tooling and its PR flow.
### Never run `openspec init` at the KB root
`openspec init` writes tool-integration files into `.claude/skills/` and adds
marker blocks to `AGENTS.md` / `CLAUDE.md`. At the KB root both are load-bearing:
`.claude/skills` is a symlink to `.agents/skills` (so OpenSpec's files would join
this KB's skill set), and `CLAUDE.md` is a symlink to `AGENTS.md`, the KB's own
system prompt.
Run it **only** inside `src/<repo>/`, where the repo gets its own `.claude/` and
its own `AGENTS.md`. The KB-root `openspec/` is not an OpenSpec install and never
needs `init`. If the user asks for `init` at the root, explain this and offer the
KB-root spec layer instead — don't run it and don't clean up afterwards.
Install is `npm install -g @fission-ai/openspec@latest` (Node 20.19.0+), then
`openspec init` in the repo; `openspec update` after a CLI upgrade. See
[OPENSPEC.md](../../../../OPENSPEC.md) for the user-facing guide.
If OpenSpec is not installed (`command -v openspec` fails, or the repo has no
`openspec/`), **say so plainly and stop** rather than improvising:
> "This repo has no OpenSpec setup, and the `openspec` CLI isn't on PATH. Per-repo
> specs are OpenSpec's own workflow — install it and run `openspec init` in
> `src/<repo>`, and I'll take it from there. I can write this as a KB-root
> cross-cutting spec instead if it isn't repo-specific."
That offer is genuine, not a consolation: a requirement that spans repos belongs
at the root anyway.
## The bridge
Three directions, all owned here.
### 1. Archived change → decision record
An applied-and-archived OpenSpec change is a decision that was made and acted on.
When the user archives a change (either level), offer to record it via
`ckb-decide`: the change's *why* becomes **Context** and **Rationale**, the delta
becomes **Decision**, and rejected options in the proposal become
**Alternatives considered**.
Cite the change id and its path in the decision's `## Sources`. Do not
auto-record without asking — not every archived change is a decision worth a
permanent numbered record, and a decisions log padded with routine changes loses
the property that makes it worth reading.
Both artifacts are append-only, which makes them a natural pair: neither is ever
rewritten when the thinking changes later.
### 2. Spec → entity page
Current KB-root specs surface in `wiki/entities/` as `type: spec` pages so
`ckb-retrieve` can answer "what is this supposed to do" without opening the spec
tree. Keep these thin and pointer-style: `tldr`, `spec_id`, status, links. The
spec file stays the source of truth — a full copy in `wiki/` is a second thing
to keep in sync, and it will lose.
### 3. Level linking — the drift rule
- A KB-root spec lists every repo-level spec implementing it in `implemented_by`.
- A repo-level spec names its parent in `implements`.
- Both become graph edges (`implements`) in `wiki/graph/edges.json`.
Set **both sides**, every time. A one-sided link is a lint finding, exactly as a
one-sided decision supersession is.
### Sync check
On "sync the specs" / "are the specs in sync", report:
1. KB-root specs with empty `implemented_by` — *specified but nobody builds it.*
2. Repo-level specs with `implements` pointing at a missing or archived root spec
— *building against something no longer true.*
3. One-sided links, either direction.
4. Root specs whose `last_updated` is older than the mapped commit of every repo
implementing them — *possible drift; verify, don't auto-fix.*
Report all four. **Fix none of them automatically** — each is a statement about
intent, and only the user knows which side is right. `ckb-lint` runs the same
four checks as part of its sweep when this module is installed.
## Edge cases
- **`src/` is empty** — the KB-root layer still works. Cross-cutting specs can
precede any code; that's often the point.
- **A spec that's really a decision** ("we'll use Postgres") — that's `ckb-decide`.
A spec states a standing contract; a decision records a choice at a point in
time. If it doesn't constrain future behaviour, it isn't a spec.
- **A capability implemented by exactly one repo, forever** — it probably belongs
in that repo, not at the root. Say so; don't silently promote it.
- **OpenSpec's format changes upstream** — for per-repo specs, follow upstream.
This skill's formats govern the KB-root layer only.
- **A change proposal that was rejected** — it still archives, and it is still
worth a decision record with `status: rejected`. The reasoning is the value.
---
*Licensed under the Apache License, Version 2.0 — see [LICENSE](../../../../LICENSE)
at the repository root, or <http://www.apache.org/licenses/LICENSE-2.0>.*

View file

@ -323,6 +323,14 @@ from Step 4, plus anything explicitly added. Then create `.claude/skills`
in the target as a symlink to `../.agents/skills`, matching this repo's
convention - do this once, after copying the whole set, not per-skill.
Also copy `.agents/modules/` wholesale. Modules are inert until installed,
so a new KB carries the full catalogue at zero context cost, and the user
can enable one later with `ckb-module` instead of re-deriving it. Do **not**
install any module into the new KB, and do not create a `ckb.yaml`: an
absent manifest correctly means "nothing installed". If the user has said
the new KB is for software they are building, mention the `software` module
and offer to install it after Step 11 — offer, don't assume.
### Step 11 - Initialize the new KB's own git history (ask first)
The target is now a complete KB but has no history of its own - and if the

View file

@ -199,6 +199,28 @@ a gap to report or fix. The script follows the same rule: it reads that
file only to label each connector `access: read-only` / `access: write` in
its report.
### 11 — Installed module checks
If `ckb.yaml` lists installed modules, run whatever extra checks those
modules define, and skip this step entirely when the file is absent or
empty. Modules are optional by design: their absence is never a finding.
For the `software` module specifically:
- **Stale code maps** — a `type: repository` page whose `commit` is behind
the current `HEAD` of its `src/` clone. Report how far behind; suggest
`ckb-code-map`. A missing clone is **not** a finding — `src/` is
gitignored and expected to be empty on a fresh checkout.
- **Spec drift** — the four checks `ckb-spec` defines: root specs with
empty `implemented_by`, repo-level specs implementing a missing or
archived parent, one-sided `implements`/`implemented_by` links, and root
specs older than the mapped commit of every repo implementing them.
- **Remote-less repos** — a mapped repository page with no `resource:`,
meaning a gitignored clone that exists nowhere else.
All report-only. Never auto-fix any of these: each is a statement about
intent, and only the user knows which side is correct.
### Auto-fix vs. report
Auto-fix what can be done safely and mechanically: broken links, missing

View file

@ -0,0 +1,164 @@
---
name: ckb-module
description: Install, list, or uninstall an optional Cascade KB module from .agents/modules/<name>/ — copying its skills into .agents/skills/, creating its scaffold directories, appending its routing block to AGENTS.md and its rules to .gitignore, and recording it in the root ckb.yaml manifest. Use when the user says "install the software module", "add the <name> module", "what modules are available", "which modules are installed", "uninstall the <name> module", or asks to make this KB handle source code / a capability the base KB doesn't have. Distinct from `ckb-init` (bootstraps a whole new KB) and `ckb-upgrade` (catches the template layer up with upstream); this skill toggles optional capabilities within an existing KB.
---
# Module skill
## Purpose
The base KB ships every skill always-loaded. Some capabilities are only useful to
*some* knowledge bases, and their skill descriptions would otherwise sit in
context for every KB that will never need them.
Optional capabilities therefore live in `.agents/modules/<name>/` — present in the
repo, inert until installed. This skill is the install/uninstall path. See
[D-0001](/wiki/decisions/0001-opt-in-file-based-kb-modules.md) for why this is
files-in-the-repo rather than a native agent plugin: a module is a property of the
knowledge base, so it must travel with a clone and work for any agent that reads
`AGENTS.md`.
## Trigger phrases
- "install the `<name>` module" / "add the `<name>` module" / "enable `<name>`"
- "what modules are available" / "which modules are installed"
- "uninstall the `<name>` module" / "remove `<name>`" / "disable `<name>`"
- "make this KB handle source code" (→ offer the `software` module)
## The manifest
Installed modules are recorded in `ckb.yaml` at the repo root:
```yaml
kb_modules:
- name: software
version: 1.0.0
installed_on: 2026-09-20
config:
src_repos: []
```
`ckb.yaml` holds repo-level configuration — what's installed, what it's
configured with. It is **not** the wiki's content contract: `kb_schema_version`
stays in `wiki/index.md` where it has always been. Two different things, two
different homes.
If `ckb.yaml` doesn't exist, no modules are installed; create it on first install.
## Installing
### Step 1 — Resolve and read the module
Find `.agents/modules/<name>/module.yaml`. If the name doesn't match, list what's
actually in `.agents/modules/` rather than guessing at a near-miss.
Read the manifest: `skills`, `scaffold`, `agents_fragment`, `gitignore_fragment`,
`schema_additions`, `depends_on`, `requires_kb_schema`.
### Step 2 — Check preconditions, and report them before writing anything
- **Already installed?** If `ckb.yaml` lists it, say so and offer to reinstall
(refresh the files) or stop. Don't silently re-copy.
- **Schema.** If `requires_kb_schema` is above `wiki/index.md`'s
`kb_schema_version`, the bump is part of this install (Step 4) — additive only.
If the module needs a *major* version above the KB's, stop and hand it to
`ckb-upgrade`.
- **Dependencies.** Run each `check`. A failing **optional** dependency is a
warning, not a blocker — report it plainly and continue. A failing required one
stops the install.
- **Collisions.** If a skill name in `skills:` already exists in
`.agents/skills/`, or a scaffold path exists with unrelated content, stop and
ask. Never overwrite a skill the user may have edited.
Report all findings **before** the first write, then proceed (or ask, if anything
needs a decision). A half-installed module is worse than an uninstalled one.
### Step 3 — Copy the payload
```bash
cp -r .agents/modules/<name>/skills/<skill> .agents/skills/<skill>
```
`.claude/skills` is a symlink to `.agents/skills` (git mode `120000`), so the
skills appear under `.claude/` automatically. **Do not create a second copy
there** — that symlink is a deliberate choice, and duplicating it creates two
things to keep in sync.
Create each `scaffold` path, copying any `from` template to its `as` destination.
Never overwrite an existing scaffold file — skip it and note the skip.
### Step 4 — Patch the shared files
Both patches are wrapped in markers so uninstall is exact:
```
<!-- ckb-module:<name> START -->
...fragment...
<!-- ckb-module:<name> END -->
```
- **`AGENTS.md`** — append `agents_fragment` at the end of the file, inside
markers. `CLAUDE.md` is a symlink to `AGENTS.md`, so it updates for free;
never write `CLAUDE.md` directly.
- **`.gitignore`** — append `gitignore_fragment`, inside markers (`#`-commented).
- **`wiki/index.md`** — bump `kb_schema_version` to `requires_kb_schema` if the
module's additions raise it. Additive only, per `ckb-upgrade`'s versioning
policy.
### Step 5 — Record, log, report
- Add the module to `ckb.yaml` with its version and today's date.
- Log to `wiki/log.md` per Rule B **only** for the `wiki/index.md` change — the
rest is template layer, not wiki content.
- Append to `workload/YYYY-MM-DD_summary.md` per Rule D.
- Report: skills now available and what they do, directories created, files
patched, dependency warnings, schema bump if any. Then the standard reminder —
on disk, not committed.
Offer to record a decision (`ckb-decide`) if installing the module was a real
choice for this KB rather than following a prior one.
## Uninstalling
Reverse Step 3 and 4, in this order, and be conservative about data:
1. Remove `.agents/skills/<skill>` for each skill the manifest lists — **but
first diff it against `.agents/modules/<name>/skills/<skill>`.** If the
installed copy was edited, show the diff and ask before deleting. Offer to
copy the edits back into the module folder so they survive.
2. Strip the marked blocks from `AGENTS.md` and `.gitignore`.
3. Remove the module's entry from `ckb.yaml`.
**Never remove scaffold directories or any content under them.** `src/` may hold
the user's clones, `openspec/` their specs. Say explicitly what was left behind
and why, so nothing looks like an oversight.
**Never remove wiki pages the module's skills created**, and never lower
`kb_schema_version`. Those pages are knowledge; the module produced them but does
not own them, and they must stay readable without it. Say which page types
(`repository`, `component`, `spec`) will now have no skill maintaining them.
## Listing
On "what modules are available": list `.agents/modules/*/module.yaml` with each
`title` and `summary`, marking which are installed per `ckb.yaml`. Keep it short
— name, one line, installed or not.
## Edge cases
- **A module directory with no `module.yaml`** — not a module. Report it as
malformed; don't try to infer its contents from its file layout.
- **The user asks for a capability no module provides** — say so, and don't
install a near-match hoping it fits. Offer to note it in `wiki/query-gaps.md`.
- **`ckb-upgrade` brought a newer version of an installed module** — the installed
skill copies are stale. Offer to reinstall; show what changed before doing it.
- **Markers missing at uninstall** (someone hand-edited `AGENTS.md`) — don't
guess at the block's boundaries. Show the fragment and ask the user to remove
it, or point at exactly what to delete.
- **A module's skill was renamed upstream** — treat as collision (Step 2), ask.
Don't delete the old name automatically.
---
*Licensed under the Apache License, Version 2.0 — see [LICENSE](../../../LICENSE)
at the repository root, or <http://www.apache.org/licenses/LICENSE-2.0>.*

View file

@ -0,0 +1,198 @@
---
name: ckb-reset
description: DESTRUCTIVE — empty this knowledge base back to a clean template, deleting every accumulated wiki page, decision record, graph edge, log entry, workload summary and (on request) raw/outputs material, then restoring the empty scaffold that `ckb-init` would create. Use when the user says "reset the wiki", "empty the wiki", "clean this KB out", "make this a clean template", "wipe the knowledge base", or wants to turn a working KB back into a distributable template. Always inventories what would be destroyed and takes explicit confirmation before deleting anything. Never touches the template layer (AGENTS.md, skills, modules, docs) or `src/`.
---
# Reset skill
## Purpose
A KB that also serves as the template for other KBs accumulates content that
shouldn't ship with it — decisions made about this project, workload summaries,
entity pages, graph edges. This skill returns it to the shape `ckb-init` creates:
same structure, same schema, no knowledge.
It is the only skill in this KB that deletes knowledge on purpose. Everything
below is written on the assumption that **getting this wrong destroys work that
took a long time to accumulate**, and that "the user asked for it" is not enough
on its own — people ask for this in the wrong repo.
## Trigger phrases
- "reset the wiki" / "empty the wiki" / "wipe the knowledge base"
- "clean this KB out" / "make this a clean template"
- "turn this back into a template" / "strip the content but keep the structure"
## Non-negotiable safety rules
1. **Never delete without an inventory shown first and an explicit confirmation
after it.** Not "proceed?" before you know the scale — the count is the thing
that makes the answer meaningful.
2. **Never touch the template layer.** `AGENTS.md`, `CLAUDE.md`, `.agents/`,
`.claude/`, `LICENSE`, `VERSION`, `README*`, `MANUAL*`, `OPENSPEC*`,
`.gitignore`, `ckb.yaml`, `.git/`. Those *are* the template.
3. **Never touch `src/`.** Those are independent repositories holding code this
skill has no business deleting. Not even with confirmation — tell the user to
delete them with `rm -rf` themselves if that's really what they want.
4. **Never run when the working tree is dirty**, unless the user overrides after
being told why. Uncommitted work is unrecoverable once deleted; committed work
is always recoverable from git.
5. **Never guess the scope.** If the user says "reset" without saying how far,
ask — don't assume the widest or the narrowest reading.
## How to run this skill
### Step 0 — Establish that git can undo this
Run `git status --short` and `git log --oneline -1`.
- **Dirty tree** — stop and report exactly what's uncommitted. Offer to commit
first ("Let me commit this as a restore point, then reset"), and only proceed
without committing if the user explicitly says the uncommitted work is
disposable. This is the single highest-value check in the skill: after a reset,
committed content is a `git checkout` away and uncommitted content is gone.
- **Not a git repository at all** — say so plainly and require a much more
explicit confirmation, because nothing here is recoverable. Recommend the user
copy the folder somewhere safe first.
- **Clean tree** — note the commit hash and tell the user it's the restore point.
Offer to tag it (`git tag pre-reset-<date>`), since a hash in a chat log is
easy to lose.
### Step 1 — Agree the scope
Present the tiers and let the user choose. Default to **Tier 1 only** if they
just said "reset the wiki" — the narrowest reading that satisfies the request.
| Tier | Contents | Default |
|---|---|---|
| **1 — Wiki knowledge** | Every page under `wiki/entities/`, `wiki/projects/`, `wiki/decisions/` (the `NNNN-*.md` records), `wiki/graph/edges.json` entries, and all log/overview/query-gap/error-book *entries* | **Yes** |
| **2 — Workload history** | Every `workload/*_summary.md` | Ask |
| **3 — Source material** | `raw/inbox/*`, `raw/archive/*` | Ask — this is the user's original material and may exist nowhere else |
| **4 — Generated artifacts** | `outputs/*` | Ask — cheap to regenerate, usually safe |
| **5 — External sources** | `libs/*`, `linked/*` | Ask — **default no.** `linked/` holds symlinks to *other people's* KBs, and deleting a symlink target by accident is a real risk |
| **6 — Installed modules** | `ckb.yaml` + module-installed skills + the marked blocks in `AGENTS.md`/`.gitignore` | Ask — **default no.** That's `ckb-module uninstall`'s job, not this skill's |
For a template being prepared for distribution, tiers 14 are the usual answer.
**Say what each tier means in files, not just in names.** "Tier 3 deletes 48
files in `raw/archive/` including the original meeting recordings" is a sentence
that changes answers.
### Step 2 — Build and show the inventory
Count, don't estimate. For the chosen tiers:
```bash
find wiki/entities wiki/projects -name '*.md' ! -name 'index.md' | wc -l
ls wiki/decisions/[0-9]*.md 2>/dev/null | wc -l
python3 -c "import json;print(len(json.load(open('wiki/graph/edges.json'))['edges']))"
ls workload/*_summary.md 2>/dev/null | wc -l
find raw/inbox raw/archive -type f 2>/dev/null | wc -l
```
Present it as a table: what, how many, and — for anything irreplaceable — where
it came from. Call out explicitly:
- **Decision records**, by number and title. These are append-only by design and
represent reasoning that cannot be reconstructed; losing them is the most
expensive part of any reset.
- **`raw/archive/` material with no upstream**, if tier 3 is selected.
- **Anything with `retention: high`** in its frontmatter — the wiki's own signal
that it was meant to be kept.
Then state what will *survive*, in one line. That's as reassuring as the deletion
list is alarming, and it's what tells the user whether you understood the task.
### Step 3 — Take the confirmation
Ask for a typed phrase, not a yes:
> This will permanently delete **47 wiki pages, 12 decision records, 9 workload
> summaries and 128 graph edges**. Restore point: `491ca8a` (clean tree).
> Type **`reset the wiki`** to proceed, or anything else to cancel.
Accept only that phrase. A "yes", a "go ahead", or silence is **not** consent
here — the typed phrase exists precisely so the action can't be taken by reflex
or by an agent misreading agreement to something else in the conversation.
If the user modifies the scope in their reply, go back to Step 2 and re-inventory.
Never carry a confirmation across a scope change: they confirmed a number, and
the number moved.
### Step 4 — Delete, then restore the scaffold
Delete the agreed tiers. Then restore the empty scaffold **exactly as `ckb-init`
Step 8 defines it** — that skill is the single source of truth for what a clean
`wiki/` looks like, so read it rather than reconstructing the files from memory:
- `wiki/index.md` — routing table, infrastructure rows only, no entity rows.
**Keep `kb_schema_version` at its current value.** A reset empties content; it
does not roll back the schema contract.
- `wiki/overview.md` — the generic version, `last_updated` today.
- `wiki/log.md`, `wiki/decisions/log.md` — headers and explanation, no entries.
- `wiki/error-book.md`, `wiki/query-gaps.md` — headers, no entries.
- `wiki/entities/index.md`, `wiki/projects/index.md`, `wiki/graph/index.md`
headers plus placeholder notes.
- `wiki/decisions/index.md` — header, placeholder, and the status-vocabulary
table **verbatim** (`ckb-decide` and `ckb-lint` both validate against it).
- `wiki/graph/edges.json``{"version": 1, "last_updated": "<today>", "edges": []}`.
- `.gitadd` placeholder files in any directory that would otherwise be empty, so
the structure survives in git.
Preserve directories even when empty. A reset KB must have the same shape as a
fresh one, or the next ingest starts by rebuilding scaffolding.
### Step 5 — Verify before reporting success
Do not report completion until you've checked it:
```bash
ls wiki/entities/ wiki/decisions/ wiki/projects/
python3 .agents/skills/ckb-lint/scripts/lint_report.py
git status --short
```
Lint should come back clean on a fresh scaffold. If it doesn't, the scaffold is
wrong — say so and fix it rather than declaring done. A reset that leaves a
malformed wiki is worse than no reset, because the damage is already unrecoverable
and now the structure is broken too.
### Step 6 — Report
State: tiers reset, counts deleted per tier, scaffold files restored, the restore
point hash (and tag, if one was made), lint result, and what was deliberately left
alone (`src/`, modules, template layer).
**Do not append a workload summary.** Rule D's session note would be the first
entry in a workload directory this skill just emptied, which defeats the purpose.
Say so in the report instead — this is a deliberate, one-off exception to Rule D,
and worth naming so it doesn't read as an oversight.
Finish with: the reset is on disk but not committed. `git checkout .` still undoes
everything until it is. That sentence is the last safety net, so don't omit it.
## Edge cases
- **Already clean** — say so and change nothing. Don't rewrite identical scaffold
files to look busy.
- **Run in a KB that is not a template** — this skill can't tell the difference,
so if the wiki holds substantial content (say, 50+ pages or any decision
records), name that in the confirmation: "This KB has 12 decision records —
templates don't usually have those. Are you in the right repository?" Ask once;
don't refuse if they confirm.
- **`linked/` symlinks** — never follow them when deleting. `rm -rf linked/foo`
where `foo` is a symlink to another KB is catastrophic and silent. Remove the
*link*, never its target, and prefer leaving tier 5 alone.
- **Partial failure mid-delete** — stop, report exactly what was and wasn't
deleted, and point at the restore point. Don't continue on the theory that
finishing is tidier.
- **User asks to reset "everything including the skills"** — that's not a reset,
it's deleting the KB. Say so and point at `ckb-init` for a fresh one elsewhere.
- **Module installed** — module-created page types (`repository`, `component`,
`spec`) are wiki content and reset with tier 1. The module itself stays
installed unless tier 6 was chosen.
---
*Licensed under the Apache License, Version 2.0 — see [LICENSE](../../../LICENSE)
at the repository root, or <http://www.apache.org/licenses/LICENSE-2.0>.*

View file

@ -63,6 +63,23 @@ ask the user via `AskUserQuestion` whether to include or skip each one
*before* staging anything in Step 3 — never silently commit or silently
drop a flagged file.
### Step 1b — Nested source repos (`software` module only)
If `ckb.yaml` lists the `software` module and `src/` holds clones, those are
**independent repositories with their own remotes**. This skill syncs *this*
repo only.
- Never `git add` anything under `src/`, and never `git commit`, `git push`,
or `git checkout` inside one. They are gitignored; if `git status` shows
something there, treat it as a `.gitignore` defect to report, not content
to stage.
- Do report each clone's state — current branch, dirty or clean, ahead or
behind its own remote — so uncommitted work isn't silently forgotten while
the KB itself gets pushed. Reporting is the whole contribution here;
acting on it is the user's call, in that repo.
Skip this step entirely when the module isn't installed or `src/` is empty.
### Step 2 — Ensure `origin` is configured
```bash

View file

@ -153,6 +153,13 @@ The template layer is exactly these paths — never anything under `wiki/`,
exist upstream (an older local KB may not have some of these yet)
- `.agents/skills/<name>/**` for every skill folder present in
`tmp/ckb-upgrade-src/.agents/skills/`
- `.agents/modules/<name>/**` for every optional module present upstream
(see `ckb-module`). Upgrade the module *payload* freely — it is inert
template content. But **never delete a skill under `.agents/skills/`
just because it is absent upstream**: it may be a module-installed copy
that this KB deliberately enabled. Check `ckb.yaml` before treating any
skill as removed upstream. When an installed module's payload changes,
say so and suggest reinstalling it — the installed copies are now stale.
- The base ignore rules in `.gitignore` (`libs/`, `linked/`, `tmp/`,
regenerated `outputs/` subfolders, `.env`, etc.) — merged, never
replaced wholesale (see Step 6)

View file

@ -14,6 +14,7 @@ should be loaded only when their trigger applies.
Maintain this root layout:
```
├── .agents/modules/ # Optional modules, inert until installed
├── libs/ # Read-only external sources:
│ └── <name>/ # - git-copy clone/ZIP: immutable, never write here
│ # - connector source: has user-authored source.yaml
@ -38,6 +39,17 @@ Maintain this root layout:
└── YYYY-MM-DD_summary.md
```
### Optional Modules
Capabilities not every KB needs ship in `.agents/modules/<name>/` and are
inert until installed. Installing copies the module's skills into
`.agents/skills/`, creates its scaffold, appends a marked block to this
file and `.gitignore`, and records it in the root `ckb.yaml`. `ckb-module`
owns that; read `ckb.yaml` to see what is installed. A module may add
directories (such as `src/`) and optional page types — always additively.
`CLAUDE.md` is a symlink to this file and `.claude/skills` a symlink to
`.agents/skills`. Write the `.agents`-side path only; never duplicate.
### Cascade Priority
When searching for any entity, concept, or file, use first match wins:
@ -94,9 +106,11 @@ append-only: never rewrite a decision's substance to match a later change of
mind — record a new decision that supersedes it, and set both
`supersedes` and `superseded_by`. `ckb-decide` owns the format.
`wiki/index.md` alone also carries `kb_schema_version`, currently `"1.4"`.
Detailed schema migration and version-bump policy belongs in
`ckb-upgrade`.
`wiki/index.md` alone also carries `kb_schema_version`, currently `"1.4"`
for the base contract. An installed module may raise it additively by
declaring `requires_kb_schema` and contributing optional types and fields;
`ckb-module` applies that bump at install time. Detailed schema migration
and version-bump policy belongs in `ckb-upgrade`.
---
@ -114,6 +128,8 @@ file.
| Sync this repo with `origin` | `ckb-sync-changes` |
| Upgrade template or wiki schema | `ckb-upgrade` |
| Bootstrap a new empty KB (from local files or a fresh clone of the template repo) | `ckb-init` |
| Install, list, or uninstall an optional module | `ckb-module` |
| Empty the wiki back to a clean template (destructive) | `ckb-reset` |
| Export OKF or Starlight artifacts | `ckb-export-okf`, `ckb-export-starlight` |
| Generate a project overview | `ckb-project-summary` |
| Teach, quiz, or onboard from the wiki | `ckb-teach-me`, `ckb-quiz`, `ckb-onboard-me` |
@ -136,6 +152,13 @@ Short routing rules:
use `ckb-sync-changes`, not ingest.
- For "upgrade the wiki" or "check for a newer template version", use
`ckb-upgrade`.
- For "install/uninstall the `<name>` module", "what modules are
available", or a request for a capability the base KB lacks (such as
handling source code), use `ckb-module`.
- For "reset the wiki", "empty the wiki", or "make this a clean template",
use `ckb-reset`. It deletes accumulated knowledge, so it always shows an
inventory and takes a typed confirmation first, and never touches the
template layer or `src/`.
---

View file

@ -284,6 +284,52 @@ safely can on its own, and reports the rest for you to decide. Like Ingest, it f
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
@ -677,6 +723,7 @@ graph stay in sync with what you changed.
| "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` |

View file

@ -296,6 +296,55 @@ zrobić bezpiecznie, a resztę zgłasza do twojej decyzji. Podobnie jak Ingest,
synchronizacji. Zaimplementowane przez skill `ckb-lint`
`.agents/skills/ckb-lint/SKILL.md`.
### Zaczynanie od zera: reset do czystego szablonu
Czasem chcesz zachować *kształt* bazy wiedzy bez jej zawartości — zwykle
dlatego, że to repozytorium pełni też rolę szablonu przekazywanego innym, a
zdążyło zebrać decyzje, podsumowania sesji i strony encji, które nie powinny
z nim wędrować.
> „Zresetuj wiki.” / „Zrób z tego czysty szablon.”
To jedyne polecenie w tym repozytorium, które **celowo usuwa wiedzę**, więc
jest zbudowane tak, żeby trudno było je uruchomić przez przypadek:
1. **Najpierw szuka punktu przywracania.** Jeśli drzewo robocze jest
„brudne”, zatrzymuje się i proponuje commit — po resecie wszystko, co
zacommitowane, jest o jedno `git checkout` stąd, a wszystko
niezacommitowane po prostu znika. Może też otagować commit
(`pre-reset-<data>`), żebyś nie musiał trzymać hasha w głowie.
2. **Pyta, jak daleko sięgnąć.** Sześć poziomów wybieranych osobno: wiedza w
wiki, historia `workload/`, materiał źródłowy w `raw/`, `outputs/`,
źródła zewnętrzne i zainstalowane moduły. Domyślnie włączony jest tylko
pierwszy. `libs/`, `linked/` i moduły domyślnie na *nie*`linked/`
zawiera dowiązania do cudzych baz wiedzy, więc usuwa dowiązanie, ale
nigdy nie podąża za nim.
3. **Liczy, zanim zapyta.** Dostajesz inwentarz — ile stron, ile rekordów
decyzji (wymienionych z numerem i tytułem), ile krawędzi grafu, plus
wszystko oznaczone `retention: high` — i jedną linijkę o tym, co
przetrwa.
4. **Wymaga wpisania frazy**, nie „tak”. A jeśli w odpowiedzi zmienisz
zakres, przeliczy wszystko i zapyta ponownie, bo zgodziłeś się na
konkretną liczbę, a liczba się zmieniła.
5. **Weryfikuje po wszystkim**, uruchamiając lint, zanim powie, że się
udało.
Odtwarza dokładnie to, co utworzyłby `ckb-init`: te same katalogi, te same
pliki szkieletu, ten sam `kb_schema_version`. Opróżnienie treści nie cofa
wersji schematu.
Czego nie rusza nigdy, z potwierdzeniem czy bez: warstwy szablonu
(`AGENTS.md`, `.agents/`, `LICENSE`, `VERSION`, dokumentacja) oraz `src/`,
gdzie leżą niezależne repozytoria kodu, do których usuwania to polecenie nie
ma żadnego tytułu.
Jedna celowa osobliwość: w odróżnieniu od każdego innego skilla ten **nie**
zapisuje notatki sesji w `workload/` — byłby to pierwszy wpis w katalogu,
który właśnie opróżnił. Informuje o tym w raporcie.
Zaimplementowane przez skill `ckb-reset`
`.agents/skills/ckb-reset/SKILL.md`.
---
## 4. Synchronizacja — z samym sobą i z innymi ludźmi
@ -711,6 +760,7 @@ zmieniłeś.
| „Zapisz decyzję: ...” / „zdecydowaliśmy ...” | Zapisuje numerowany rekord decyzji pod `wiki/decisions/` | `ckb-decide` |
| „Co zdecydowaliśmy w sprawie X” / „kto zdecydował X” / „co jest otwarte” | Odpowiada z zapisów decyzji, z autorem, datą i statusem | `ckb-decide` |
| „Lint” | Sprawdza kondycję wiki, automatycznie naprawia to, co bezpiecznie może | `ckb-lint` |
| „Zresetuj wiki” / „Zrób z tego czysty szablon” | **Destrukcyjne.** Usuwa zgromadzoną wiedzę i odtwarza pusty szkielet, po inwentarzu i potwierdzeniu wpisaną frazą | `ckb-reset` |
| „Sync changes” / „Sync with git” | Commituje, pobiera, rozwiązuje konflikty, wypycha do `origin` | `ckb-sync-changes` |
| „Quiz me on X” | Jednorazowy, punktowany sprawdzian wiedzy | `ckb-quiz` |
| „Teach me the wiki” / „Teach me about X” | Planuje i prowadzi rozłożony w czasie kurs ze śledzeniem postępu | `ckb-teach-me` |

202
OPENSPEC.md Normal file
View file

@ -0,0 +1,202 @@
# OpenSpec in this knowledge base
*Read this in: **English** | [Polski](OPENSPEC.pl.md)*
How to add [OpenSpec](https://openspec.dev) to a Cascade KB that documents
software you're building, and how it fits alongside the wiki.
This is a human guide. The agent's own rules live in the `software` module —
[.agents/modules/software/](.agents/modules/software/README.md) — which must be
installed before any of this applies. Say **"install the software module"**.
---
## Contents
1. [What OpenSpec is for here](#1-what-openspec-is-for-here)
2. [Read this before you run `openspec init`](#2-read-this-before-you-run-openspec-init)
3. [Installing](#3-installing)
4. [The two spec levels](#4-the-two-spec-levels)
5. [Daily workflow](#5-daily-workflow)
6. [How specs reach the wiki](#6-how-specs-reach-the-wiki)
7. [Keeping the levels honest](#7-keeping-the-levels-honest)
8. [Quick reference](#8-quick-reference)
---
## 1. What OpenSpec is for here
The wiki records three different things about software, and it's worth keeping
them apart:
| Question | Where it lives | Who writes it |
|---|---|---|
| What *is* the code? | `wiki/entities/``repository` and `component` pages | `ckb-code-map` |
| What *should* it do? | `openspec/specs/` | `ckb-spec` + OpenSpec |
| What did we *choose*, and why? | `wiki/decisions/` | `ckb-decide` |
OpenSpec owns the middle row: a spec states a standing contract, and a change
proposal states what should become true next. You write the spec before the
code, the agent implements against it, and the archived change becomes part of
the permanent record.
If something doesn't constrain future behaviour, it isn't a spec — it's a
decision. Say "record a decision" instead.
## 2. Read this before you run `openspec init`
**Never run `openspec init` in the knowledge base root.** Run it inside
`src/<repo>/`.
This isn't stylistic caution. `openspec init` writes tool integration files into
`.claude/skills/`, and it adds marker blocks to `AGENTS.md` / `CLAUDE.md`. In
this repository both of those are load-bearing:
- `.claude/skills` is a **symlink** to `.agents/skills`. Anything OpenSpec writes
there lands in your KB's own skill set.
- `CLAUDE.md` is a **symlink** to `AGENTS.md` — the KB's system prompt. They are
one file, so a marker block written to "both" is written twice to the same
place.
Run it at the root and you get OpenSpec's per-repo workflow instructions mixed
into the rules governing your whole knowledge base. Run it in `src/<repo>/` and
everything stays where it belongs: the repo gets its own `.claude/`, its own
`AGENTS.md`, and its specs travel with its code.
The KB root's `openspec/` directory is **not** an OpenSpec install (§4), so it
never needs `init`.
## 3. Installing
Needs **Node.js 20.19.0+**.
```bash
npm install -g @fission-ai/openspec@latest # or pnpm / yarn / bun
openspec --version
```
Then, per repository:
```bash
cd src/<repo>
openspec init
```
After upgrading the CLI later, run `openspec update` in each repo to refresh its
generated instruction files.
**Uninstalling from a repo** means removing its `openspec/` directory, its
generated tool files, and the OpenSpec marker blocks from that repo's
`AGENTS.md` / `CLAUDE.md` by hand — the CLI doesn't unwind those for you.
## 4. The two spec levels
Specs live in two places on purpose.
**KB root — `openspec/`** — cross-cutting capabilities that span several `src/`
repos. The *what* and *why* that no single repo owns.
This layer is managed by the `ckb-spec` skill, **not** by the OpenSpec CLI.
There's no code beneath it and no repo for it to govern, so OpenSpec's
repo-shaped workflow doesn't apply. It's tracked in the KB's git history, like
every other piece of knowledge here.
**Per repo — `src/<repo>/openspec/`** — how that repo implements those
capabilities. The *how*. This is OpenSpec's native case: managed by the CLI and
its own instructions, travelling with the code and riding along in that repo's
pull requests.
The agent defers to OpenSpec here and won't substitute a workflow of its own. If
the CLI isn't installed it says so rather than improvising.
## 5. Daily workflow
From inside a repo that's been initialized, the loop is
**propose → apply → archive**:
| Step | Say / run | What happens |
|---|---|---|
| Propose | `/opsx:propose <what you want>` | Proposal, spec delta, design and tasks written as Markdown under `openspec/changes/<id>/` |
| Review | `openspec show <id>`, `openspec validate <id>` | Read the delta; validation checks structure and checks modified requirements against the specs they'd replace |
| Apply | `/opsx:apply` | The agent implements against the spec |
| Archive | `/opsx:archive` or `openspec archive <id>` | The change merges into the main specs and moves to `changes/archive/` |
Useful alongside: `openspec list`, `openspec status`, `openspec view` (an
interactive dashboard).
For the KB-root layer there's no CLI — just say **"write a cross-cutting spec
for X"** and `ckb-spec` handles it.
## 6. How specs reach the wiki
Three bridges, all handled by `ckb-spec`. This is what stops OpenSpec from being
a parallel universe next to your knowledge base.
**Archived change → decision record.** An applied-and-archived change is a
decision that was made and acted on. The agent *offers* to record it under
`wiki/decisions/` — the proposal's reasoning becomes Context and Rationale, the
delta becomes the Decision, rejected options become Alternatives considered.
It offers rather than doing it automatically, deliberately. Not every routine
change deserves a permanent numbered record, and a decisions log padded with
them stops being worth reading.
**Spec → entity page.** Current KB-root specs surface in `wiki/entities/` as thin
`type: spec` pages, so questions like "what is this supposed to do?" get answered
from the index without opening the spec tree. The spec file stays the source of
truth — the wiki page is a pointer, not a copy.
**Level → level.** Root specs and repo specs link to each other (§7).
## 7. Keeping the levels honest
Two spec levels means two places a statement can live, and therefore two places
it can quietly diverge. One rule prevents that:
> A root spec lists every repo spec implementing it in `implemented_by:`.
> A repo spec names its parent in `implements:`.
> **Always set both sides.**
Those links become graph edges, which turns divergence into a visible finding
rather than a silent second source of truth.
Say **"sync the specs"** (or run `lint`) and you get four checks:
1. Root specs with no implementer — *specified, but nobody's building it.*
2. Repo specs whose parent is missing or archived — *building against something
that's no longer true.*
3. One-sided links, either direction.
4. Root specs older than the mapped commit of every repo implementing them —
*possible drift, worth a look.*
None of these are auto-fixed. Each is a statement about intent, and only you know
which side is right.
## 8. Quick reference
| You want to | Say / run |
|---|---|
| Enable all of this | "install the software module" |
| Add OpenSpec to a repo | `cd src/<repo> && openspec init` |
| Map a repo into the wiki | "map `src/<repo>`" |
| Write a cross-cutting spec | "write a cross-cutting spec for X" |
| Propose a change in a repo | `/opsx:propose <what>` |
| Check spec health | "sync the specs" |
| Turn an archived change into a decision | "record this change as a decision" |
**Never:** run `openspec init` at the KB root · `git add` anything under `src/` ·
edit a repo's OpenSpec files to match this KB's conventions.
---
## Sources
- [OpenSpec documentation](https://openspec.dev/docs/installation) ·
[Fission-AI/OpenSpec](https://github.com/Fission-AI/OpenSpec) ·
[@fission-ai/openspec on npm](https://www.npmjs.com/package/@fission-ai/openspec)
- Design records: [D-0001](wiki/decisions/0001-opt-in-file-based-kb-modules.md),
[D-0002](wiki/decisions/0002-software-module-design.md)
---
*Licensed under the Apache License, Version 2.0 — see [LICENSE](LICENSE).*

209
OPENSPEC.pl.md Normal file
View file

@ -0,0 +1,209 @@
# OpenSpec w tej bazie wiedzy
*Read this in: [English](OPENSPEC.md) | **Polski***
Jak dodać [OpenSpec](https://openspec.dev) do Cascade KB, które dokumentuje
tworzone przez Ciebie oprogramowanie, i jak to współgra z wiki.
To przewodnik dla człowieka. Zasady dla samego agenta są w module `software`
[.agents/modules/software/](.agents/modules/software/README.md) — który musi być
zainstalowany, zanim cokolwiek z poniższych zacznie obowiązywać. Powiedz:
**„zainstaluj moduł software”**.
---
## Spis treści
1. [Po co tu OpenSpec](#1-po-co-tu-openspec)
2. [Przeczytaj to, zanim uruchomisz `openspec init`](#2-przeczytaj-to-zanim-uruchomisz-openspec-init)
3. [Instalacja](#3-instalacja)
4. [Dwa poziomy specyfikacji](#4-dwa-poziomy-specyfikacji)
5. [Codzienna praca](#5-codzienna-praca)
6. [Jak specyfikacje trafiają do wiki](#6-jak-specyfikacje-trafiają-do-wiki)
7. [Pilnowanie spójności poziomów](#7-pilnowanie-spójności-poziomów)
8. [Szybki przegląd](#8-szybki-przegląd)
---
## 1. Po co tu OpenSpec
Wiki zapisuje o oprogramowaniu trzy różne rzeczy i warto trzymać je osobno:
| Pytanie | Gdzie mieszka | Kto zapisuje |
|---|---|---|
| Czym *jest* kod? | `wiki/entities/` — strony `repository` i `component` | `ckb-code-map` |
| Co *powinien* robić? | `openspec/specs/` | `ckb-spec` + OpenSpec |
| Co *wybraliśmy* i dlaczego? | `wiki/decisions/` | `ckb-decide` |
OpenSpec odpowiada za środkowy wiersz: specyfikacja opisuje obowiązujący
kontrakt, a propozycja zmiany — co ma stać się prawdą w następnej kolejności.
Piszesz specyfikację przed kodem, agent implementuje pod nią, a zarchiwizowana
zmiana staje się częścią trwałego zapisu.
Jeśli coś nie ogranicza przyszłego zachowania, to nie jest specyfikacja, tylko
decyzja. Powiedz wtedy „zapisz decyzję”.
## 2. Przeczytaj to, zanim uruchomisz `openspec init`
**Nigdy nie uruchamiaj `openspec init` w katalogu głównym bazy wiedzy.**
Uruchamiaj go w `src/<repo>/`.
To nie jest ostrożność na wszelki wypadek. `openspec init` zapisuje pliki
integracji z narzędziami w `.claude/skills/` oraz dodaje bloki znacznikowe do
`AGENTS.md` / `CLAUDE.md`. W tym repozytorium oba te miejsca są nośne:
- `.claude/skills` to **dowiązanie symboliczne** do `.agents/skills`. Cokolwiek
OpenSpec tam zapisze, ląduje w zestawie skilli Twojej bazy wiedzy.
- `CLAUDE.md` to **dowiązanie symboliczne** do `AGENTS.md` — systemowego prompta
bazy. To jeden i ten sam plik, więc blok zapisany „do obu” zapisuje się
dwukrotnie w to samo miejsce.
Uruchomienie w katalogu głównym wmiesza instrukcje OpenSpec dla pojedynczego
repozytorium w reguły rządzące całą bazą wiedzy. Uruchomienie w `src/<repo>/`
zostawia wszystko na swoim miejscu: repozytorium dostaje własne `.claude/`,
własny `AGENTS.md`, a jego specyfikacje podróżują razem z kodem.
Katalog `openspec/` w korzeniu bazy **nie jest** instalacją OpenSpec (§4), więc
nigdy nie wymaga `init`.
## 3. Instalacja
Wymaga **Node.js 20.19.0 lub nowszego**.
```bash
npm install -g @fission-ai/openspec@latest # albo pnpm / yarn / bun
openspec --version
```
Następnie, dla każdego repozytorium:
```bash
cd src/<repo>
openspec init
```
Po późniejszej aktualizacji CLI uruchom w każdym repozytorium `openspec update`,
żeby odświeżyć wygenerowane pliki instrukcji.
**Odinstalowanie z repozytorium** oznacza ręczne usunięcie katalogu `openspec/`,
wygenerowanych plików narzędziowych oraz bloków znacznikowych OpenSpec z
`AGENTS.md` / `CLAUDE.md` tego repozytorium — CLI tego za Ciebie nie cofa.
## 4. Dwa poziomy specyfikacji
Specyfikacje mieszkają w dwóch miejscach i jest to zamierzone.
**Korzeń bazy — `openspec/`** — przekrojowe zdolności obejmujące kilka
repozytoriów w `src/`. To *co* i *dlaczego*, którego nie posiada żadne pojedyncze
repozytorium.
Tą warstwą zarządza skill `ckb-spec`, a **nie** CLI OpenSpec. Nie ma pod nią
kodu ani repozytorium, którym miałaby rządzić, więc workflow OpenSpec — skrojony
pod repozytorium — tu nie pasuje. Warstwa ta jest śledzona w historii gita bazy,
tak jak każda inna wiedza.
**Per repozytorium — `src/<repo>/openspec/`** — jak to repozytorium realizuje te
zdolności. To *jak*. Rodzimy przypadek OpenSpec: zarządzany przez CLI i jego
własne instrukcje, podróżujący z kodem i biorący udział w pull requestach tego
repozytorium.
Agent oddaje tu pole OpenSpec i nie podstawia własnego workflow. Jeśli CLI nie
jest zainstalowane, powie to wprost, zamiast improwizować.
## 5. Codzienna praca
W zainicjalizowanym repozytorium pętla wygląda tak:
**propose → apply → archive**.
| Krok | Powiedz / uruchom | Co się dzieje |
|---|---|---|
| Propozycja | `/opsx:propose <co chcesz zbudować>` | Propozycja, delta specyfikacji, projekt i zadania zapisane jako Markdown w `openspec/changes/<id>/` |
| Przegląd | `openspec show <id>`, `openspec validate <id>` | Czytasz deltę; walidacja sprawdza strukturę oraz zmodyfikowane wymagania wobec specyfikacji, które mają zastąpić |
| Wdrożenie | `/opsx:apply` | Agent implementuje pod specyfikację |
| Archiwizacja | `/opsx:archive` lub `openspec archive <id>` | Zmiana scala się z główną specyfikacją i trafia do `changes/archive/` |
Przydatne obok: `openspec list`, `openspec status`, `openspec view`
(interaktywny pulpit).
Dla warstwy w korzeniu bazy nie ma CLI — po prostu powiedz **„napisz przekrojową
specyfikację dla X”**, a zajmie się tym `ckb-spec`.
## 6. Jak specyfikacje trafiają do wiki
Trzy mostki, wszystkie obsługiwane przez `ckb-spec`. To one sprawiają, że
OpenSpec nie staje się równoległym światem obok bazy wiedzy.
**Zarchiwizowana zmiana → rekord decyzji.** Wdrożona i zarchiwizowana zmiana to
decyzja, którą podjęto i wykonano. Agent *proponuje* zapisanie jej w
`wiki/decisions/` — uzasadnienie z propozycji staje się Kontekstem i Uzasadnieniem,
delta staje się Decyzją, a odrzucone opcje — Rozważanymi alternatywami.
Proponuje, a nie robi tego automatycznie, i jest to celowe. Nie każda rutynowa
zmiana zasługuje na trwały, numerowany rekord, a dziennik decyzji zapchany nimi
przestaje być wart czytania.
**Specyfikacja → strona encji.** Aktualne specyfikacje z korzenia bazy pojawiają
się w `wiki/entities/` jako cienkie strony `type: spec`, dzięki czemu pytania w
rodzaju „co to ma robić?” da się odpowiedzieć z indeksu, bez otwierania drzewa
specyfikacji. Źródłem prawdy pozostaje plik specyfikacji — strona wiki jest
wskaźnikiem, nie kopią.
**Poziom → poziom.** Specyfikacje z korzenia i z repozytoriów linkują się
nawzajem (§7).
## 7. Pilnowanie spójności poziomów
Dwa poziomy specyfikacji to dwa miejsca, w których może mieszkać to samo
stwierdzenie — a więc i dwa, w których może się po cichu rozjechać. Zapobiega
temu jedna zasada:
> Specyfikacja z korzenia wymienia każdą implementującą ją specyfikację
> repozytorium w `implemented_by:`.
> Specyfikacja repozytorium wskazuje rodzica w `implements:`.
> **Zawsze ustawiaj obie strony.**
Te odnośniki stają się krawędziami grafu, co zamienia rozjazd w widoczne
znalezisko, zamiast w cichy drugi ośrodek prawdy.
Powiedz **„zsynchronizuj specyfikacje”** (albo uruchom `lint`), a dostaniesz
cztery kontrole:
1. Specyfikacje z korzenia bez implementacji — *opisane, ale nikt tego nie buduje.*
2. Specyfikacje repozytorium, których rodzic zniknął lub trafił do archiwum —
*budujesz pod coś, co przestało obowiązywać.*
3. Jednostronne odnośniki, w dowolnym kierunku.
4. Specyfikacje z korzenia starsze niż zmapowany commit każdego repozytorium,
które je implementuje — *możliwy rozjazd, wart sprawdzenia.*
Żadna z tych rzeczy nie jest naprawiana automatycznie. Każda jest stwierdzeniem
o intencji, a tylko Ty wiesz, która strona ma rację.
## 8. Szybki przegląd
| Chcesz | Powiedz / uruchom |
|---|---|
| Włączyć to wszystko | „zainstaluj moduł software” |
| Dodać OpenSpec do repozytorium | `cd src/<repo> && openspec init` |
| Zmapować repozytorium do wiki | „zmapuj `src/<repo>`” |
| Napisać przekrojową specyfikację | „napisz przekrojową specyfikację dla X” |
| Zaproponować zmianę w repozytorium | `/opsx:propose <co>` |
| Sprawdzić stan specyfikacji | „zsynchronizuj specyfikacje” |
| Zamienić zarchiwizowaną zmianę w decyzję | „zapisz tę zmianę jako decyzję” |
**Nigdy:** nie uruchamiaj `openspec init` w korzeniu bazy · nie rób `git add`
niczego w `src/` · nie przerabiaj plików OpenSpec repozytorium pod konwencje tej
bazy.
---
## Źródła
- [Dokumentacja OpenSpec](https://openspec.dev/docs/installation) ·
[Fission-AI/OpenSpec](https://github.com/Fission-AI/OpenSpec) ·
[@fission-ai/openspec na npm](https://www.npmjs.com/package/@fission-ai/openspec)
- Rekordy projektowe: [D-0001](wiki/decisions/0001-opt-in-file-based-kb-modules.md),
[D-0002](wiki/decisions/0002-software-module-design.md)
---
*Udostępniane na licencji Apache License 2.0 — zobacz [LICENSE](LICENSE).*

View file

@ -14,6 +14,10 @@ how to create a wiki, add knowledge, keep it tidy, sync with others, and
worked examples for every use case — see [MANUAL.md](MANUAL.md)
([Polski](MANUAL.pl.md)).
If this KB documents software you're building, the optional `software` module
adds `src/` repositories and spec-driven development — see
[OPENSPEC.md](OPENSPEC.md) ([Polski](OPENSPEC.pl.md)).
---
## Directory Structure

View file

@ -15,6 +15,10 @@ przewodnik — jak stworzyć wiki, dodawać wiedzę, utrzymywać porządek,
synchronizować się z innymi i przykłady dla każdego przypadku użycia —
znajdziesz w [MANUAL.pl.md](MANUAL.pl.md) ([English](MANUAL.md)).
Jeśli ta baza dokumentuje tworzone przez Ciebie oprogramowanie, opcjonalny moduł
`software` dodaje repozytoria w `src/` i pracę sterowaną specyfikacją — zobacz
[OPENSPEC.pl.md](OPENSPEC.pl.md) ([English](OPENSPEC.md)).
---
## Struktura katalogów

View file

@ -1 +1 @@
1.6.1
1.7.0

View file

@ -7,10 +7,4 @@ absorbs a change.
Reverse chronological order, most recent first.
---
## [2026-09-01 21:05] - [CREATE]
- **File Affected:** `wiki/decisions/index.md`, `wiki/decisions/log.md`
- **Description:** Created the decision-log scaffold: an index listing every decision by number with its status and one-line summary, the status vocabulary (proposed / accepted / rejected / superseded / reversed), and this log. No decisions recorded yet.
- **Source:** Chat conversation requesting a decision log feature.
---
*(No entries yet.)*

View file

@ -1,7 +1,7 @@
---
type: error-book
tldr: Table of known ingest/lint errors, root causes, and the constraints derived from them.
last_updated: 2026-07-13
last_updated: 2026-09-20
---
# Error Book

1
wiki/graph/edges.json Normal file
View file

@ -0,0 +1 @@
{"version": 1, "last_updated": "2026-09-20", "edges": []}

View file

@ -1,54 +1,19 @@
# Wiki Change Log
## [2026-09-01 21:05] - [CREATE]
- **File Affected:** `wiki/decisions/` (directory)
- **Description:** Created the decision-records directory — one numbered, append-only page per decision, recorded and queried by the new `ckb-decide` skill. Its own contents are logged in `wiki/decisions/log.md`.
- **Source:** Chat conversation requesting a decision log feature.
---
## [2026-09-01 21:05] - [UPDATE]
- **File Affected:** `wiki/index.md`
- **Description:** Added the Decisions routing row and a "Decision Records" section, and bumped `kb_schema_version` from `1.3` to `1.4` — a minor bump for the additive `decisions/` scaffold and the optional `status`/`decided_on`/`decided_by`/`affects`/`review_on` fields on `type: decision` pages. No existing field or convention changed meaning.
- **Source:** Chat conversation requesting a decision log feature.
---
## [2026-09-01 21:05] - [UPDATE]
- **File Affected:** `wiki/overview.md`
- **Description:** Documented `wiki/decisions/` in the directory tree, added a "Decision Records" section covering the append-only rule and the decision-specific frontmatter, and listed `decisions/` among the recursive indexes.
- **Source:** Chat conversation requesting a decision log feature.
---
## [2026-09-01 21:05] - [UPDATE]
- **File Affected:** `wiki/graph/index.md`
- **Description:** Documented two new optional edge types, `decided_by` (decision -> person) and `affects` (decision -> constrained entity), so "who decided X" and "what decisions touch Y" become direct graph lookups.
- **Source:** Chat conversation requesting a decision log feature.
---
- See wiki/decisions/log.md for decision-record changes on this date.
## [2026-07-30 08:40] - [UPDATE]
- **File Affected:** `wiki/index.md`
- **Description:** Bumped `kb_schema_version` from `1.2` to `1.3` — a minor bump for the additive `has_expertise_in`/`owns` graph edge types. No existing field or convention changed meaning.
- **Source:** Chat conversation implementing eight ideas drawn from Cerebras' "How We Built Our Knowledge Base".
---
## [2026-07-30 08:38] - [UPDATE]
- **File Affected:** `wiki/graph/index.md`
- **Description:** Documented two new optional edge types, `has_expertise_in` and `owns`, alongside the existing structural ones, so "who knows about X" / "who owns X" become direct graph lookups. Both are evidence-only — never inferred from meeting attendance or job title.
- **Source:** Chat conversation implementing eight ideas drawn from Cerebras' "How We Built Our Knowledge Base".
---
## [2026-07-29 22:47] - [UPDATE]
- **File Affected:** `wiki/index.md`
- **Description:** Bumped `kb_schema_version` from `1.1` to `1.2` for the new optional project-scope and query-gap scaffold conventions.
- **Source:** Chat conversation follow-up asking whether the wiki version was updated.
---
## [2026-07-29 22:30] - [CREATE/UPDATE]
- **File Affected:** `wiki/index.md`, `wiki/overview.md`, `wiki/projects/index.md`, `wiki/query-gaps.md`
- **Description:** Added local-first project scope and query-gap scaffolds inspired by the Cerebras knowledge base concept while keeping the wiki file-based and agent-driven.
- **Source:** Chat conversation comparing Cerebras knowledge base ideas to this local Cascade KB.
---
All modifications to the local `wiki/` directory are recorded here
in reverse chronological order (most recent first).
Each entry uses this format:
```markdown
## [YYYY-MM-DD HH:MM] - [ACTION TYPE]
- **File Affected:** `wiki/path/to/file.md`
- **Description:** Brief summary of what knowledge or structure changed.
- **Source:** Chat conversation, raw file, URL, or skill name.
---
```
Changes to pages under `wiki/decisions/` live in `wiki/decisions/log.md`
instead, per the Recursive Index & Log Convention.
*(No entries yet.)*

View file

@ -1,7 +1,7 @@
---
type: overview
tldr: High-level map of the cascade knowledge base's directory structure, frontmatter schema, and layering rules.
last_updated: 2026-09-01
last_updated: 2026-09-20
---
# Knowledge Base Overview

View file

@ -3,7 +3,7 @@ type: log
tldr: Local queue of questions the wiki could not answer yet, used to drive demand-driven ingest.
confidence: 1.0
quality: 0.8
last_updated: 2026-07-29
last_updated: 2026-09-20
freshness_window_days: 30
retention: medium
---

View file

@ -1,57 +0,0 @@
## 2026-07-29 22:08 CEST
- Compared Cerebras' "How We Built Our Knowledge Base" concept against the current local Cascade KB scaffold.
- Read `wiki/index.md`, `wiki/overview.md`, `wiki/entities/index.md`, and `wiki/graph/index.md`; found the wiki currently covers cascade layering, schema, lazy indexes, empty entity pages, and empty graph scaffolding.
- User requested only a list of ideas not currently covered but compatible with a local-first wiki that does not require dedicated user software; no wiki implementation was performed.
- Noted existing unsynchronized working-tree state from session start: deleted `.claude/skills` and typechanged `CLAUDE.md`.
## 2026-07-29 22:10 CEST
- User asked to commit changes.
- Checked working-tree status before committing; planned to include the current tracked changes plus this workload summary in a single git commit.
## 2026-07-29 22:17 CEST
- User asked again to commit changes.
- Checked working-tree status; found deletions for `CLAUDE.md`, `.claude/skills/export-okf/SKILL.md`, and `.claude/skills/sync-changes/SKILL.md`.
- Planned to commit the current working tree, including this session note.
## 2026-07-29 22:23 CEST
- User asked which ideas from the Cerebras knowledge base concept could be easily implemented in the current local wiki.
- Re-read the current wiki scaffold and git status; identified low-effort, local-first ideas that fit Markdown files and CLI/agent workflows without requiring dedicated user software.
## 2026-07-29 22:44 CEST
- User asked to implement the selected local-first changes and update README/instruction files.
- Added `wiki/projects/index.md` for optional project query scopes and `wiki/query-gaps.md` for durable missing-answer tracking.
- Updated `wiki/index.md`, `wiki/overview.md`, and `wiki/log.md` to register the new scaffolds.
- Updated `README.md`, `MANUAL.md`, `AGENTS.md`, `ckb-retrieve`, and `ckb-ingest` instructions to cover project scopes, local hybrid retrieval, evidence packets, context expansion, query-gap capture, and long-note distillation.
## 2026-07-29 22:47 CEST
- User asked whether the wiki version had been updated.
- Confirmed it had not been bumped yet, then updated `wiki/index.md` from `kb_schema_version: "1.1"` to `"1.2"` and `VERSION` from `1.1.0` to `1.2.0`.
- Updated README/AGENTS schema-version examples and logged the wiki schema bump in `wiki/log.md`.
## 2026-07-29 22:48 CEST
- User asked to commit changes and push to `origin`.
- Began the `ckb-sync-changes` git-level workflow: pre-flight checks passed, `origin` was configured, and `git fetch origin` completed.
## 2026-07-29 22:59 CEST
- User asked which features in `AGENTS.md` could be moved into skills so they do not load every session.
- Read `AGENTS.md`, listed existing skill files, and identified always-on invariants versus procedural or situational sections that are good skill candidates.
## 2026-07-29 23:06 CEST
- User asked to implement the `AGENTS.md` slimming changes.
- Replaced `AGENTS.md` with a shorter always-loaded instruction file focused on directory contract, cascade priority, schema, skill routing, and non-negotiable rules.
- Moved/kept procedural detail in owning skills: retrieval, ingest, external indexing, lint, sync, upgrade, and OKF export references.
- Added schema-versioning policy to `ckb-upgrade` and bumped root `VERSION` from `1.2.0` to `1.2.1`; wiki schema remains `1.2`.
## 2026-07-29 23:13 CEST
- User asked to commit and push the `AGENTS.md` slimming changes.
- Started `ckb-sync-changes`: pre-flight checks passed, `origin` is configured, no in-progress git operation was detected, and `git fetch origin` completed.

View file

@ -1,29 +0,0 @@
## 2026-07-30 08:05 CEST
- User pointed at a local copy of the Cerebras article saved to `tmp/How Cerebras Built Its Enterprise Knowledge Base.html` after two direct `WebFetch` attempts returned HTTP 500.
- Converted it to plain text via `lynx -dump` into the session scratchpad and re-derived the concept list from the primary source, correcting details taken from secondary write-ups in the previous turn.
- Re-listed the ideas not covered by this KB but compatible with a local, file-based, no-install design; excluded the pgvector/HNSW embeddings table, Socket Mode ingestion, CocoIndex chunking, and the hosted cross-encoder reranker as out of scope.
## 2026-07-30 08:20 CEST
- User asked which of those ideas could actually be implemented in the current wiki.
- Read `.agents/skills/ckb-retrieve/SKILL.md` and `.agents/skills/ckb-ingest/SKILL.md` in full, plus the `source.yaml` schema in `ckb-index-external`, the graph edge-type vocabulary, and `.gitignore`'s per-user local-state precedent.
- Found three items from the previous turn's list were already partly covered by the skills (high-signal excerpts in ingest Step 4, `rg` over `raw/archive/` in retrieve Step 2, contradiction-surfacing in retrieve Step 6) and narrowed those claims accordingly.
- Concluded all ten are implementable without dedicated software: seven as prose-only edits to existing skills, three needing one new convention each (an expertise edge type, a `source.yaml` cadence field, a gitignored default-scope file). No implementation performed — assessment only.
## 2026-07-30 09:05 CEST
- User asked to implement the list, then chose all ten minus #5 (planning pass) and #10 (per-user default scope) — the two I'd advised against on value grounds. Eight items implemented.
- `ckb-retrieve`: added `raw/inbox/` to the exact-token sweep, a new Step 4 (RRF-style fusion at `k = 10`, claim-level dedupe, explicit 010 rerank), an expertise/ownership graph lookup in Step 3, caveat surfacing in Step 7, and an edge case for the single-signal case. Renumbered old Steps 46 to 57.
- `ckb-ingest`: replaced the loose "high-signal excerpt" guidance with a three-part acceptance test (rare term via `rg -c`, ~200 chars, corroborated later in the material) plus a rule to carry the parent heading; added `has_expertise_in`/`owns` edge recording, evidence-only.
- `ckb-index-external`: added optional `refresh_interval_days` to `source.yaml` (default 30), wired it into the generated pages' `freshness_window_days` and into Step 4's overdue reporting for both access levels.
- `ckb-lint`: validates `refresh_interval_days` and reports overdue connector indexes with how overdue, regardless of the user's access level; never re-indexes.
- Chose `k = 10` rather than the usual `k = 60` for fusion, since 60 is tuned for hundreds of candidates and flattens scores at local-wiki scale. Recorded the reasoning inline in the skill so it isn't mistaken for a transcription error.
- Bumped `kb_schema_version` 1.2 → 1.3 (additive edge types) and `VERSION` 1.2.1 → 1.3.0; logged both wiki changes in `wiki/log.md` per Rule B.
- Found `README.pl.md`/`MANUAL.pl.md` were behind by more than the version string: five README sections and two MANUAL sections from the 2026-07-29 session had never been translated. Caught both up rather than layering today's changes onto an incoherent base. EN/PL section parity now 28/28 and 15/15.
## 2026-07-30 09:30 CEST
- User asked the reverse comparison: what this KB has that the Cerebras system does not.
- Verified claimed absences by grepping the saved article text rather than asserting from memory — no hits for version/history/supersede/contradict/retention/archive/quality/confidence/entity/ontology/curate/stale/conflict; "graph" only as the HNSW citation, "decay" only as query-time age decay, "audit" once with no detail.
- Framed the answer around the root asymmetry: Cerebras Knowledge is a read path over systems of record it doesn't own, while this KB is itself a system of record that authors and curates content. Noted honestly that the article is a blog post rather than a spec, and that several of this KB's curation features are only tractable at small scale.

View file

@ -1,45 +0,0 @@
## 2026-09-01 20:25 CEST
- Ran `ckb-sync-changes`: committed a local `workload/2026-07-29_summary.md` edit, merged 4 commits from `origin/main` (one conflict in that file, resolved by keeping the remote superset), pushed; `origin/main` now at `8174a54`.
- Updated `.agents/skills/ckb-init/SKILL.md` so init can pull the template repo into a scratch folder instead of only copying from the local working tree:
- New Step 3 "Resolve the template source" (shallow clone of the canonical repo or a user-supplied fork/mirror URL vs. the local working tree), with scratch-path guidance and an explicit rule against cloning into the target itself.
- New Step 11 "Initialize the new KB's own git history (ask first)"; report step now names the template source and git-init outcome.
- Fixed drift while there: skill list (`ckb-quiz` typo, added `ckb-retrieve`/`ckb-index-external`), `kb_schema_version` no longer hard-coded to 1.1, `wiki/projects/` and `wiki/query-gaps.md` added to the scaffold, `.gitignore` snapshot refreshed with the connector `libs/` rules.
- Added clone-related edge cases (clone failure with no local fallback, clone-in-place request, target already a git repo, stale scratch dir).
- Propagated the change to `AGENTS.md` skill routing table and `MANUAL.md`/`MANUAL.pl.md` (prose + "say this" tables).
- Bumped root `VERSION` 1.3.0 → 1.4.0 (template/tooling layer); `wiki/index.md` `kb_schema_version` stays 1.3 — no wiki content contract change.
## 2026-09-01 20:35 CEST
- User asked for a review of the skill set with a proposed model per skill.
- Reviewed all 13 `.agents/skills/ckb-*` skills (plus the 7 personal skills under `~/.claude/skills/`) and classified each by reasoning load vs. mechanical load.
- Proposal: Opus 5 for `ckb-ingest`, `ckb-retrieve`, `ckb-upgrade`, `ckb-project-summary`, `ckb-teach-me`; Sonnet 5 for `ckb-index-external`, `ckb-lint`, `ckb-init`, `ckb-sync-changes`, `ckb-export-okf`, `ckb-onboard-me`, `ckb-quiz`; Haiku 4.5 for `ckb-export-starlight` (script-driven).
- Noted that SKILL.md frontmatter carries only `name`/`description` here and Claude Code skills have no `model` field — model choice is per-session (`/model`) or per-subagent, so applying the proposal means either switching model before invoking or wrapping a skill in a subagent definition with `model:` frontmatter.
- Also flagged: `ckb-export-okf` does its page transform by hand while `ckb-export-starlight` delegates to a Python script — the OKF one is the obvious candidate to scriptify (and would then drop to Haiku).
- No files changed by this review.
## 2026-09-01 20:45 CEST
- User asked to remove the duplicate personal `quiz` skill and to scriptify the skills whose work is mechanical.
- Deleted `~/.claude/skills/quiz/` (byte-identical to `ckb-quiz` apart from the `name:` field and the license footer); a copy was kept in the session scratchpad only.
- Scriptified `ckb-export-okf`: added `.agents/skills/ckb-export-okf/scripts/export_okf.py` (stdlib-only, read-only outside its output dir) doing the whole transform — frontmatter remap, wikilink stripping, `/wiki/` link rewriting, index and log regeneration from the tree, plus an OKF conformance pass over its own output. `--check` validates into a temp dir without writing. Verified byte-identical across two runs.
- Rewrote `ckb-export-okf/SKILL.md` around the script (run it, relay the report, distinguish `SOURCE ISSUE:` = fix the wiki from `NONCONFORMANT:` = fix the script), keeping the mapping table as reference documentation.
- Scriptified the detection half of `ckb-lint`: added `.agents/skills/ckb-lint/scripts/lint_report.py` — strictly read-only, covering checks 1/2/3/4/6/7/8/10 across `wiki/` and every connector-backed `libs/<name>/` (reporting each one's `access:` level). Supersession (5), error-book (9), and every auto-fix-vs-report decision deliberately stay with the model. Added Step 0 to `ckb-lint/SKILL.md` and rewrote the mechanical checks to describe what the findings mean rather than how to detect them.
- Tested the checker against a synthetic tree covering unparseable frontmatter, missing `type`, stale/low-confidence/archive-candidate pages, orphans, dangling graph edges, missing index entries, a change double-logged in root and subdirectory logs, and an invalid `source.yaml`. Against the real wiki it finds one genuine issue: `wiki/query-gaps.md` is 4 days past its 30-day freshness window.
- Propagated to `README.md`/`README.pl.md` (OKF section now describes the script), `MANUAL.md`/`MANUAL.pl.md` (Lint section notes the read-only checker), and `ckb-init` (skill-set copy now names all three support scripts).
- Bumped root `VERSION` 1.4.0 → 1.5.0 (template/tooling layer); wiki `kb_schema_version` stays 1.3 — no content contract change.
- Decided against scriptifying anything else: `ckb-init`/`ckb-upgrade` are interactive and decision-heavy, and the rest (`ingest`, `retrieve`, `project-summary`, `teach-me`, `onboard-me`, `quiz`) are judgment work with no fixed ruleset to encode.
## 2026-09-01 21:10 CEST
- User asked for a decision-log feature: record decisions with who/when/supersession and query them back.
- Designed decisions as their own page kind rather than entity pages, because a decision is a point-in-time record with a lifecycle, not a description that gets rewritten as understanding improves. Core rule: **decision pages are append-only** — a changed mind is a new decision superseding the old one, with the old page's context and rationale left intact.
- Wiki layer: created `wiki/decisions/` with `index.md` (status vocabulary: proposed / accepted / rejected / superseded / reversed) and its own `log.md`. Pages are `NNNN-slug.md`, numbered from 0001, numbers never reused.
- Schema: `type: decision` adds `status`, `decided_on`, `decided_by`, and optional `affects` / `review_on`; the existing `supersedes`/`superseded_by` pair carries decision history (must be set on both sides). Bumped `kb_schema_version` 1.3 → 1.4 (additive) and root `VERSION` 1.5.0 → 1.6.0.
- New skill `ckb-decide` owns both halves: recording (collect facts, ask for gaps in one round rather than an interview, check for a decision it supersedes, allocate the number, write page, update index + graph edges + logs) and lookup (index first, read superseded chains as history, answer with who/when/status attached, never reconstruct an unrecorded decision).
- `ckb-lint` now checks decision structure mechanically via `lint_report.py`: status vocabulary, `decided_on` where the status implies one, `decided_by` present (`unknown` counts), resolvable `affects` targets, two-sided supersession, `superseded`/`reversed` matched by a `superseded_by`, unique four-digit numbers, and overdue `review_on`. The semantic call — whether one decision genuinely replaces another — stays with the model.
- `ckb-ingest` now routes decisions found in raw material to `ckb-decide`'s format, with explicit guardrails against filing a proposal as accepted or guessing a decider. `ckb-retrieve` gained `wiki/decisions/index.md` as cascade step 4 with a handoff rule.
- Graph gained `decided_by` (decision → person) and `affects` (decision → constrained entity) edge types.
- Docs updated in both languages (README/README.pl feature + skill sections, MANUAL/MANUAL.pl new §2.D walkthrough and "say this" table rows, ownership table row noting the append-only convention), plus `ckb-init` (scaffold + skill list). Also fixed five stale `cbk-quiz` path references left from the upstream rename.
- End-to-end tested on a scratch copy: a sample decision record passes lint clean and exports to OKF conformantly. That test surfaced a real bug in `export_okf.py` — a Rule B log line naming a directory (`wiki/decisions/` (directory)) was being turned into a broken intra-bundle link; `files_to_links` now only linkifies entries that name an actual `.md` file.
- Fixed a second bug in `lint_report.py`'s `check_graph`: graph edge endpoints are project-root-absolute per Rule C (`/wiki/entities/foo.md`), but the `known` set holds paths relative to `wiki/`, so every conformant edge was reported as pointing at a missing page. The candidate set now also tries the `/wiki/`-stripped form, matching what the decision-record check already did. Root `VERSION` 1.6.0 → 1.6.1 (patch).