@markstanden/opencode-docs-plugin 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CONVENTION.md CHANGED
@@ -4,13 +4,42 @@ This plugin owns this convention: it is what the `docs` tool's `add` writes,
4
4
  what `check` validates, and what the registered `docs` skill teaches. A
5
5
  repository that adopts the plugin takes the convention with it.
6
6
 
7
+ ## Classes and scope
8
+
9
+ Every doc belongs to exactly one class. The class is fixed by the lake it lives
10
+ in, so a doc cannot mix scopes.
11
+
12
+ | Class | Where | Reader | Writes |
13
+ | ------------------ | ----------------------------------- | ---------------------------- | ------------------------------------- |
14
+ | **Instructions** | nested `README.md` files | code-local how-to | never by the tool |
15
+ | **RepoContext** | `<repo>/docs` by default | this repo | yes |
16
+ | **MachineContext** | a personal lake such as `~/doclake` | this person, across machines | yes |
17
+ | **GlobalContext** | an organisation lake | every team, every repo | yes, lock down with `writable: false` |
18
+ | **Wiki** | a human-readable wiki checkout | humans first, agents second | no |
19
+
20
+ Place at the **narrowest scope where the whole claim is true**:
21
+
22
+ 1. Command or step to build, run, test, deploy → Instructions.
23
+ 2. True only for this repo → RepoContext.
24
+ 3. True for you across machines → MachineContext.
25
+ 4. True for the org across repos → GlobalContext.
26
+ 5. Human-facing narrative → Wiki.
27
+
28
+ Two answers mean two focused docs, one per class. A doc that needs a placement
29
+ debate is not focused enough.
30
+
7
31
  ## Where knowledge lives
8
32
 
9
- Durable knowledge is one Markdown file per topic under the docs root, grouped by
10
- area: `<area>/<name>.md` (the root is the plugin's `root` option; default
11
- `<location>/docs`). The excluded areas — never scanned, never validated —
12
- are `plans/` (scratch, gitignored, deleted when the work lands),
13
- `requirements/` and `wiki/` (vendored mirrors).
33
+ Durable knowledge is one Markdown file per topic under a lake root, grouped by
34
+ area: `<area>/<name>.md`. The default repo lake is `<location>/docs`; its docs
35
+ are RepoContext. A repo adds other local roots in
36
+ `.opencode/docs-lakes.json`; a personal or managed base file lists the
37
+ machine, global and wiki lakes.
38
+
39
+ The excluded areas — never scanned, never validated in a knowledge lake — are
40
+ `plans/` (scratch, gitignored, deleted when the work lands), `requirements/`
41
+ and `wiki/` (vendored mirrors). The wiki profile has no such exclusions; only
42
+ dot-directories and `node_modules` are skipped there.
14
43
 
15
44
  Search also covers `README.md` files nested in the project tree, so an agent
16
45
  finds the map beside the code. They are indexed as they stand (H1 title,
@@ -21,27 +50,44 @@ are skipped by name.
21
50
 
22
51
  ## Front-matter
23
52
 
24
- Every doc opens with a `---` front-matter block. The fields, in canonical order:
53
+ Every knowledge doc opens with a `---` front-matter block. The fields, in
54
+ canonical order:
25
55
 
26
- | Field | Required | Meaning |
27
- | ------------ | -------- | ----------------------------------------------------------------------- |
28
- | `Area` | yes | One top-level path segment; the doc's group. |
29
- | `Keywords` | yes | Comma-separated search terms; the second half of the doc's identity. |
30
- | `Summary` | yes | One self-contained sentence: enough to decide whether to open the file. |
31
- | `Status` | no | `active` (the default) or `superseded`. |
32
- | `Supersedes` | no | The doc this one replaces. |
56
+ | Field | Required | Meaning |
57
+ | ---------- | -------- | ----------------------------------------------------------------------------------------------------------- |
58
+ | `Area` | yes | One top-level path segment; the doc's group. |
59
+ | `Keywords` | yes | Comma-separated search terms; the second half of the doc's identity. |
60
+ | `Summary` | yes | One self-contained sentence that lets a reader decide whether to open the file — not a second introduction. |
33
61
 
34
62
  `Date` is **derived, never written**: the file's last git commit date, falling
35
63
  back to mtime. A hand-maintained `Date` is a finding, not a field.
36
64
 
65
+ There is no lifecycle field. `Status` and `Supersedes` are **obsolete**; `check`
66
+ reports them as notes so an existing lake can be cleaned once. A doc is current
67
+ or deleted: git is the archive.
68
+
37
69
  The tool serialises the front-matter — never copy it by hand.
38
70
 
71
+ Wiki pages carry no front-matter. ADO renders YAML as raw text, and a human wiki
72
+ should read cleanly. The wiki profile derives the title from the H1, the area
73
+ from the folder, the summary from the first prose paragraph, and the date from
74
+ git. Optional invisible metadata may be added later; it is not required.
75
+
39
76
  ## Body
40
77
 
41
78
  - An `H1` title: the first half of the doc's identity.
42
79
  - At least one claim section as an `H2`/`H3` heading — `Facts`, `Inferred`,
43
- `Tested`, `Open questions` — so a reader knows how much to rely on each claim.
44
- Group claims by section rather than mixing them.
80
+ `Tested`, `Failed approaches`, `Open questions` — so a reader knows how much
81
+ to rely on each claim. Group claims by section rather than mixing them.
82
+ - Include only the sections the doc actually needs. An empty heading is noise;
83
+ leave it out.
84
+ - Write so the next reader decides fast: lead with the actionable fact, include
85
+ its reason, limits and evidence where they affect its use, and omit discovery
86
+ chronology, repeated conclusions and empty sections. Under `Tested`, record
87
+ the check, its result and the conditions that mattered.
88
+ - A failed attempt is a valid current doc or section: state what was tried, why
89
+ it failed, what is true now, and what not to retry. Do not keep a doc whose
90
+ claims are no longer true.
45
91
 
46
92
  ## Identity and duplicates
47
93
 
@@ -52,16 +98,54 @@ The tool serialises the front-matter — never copy it by hand.
52
98
  `add` refuses a near-twin write and returns the candidates to reconcile
53
99
  against — edit before add, merge near-twins, split a bloated doc into
54
100
  per-topic files.
101
+ - The reconcile applies to a **create**: with `path` omitted, the target is
102
+ derived and the near-twin guard runs. An explicit `path` is the update
103
+ contract and skips it, which is how you replace a doc in place. Passing an
104
+ explicit _new_ path is therefore a deliberate override, not a protected
105
+ write.
106
+ - Near-twins are per lake. The same topic at repo and global scope is
107
+ legitimate; the narrower doc states its delta and links up.
108
+
109
+ ## Focus, ownership and promotion
110
+
111
+ - One question per doc. One topic per doc.
112
+ - More than one H2 aimed at different topics or audiences means split.
113
+ - Never write an omnibus notes doc to avoid choosing a class.
114
+ - The narrowest true scope owns the claim. A broader class owns the general
115
+ rule; the narrower doc states only its delta and links up.
116
+ - Do not copy between knowledge classes. Move or link.
117
+ - Instructions own commands. Knowledge docs own reasons and link to the
118
+ command. Knowledge docs link to the wiki page for human narrative.
119
+ - Wiki duplication is expected, not a defect. If a wiki page drifts from a
120
+ knowledge doc, report it and name both pages; do not edit the wiki.
121
+ - Promotion is a move: the general claim goes up, the local delta stays. Delete
122
+ the emptied doc and repoint every in-repo link. No superseded stubs. An
123
+ unrepointable external link is reported for a human to fix.
124
+ - A soft note appears when a body exceeds `maxDocLines` (default 200,
125
+ configurable). A note, not a refusal. Reference tables are judged by review.
126
+
127
+ ## Safety
128
+
129
+ - No secrets, credentials, tokens, or customer data. Name the vault or variable,
130
+ never the value.
131
+ - No personal data in GlobalContext or Wiki.
132
+ - The wiki profile is read-only to the tool. Its own owners review changes.
55
133
 
56
134
  ## Lifecycle
57
135
 
58
- `Status` and `Supersedes` are load-bearing, not decoration. A doc marked
59
- `Status: superseded` is flagged `(superseded)` in search results and ranks below
60
- an active doc on a tie; `check` flags a `Supersedes` that names no doc in the
61
- tree.
136
+ A doc is current or deleted. Correct a wrong doc by replacing it in place with
137
+ `add` and an explicit `path`. Delete an obsolete doc through the shell with
138
+ explicit approval; there is no `delete` verb. A failed attempt is still valid
139
+ knowledge when it records the outcome and the current truth.
62
140
 
63
141
  ## Adopting it
64
142
 
65
- Run `check` to audit an existing tree, and the gate's `defined comply` before
66
- proposing a commit. A missing docs root is not an error: the plugin scans
67
- what is there and reports per-doc findings for what is not.
143
+ Run `check` to audit an existing tree, and the project's own tests before
144
+ proposing a commit. `add` enforces the per-doc structural rules at the write
145
+ boundary — front-matter, `H1`, claim section, identity term floor, and the
146
+ near-twin guard on a create — while the cross-document audits (near-twin pairs
147
+ and relative links) stay with `check`. A missing lake root is a note, not an
148
+ error: the plugin scans what is there, search and help flag the absent path, and
149
+ `add` refuses rather than creating a tree at a mistyped root. Create the
150
+ directory deliberately. Wiki lakes are read-only and are reported as not
151
+ validated, never silently skipped.
package/README.md CHANGED
@@ -1,28 +1,49 @@
1
1
  # opencode-docs-plugin
2
2
 
3
- An [OpenCode](https://opencode.ai) V2 plugin that gives an agent a knowledge
4
- tree it can actually use: a `docs` tool and a `/docs` command over the
5
- configured docs root's `*.md` files (the `root` plugin option; default
6
- `<location>/docs`), plus nested `README.md` files in the project tree, and the
3
+ An [OpenCode](https://opencode.ai) V2 plugin that gives an agent a set of
4
+ knowledge **lakes** it can actually use: a `docs` tool and a `/docs` command
5
+ over configured Markdown trees, nested `README.md` files in the project, and the
7
6
  writing convention those docs follow.
8
7
 
9
- - `docs` (tool) — blank search lists the 10 most recently changed docs
10
- (`path — Area — date — Summary`); a search ranks docs over their
11
- front-matter, path and body identifiers, falling back to the closest
12
- matches rather than a dead end; `read` returns a matched doc verbatim
13
- (front-matter and body), so find-then-read is one call; `add` writes
14
- knowledge through a typed DTO; `check` validates the tree against the
15
- convention. Nested project `README.md` files are indexed too —
16
- `.gitignore` rules decide what is skipped — but only for search: `add`
17
- and `check` never touch them. A Code Mode twin, `docs_search`, registers
18
- alongside it, so `execute` reaches the same lake as
8
+ Docs are grouped by **class**:
9
+
10
+ | Class | Where | Use it for | Writes |
11
+ | ------------------ | ------------------------------- | --------------------------------------- | ------------- |
12
+ | **Instructions** | nested `README.md` | build, run, test, deploy this code | never |
13
+ | **RepoContext** | `<repo>/docs` by default | this repo's traps, decisions, landmines | yes |
14
+ | **MachineContext** | personal lake, e.g. `~/doclake` | tooling and traps across your machines | yes |
15
+ | **GlobalContext** | organisation lake | standards and integrations across repos | yes, reviewed |
16
+ | **Wiki** | human-readable wiki checkout | narrative for humans | read-only |
17
+
18
+ Place knowledge at the narrowest scope where the whole claim is true. A doc that
19
+ spans scopes is split into focused docs, one per class. The full rulebook is
20
+ [CONVENTION.md](CONVENTION.md); the registered `docs` skill carries the working
21
+ version.
22
+
23
+ ## The tool and command
24
+
25
+ - `docs` (tool) — blank search lists the most recently changed docs
26
+ (`path — Area — date — Summary`); a search ranks docs over their front-matter,
27
+ path and body identifiers (plus wiki prose), falling back to the closest
28
+ matches rather than a dead end; `read` returns a doc verbatim and accepts a
29
+ `lake` or `lake:path`; `add` writes knowledge through a typed DTO; `check`
30
+ validates the knowledge lakes. Nested project `README.md` files are indexed
31
+ too — `.gitignore` rules decide what is skipped — but only for search: `add`
32
+ and `check` never touch them, and their results are prefixed `instructions:`
33
+ and read with the built-in `read` tool. A Code Mode twin, `docs_search`,
34
+ registers alongside it, so `execute` reaches the same lakes as
19
35
  `tools.docs.docs_search(…)`.
20
36
  - `/docs` (command) — the same core, driven from the prompt:
21
37
  `search <text>` (bare text searches too), `add <text>`, `check`, `help`.
22
38
  - The plugin also registers the `docs` skill, so the convention travels with
23
39
  the tool rather than living in always-loaded prose.
24
40
 
25
- Reading a matched doc stays OpenCode's built-in `read`.
41
+ Reading a matched project file stays OpenCode's built-in `read`. The tool's own
42
+ `read` serves lake docs and wiki pages.
43
+
44
+ Every source reserves a few results (default 3 per source) before the rest of
45
+ the cap fills by score, so a broad wiki cannot bury a focused repo doc. The
46
+ cap is 10 results; the cut is counted.
26
47
 
27
48
  ## Installation
28
49
 
@@ -42,41 +63,133 @@ or as a `plugins` entry in `opencode.json(c)` (global, project or `.opencode/`):
42
63
  ```
43
64
 
44
65
  Unpinned entries update on the next server start or `opencode plugin update`;
45
- an exact version (e.g. `@0.2.0`) stays pinned.
66
+ an exact version (e.g. `@0.5.0`) stays pinned.
46
67
 
47
68
  ## Configuration
48
69
 
49
- The docs root defaults to `<location>/docs`. Set the `root` option with the
50
- object form — `~` expands against the home directory, so a global config can
51
- point every project at one shared tree:
70
+ One docs plugin entry, in the global or managed config. **Do not repeat the
71
+ entry at project level**: the same package loads twice and both copies receive
72
+ the project options, losing the base lakes. Add per-repo lakes through the repo
73
+ file instead.
74
+
75
+ The simplest setup uses `root` — one repo lake:
76
+
77
+ ```jsonc
78
+ {
79
+ "plugins": [
80
+ {
81
+ "package": "@markstanden/opencode-docs-plugin",
82
+ "options": {
83
+ "root": "./docs",
84
+ },
85
+ },
86
+ ],
87
+ }
88
+ ```
89
+
90
+ `root` expands `~`, resolves a relative path against the location, and defaults
91
+ to `<location>/docs`. A blank value counts as unset. `root` declares a **repo**
92
+ lake; for a personal or global lake, use `lakes` with the class instead.
93
+
94
+ For several lakes, list them inline, in a base file, or both. The base file is
95
+ usually a personal or managed file; the repo file adds local lakes:
52
96
 
53
97
  ```jsonc
54
98
  {
55
- "$schema": "https://opencode.ai/config.json",
56
99
  "plugins": [
57
100
  {
58
101
  "package": "@markstanden/opencode-docs-plugin",
59
102
  "options": {
60
- "root": "~/doclake",
103
+ "lakesFile": "~/.config/opencode/docs-lakes.json",
104
+ "lakes": [{ "class": "repo", "root": "./docs" }],
105
+ "maxDocLines": 200,
106
+ "perLakeQuota": 3,
61
107
  },
62
108
  },
63
109
  ],
64
110
  }
65
111
  ```
66
112
 
67
- Relative paths resolve against the location's directory; absolute paths pass
68
- through. A blank `root` value counts as unset and uses the default; a
69
- non-string value fails at startup. The root directory itself need not exist in
70
- advance — it is created on the first `add`, and a search or `check` over a
71
- still-empty tree simply reports nothing. Restart OpenCode after editing the
72
- config — it isn't hot-reloaded.
113
+ `~/.config/opencode/docs-lakes.json`:
114
+
115
+ ```jsonc
116
+ {
117
+ "lakes": [
118
+ { "class": "machine", "root": "~/doclake", "name": "doclake" },
119
+ { "class": "global", "root": "~/org-docs", "name": "global" },
120
+ { "class": "wiki", "root": "~/org-wiki", "name": "wiki" },
121
+ ],
122
+ }
123
+ ```
124
+
125
+ A repo adds its own lakes in `.opencode/docs-lakes.json`, checked into the repo:
126
+
127
+ ```jsonc
128
+ {
129
+ "lakes": [
130
+ { "root": "documentation", "name": "docs" },
131
+ { "root": "reference", "name": "reference", "writable": false },
132
+ ],
133
+ }
134
+ ```
135
+
136
+ Repo-file rules:
137
+
138
+ - only `repo` lakes;
139
+ - roots must resolve inside the location;
140
+ - an absent file is ignored; a malformed file fails at startup.
141
+
142
+ A sibling repository's docs belong in the base `lakesFile`, not the repo file.
143
+
144
+ Merge order: base `lakesFile`, repo file, inline `lakes`, then `root`. Duplicate
145
+ lake names fail at startup. If no repo lake is configured, one implicit repo
146
+ lake at `<location>/docs` is added — so a repo needs no lake file unless its
147
+ docs live elsewhere.
148
+
149
+ Lake entries:
150
+
151
+ | Field | Meaning |
152
+ | ---------- | ------------------------------------------------------------------------------------------------ |
153
+ | `class` | `repo`, `machine`, `global` or `wiki`; default `repo`. |
154
+ | `root` | The lake root. Required for `machine`/`global`/`wiki`; defaults to `<location>/docs` for `repo`. |
155
+ | `name` | Lower-case dashes; defaults to the root folder name. `instructions` is reserved. |
156
+ | `writable` | Defaults true for knowledge classes, fixed false for `wiki`. |
157
+
158
+ Lake paths never follow symlinks: a symlinked doc is skipped by search and
159
+ `check`, refused by `read`, and refused by `add`. The configured `root` itself
160
+ may be a symlink; the content beneath it must be real.
161
+
162
+ A missing lake root is flagged, never created. The lake stays dormant until the
163
+ directory exists: `search` appends a note naming the lake and path, `help` marks
164
+ it `— missing`, and `add` refuses with the path rather than bootstrapping a
165
+ tree. Create the directory deliberately. Area folders beneath an existing root
166
+ are still created on write.
167
+
168
+ `maxDocLines` (default 200, `0` disables) is a **soft** note on a long doc, not a
169
+ refusal. `perLakeQuota` (default 3, `0` disables) is the per-source result
170
+ reservation.
171
+
172
+ ## Wiki lakes
173
+
174
+ Wiki pages are read-only reference. They carry no required front-matter: the
175
+ title comes from the H1, the area from the folder, the summary from the first
176
+ prose paragraph, and the date from git. Prose and tables are indexed so a page
177
+ that names an Azure region only in a table is still searchable. Wiki lakes are
178
+ never validated. If a wiki page drifts from a knowledge doc, report it; the
179
+ wiki's owners decide.
180
+
181
+ ## Check
182
+
183
+ `check` validates the knowledge lakes: required front-matter, an H1, at least
184
+ one claim section (`Facts`, `Inferred`, `Tested`, `Failed approaches`,
185
+ `Open questions`), no hand-maintained `Date`, a distinctive H1+Keywords
186
+ identity, same-area near-twins, and broken relative `.md` links. Obsolete
187
+ `Status`/`Supersedes` fields, long docs, and unversioned or missing roots are
188
+ **notes**, not findings. An empty findings list means compliant.
73
189
 
74
- The runtime nudges default on: a one-line pointer appended to the first
75
- grep/glob miss of a session (suggesting a `docs search`), and a record-ready
76
- block format injected into compaction summarisation, so durable findings are
77
- shaped as separate focused docs — one artifact per topic, never a session
78
- dump. Set `"nudge": false` to restore silence; a non-boolean value fails at
79
- startup.
190
+ There is no lifecycle field. A doc is current or deleted; git is the archive.
191
+ Correct a wrong doc by replacing it in place. A failed attempt is valid
192
+ knowledge when it records the outcome and what is true now.
80
193
 
81
194
  ## Status
82
195
 
@@ -88,7 +201,6 @@ Standalone extract of the docs tooling, under active development.
88
201
  npm install
89
202
  npm test # node --test
90
203
  npm run typecheck
91
- defined comply # the gate: bootstrap, repair and verify
92
204
  ```
93
205
 
94
206
  Tests run the plugin source directly under Node's type-stripping (`noEmit`,
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@markstanden/opencode-docs-plugin",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
- "description": "OpenCode V2 plugin: a `docs` tool and `/docs` command over a repository's knowledge tree and the project's nested README.md files (search only), with the writing convention it owns",
5
+ "description": "OpenCode V2 plugin: a `docs` tool and `/docs` command over configurable knowledge lakes (repo, machine, global and read-only wiki), nested README.md search, and the writing convention they share",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/markstanden/opencode-docs-plugin.git"
package/src/SKILL.md CHANGED
@@ -1,100 +1,74 @@
1
1
  # Docs
2
2
 
3
- Durable knowledge lives under the configured docs root (the plugin's `root`
4
- option; default `<location>/docs`). This skill covers both
5
- halves of the loop: **find** (discover with the `docs` tool, read the match) and
6
- **record** (write or update a doc for the current task).
3
+ Durable knowledge lives in **lakes**: **find** it (search, then read), or
4
+ **record** one focused doc at the narrowest true scope. Call the `docs` tool;
5
+ inside `execute` it is `tools.docs.docs_search(…)`, same verbs.
7
6
 
8
- Call the `docs` tool at top level. Inside `execute` (Code Mode) the same tool
9
- is reachable as the twin `tools.docs.docs_search(…)` — same verbs, same lake —
10
- so batch it with the rest of the catalog there.
7
+ ## Classes
8
+
9
+ | Class | Where | Use it for | Writes |
10
+ | ------------------ | --------------------------- | --------------------------------------- | ------------- |
11
+ | **Instructions** | nested `README.md` | build, run, test, deploy this code | never |
12
+ | **RepoContext** | `<repo>/docs` | this repo's traps, decisions, landmines | yes |
13
+ | **MachineContext** | personal lake (`~/doclake`) | tooling and traps across your machines | yes |
14
+ | **GlobalContext** | organisation lake | standards and integrations across repos | yes, reviewed |
15
+ | **Wiki** | human-readable wiki | narrative for humans | read-only |
16
+
17
+ Record at the **narrowest scope where the whole claim is true**. Two scopes
18
+ means two docs; one omnibus doc is out of place everywhere.
11
19
 
12
20
  ## Find it
13
21
 
14
- Call the `docs` tool:
15
-
16
- - **blank `search`** — the most recently changed docs, one line per doc
17
- (`path — Area — date — Summary`).
18
- - **a `search`** — those docs ranked over title, path, keywords, body headings
19
- and code spans, area and summary. When no doc contains every term it returns
20
- the closest matches under a `Closest matches` header rather than a dead end.
21
- A term must appear as a **substring** to match — a typo returns nothing, by
22
- design. Terms shorter than `MIN_TERM_LENGTH` (3) are ignored unless they are
23
- the whole query, so filler words cannot drag in the catalogue.
24
- - **every call** caps at `MAX_RESULTS` (10), preferring the best matches and
25
- then the most recent edits, and ends with `… and N more not shown.` when
26
- anything was cut.
27
- - **exactly `help`** — plain text explaining the weights, the hit qualities and
28
- the outcomes, instead of a search.
29
-
30
- Then open the match: either the built-in `read` tool (project files and
31
- READMEs), or the tool's own `read` verb — pass the root-relative path and it
32
- returns the doc verbatim, front-matter and body, in one call.
33
- `/docs [search]` runs the same search into the session (`/docs search <text>`
34
- is the explicit form).
35
-
36
- Every `*.md` under the root is covered except the excluded areas — scratch (`plans/`)
37
- and vendored mirrors (`requirements/`, `wiki/`). `Area` comes from the path,
38
- `date` from git. A doc marked `Status: superseded` carries a `(superseded)`
39
- marker in results and ranks below an active doc on a tie.
40
-
41
- Search also covers nested `README.md` files in the project tree — the map lives
42
- beside the code. They are indexed as they stand (H1 title, headings, code
43
- spans) and are **search-only**: `add` and `check` never touch them.
44
- `.gitignore` decides which directories are skipped; outside git, dependency and
45
- build directories are skipped by name. The lake root is skipped when it sits
46
- inside the project, since those READMEs are already knowledge docs.
47
-
48
- ## Read it
49
-
50
- - Consult matching docs before a broad grep: they are the curated knowledge.
51
- - A `Summary` is a self-contained sentence — enough to decide whether to open
52
- the file.
22
+ A **blank `search`** lists recent docs, one line each; a **`search`** ranks
23
+ them, falling back to `Closest matches` and matching terms as **substrings** —
24
+ so a typo finds nothing and terms under `MIN_TERM_LENGTH` (3) are ignored.
25
+ `help` lists the lakes and ranking.
26
+
27
+ Open the match with `read`: the root-relative path, or `lake:path` when several
28
+ lakes exist. A README result is `instructions:path` and opens with the built-in
29
+ `read`. Consult matching docs before a broad grep; a tie ranks repo,
30
+ instructions, global, machine, wiki. Excluded areas: `plans/`, `requirements/`
31
+ and `wiki/`.
53
32
 
54
33
  ## Record it
55
34
 
56
- Write durable findings and task documentation to `<area>/<title>.md` under the
57
- root so the
58
- next human or agent skips the rediscovery. The convention is this plugin's
59
- `CONVENTION.md`, restated here.
60
-
61
- Before writing:
62
-
63
- 1. **Read first, never duplicate.** List the tree with the `docs` tool and read
64
- the docs relevant to the task: the same `<area>/` neighbourhood, keyword
65
- hits on the task's entities (service names, file paths, error strings, class
66
- names), or links from touched docs.
67
- 2. **Reconcile, then add.** Edit before add; merge near-twins; split a bloated
68
- doc into per-topic files; after any split, merge or move, grep for inbound
69
- references and repoint them, leaving a stub if needed.
70
-
71
- One artifact per topic: a session's findings land as several focused docs,
72
- never one session dump — a compaction nudge hands you `Record with docs add:`
73
- blocks already shaped for this.
74
-
75
- Then record through the `docs` tool's typed `add`: metadata (`Area`, `Keywords`
76
- as a list, `Summary`; optionally `Status`/`Supersedes`) plus a body carrying an
77
- `H1` and the claim sections (`Facts`, `Inferred`, `Tested`, `Open questions`).
78
- The tool serialises the front-matter — never copy it — and derives
79
- the target (`<Area>/<slug>.md`) when `path` is omitted; pass `path` to
80
- update an existing doc, replacing its body wholesale. Its guardrails refuse
81
- blank metadata, path traversal, a body without an `H1`, and a same-area
82
- near-twin (returning the candidates to reconcile against). A plan for an
83
- in-flight effort is scratch, not a doc — a `plans/` area, excluded from the
84
- index and deleted when the work lands. `/docs add <text>` runs this record
85
- loop for a fact supplied inline.
35
+ Write to `<area>/<title>.md` under the right lake; `CONVENTION.md` is
36
+ authoritative.
37
+
38
+ 1. **Read first, never duplicate.** Read the docs relevant to the task: the same
39
+ area, keyword hits on its entities, or links from touched docs.
40
+ 2. **Choose one class** from the table — the narrowest that holds the claim.
41
+ 3. **Reconcile, then add.** Edit before add; merge near-twins; split a bloated
42
+ doc per topic; after a split, merge or move, repoint inbound references and
43
+ delete the emptied doc — no superseded stubs.
44
+
45
+ One artifact per topic and class, never one dump; the compaction nudge shapes
46
+ `Record with docs add:` blocks for this.
47
+
48
+ Record through the typed `add`: metadata (`Area`, `Keywords`, `Summary`) and a
49
+ body with an `H1` and a claim section — Facts, Inferred, Tested, Failed approaches, Open questions. Omit `path` to create `<Area>/<slug>.md`; pass `path` to replace **wholesale**, so omitted body content is lost and the near-twin reconcile is skipped. Refused: blank metadata, traversal, a non-`.md` or symlinked target, no claim section, and — only when `path` is omitted — a same-area near-twin.
50
+
51
+ A doc is current or deleted; no `Status` or `Supersedes`. A failed attempt is
52
+ valid knowledge when it records what was tried, why it failed, what is true now,
53
+ and what not to retry.
54
+
55
+ Lead with the actionable fact, keeping the reason, limits and evidence that
56
+ affect using it; drop chronology, repeated conclusions and empty sections. Keep
57
+ the service names, errors, paths and commands someone will search for. A
58
+ `Summary` decides whether to open the file.
59
+
60
+ Never record secrets, credentials, tokens or customer data — name the vault or
61
+ variable, never the value — and no personal data in GlobalContext or Wiki.
86
62
 
87
63
  ## Check it
88
64
 
89
- To audit the tree instead of writing it, call the tool's `check` (`/docs check`
90
- runs it into the session): it validates every doc against the convention —
91
- required front-matter, an `H1`, at least one claim section, no hand-maintained
92
- `Date`, an `H1`+`Keywords` identity with a term of `MIN_TERM_LENGTH` (3) or
93
- longer, a `Supersedes` naming a doc in the tree, and same-area near-twins — and
94
- reports findings per doc. An empty report means compliant. `add` enforces the
95
- same rules at the trust boundary.
96
-
97
- Finally, run the repo's gate (`defined comply` where `.defined.json` exists,
98
- else what its README documents) before proposing a commit. Fix failures; never
99
- paper over a red gate with a docs commit. Prepare the commit and **wait for
65
+ `check` audits the lakes: front-matter, an `H1`, a claim section, no
66
+ hand-maintained `Date`, a distinctive identity, near-twins and broken relative
67
+ links. Obsolete fields, long docs and missing roots are **notes**, not findings;
68
+ wiki lakes are not validated. `add` enforces the structural rules at the write
69
+ boundary; cross-document audits stay with `check`. `maxDocLines` (default 200,
70
+ `0` disables) is a soft size signal, not a refusal.
71
+
72
+ Run the project's tests and typecheck before proposing a commit, fixing
73
+ failures rather than papering over them. Prepare the commit and **wait for
100
74
  explicit approval** — recording findings is not commit approval. Never push.