ai-fob 1.3.2 → 1.4.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/README.md +10 -0
- package/assets/agents/wiki-curator-agent.md +46 -0
- package/assets/commands/wiki-ingest.md +349 -0
- package/assets/commands/wiki-init.md +262 -0
- package/assets/commands/wiki-lint.md +385 -0
- package/assets/commands/wiki-query.md +291 -0
- package/assets/skills/llm-wiki/SKILL.md +164 -0
- package/assets/skills/llm-wiki/reference/citation-format.md +120 -0
- package/assets/skills/llm-wiki/reference/ingest-protocol.md +93 -0
- package/assets/skills/llm-wiki/reference/lint-rules.md +104 -0
- package/assets/skills/llm-wiki/reference/query-protocol.md +93 -0
- package/assets/skills/llm-wiki/reference/schema-design.md +116 -0
- package/assets/skills/llm-wiki/reference/trust-tiers.md +97 -0
- package/assets/skills/llm-wiki/templates/page-template.md +40 -0
- package/assets/skills/llm-wiki/templates/schema-template.md +54 -0
- package/assets/skills/llm-wiki/templates/source-frontmatter.md +35 -0
- package/assets/supporting/hooks/branch-protect-warn.sh +46 -0
- package/assets/supporting/settings.json +11 -0
- package/bin/install.js +2 -1
- package/manifest.json +19 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -59,6 +59,16 @@ Tools for building Claude Code primitives (skills, agents, commands).
|
|
|
59
59
|
|
|
60
60
|
**Commands:** plan-cc-assets-phases, build-cc-assets-phases
|
|
61
61
|
|
|
62
|
+
### llm-wiki
|
|
63
|
+
|
|
64
|
+
A domain-agnostic, citation-backed wiki maintained by an LLM curator. Scaffold with `/wiki-init`, populate with `/wiki-ingest`, read with `/wiki-query`, and enforce integrity with `/wiki-lint`. Based on Karpathy's LLM Wiki pattern.
|
|
65
|
+
|
|
66
|
+
**Skills:** llm-wiki, brainstorm-plan
|
|
67
|
+
|
|
68
|
+
**Agents:** wiki-curator
|
|
69
|
+
|
|
70
|
+
**Commands:** wiki-init, wiki-ingest, wiki-query, wiki-lint
|
|
71
|
+
|
|
62
72
|
### all
|
|
63
73
|
|
|
64
74
|
Everything from both presets.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wiki-curator-agent
|
|
3
|
+
description: >
|
|
4
|
+
LLM wiki curator. Writes wiki content only from cited ingested sources; never
|
|
5
|
+
infers from training data. Use when invoked by /wiki-ingest, /wiki-query, or
|
|
6
|
+
/wiki-lint.
|
|
7
|
+
model: opus
|
|
8
|
+
color: cyan
|
|
9
|
+
tools: Read, Write, Edit, Grep, Glob
|
|
10
|
+
permissionMode: acceptEdits
|
|
11
|
+
skills:
|
|
12
|
+
- llm-wiki
|
|
13
|
+
- brainstorm-plan
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Wiki Curator Agent
|
|
17
|
+
|
|
18
|
+
## Purpose
|
|
19
|
+
|
|
20
|
+
You are the LLM wiki curator. You maintain a citation-backed knowledge base from ingested sources — building and querying a three-layer wiki (sources, pages, schema) that reflects exactly what has been ingested, nothing more.
|
|
21
|
+
|
|
22
|
+
## Core Principle — Sources Only — Cite or Abstain
|
|
23
|
+
|
|
24
|
+
You draw exclusively from files under `sources/`. You never supplement from training data, never infer missing facts, and never fill gaps silently. If the wiki does not contain the information a caller asks about, you say so explicitly with a `(Gap)` marker. An uncited factual claim is a protocol violation. When in doubt, cite or abstain.
|
|
25
|
+
|
|
26
|
+
## Domain Knowledge
|
|
27
|
+
|
|
28
|
+
Your domain knowledge lives in the `llm-wiki` skill — it defines the three-layer wiki model, the five operating modes, the citation format, trust tiers, gap handling, contradiction handling, and the lint rule catalog. Consult `brainstorm-plan` when proposing structure during first-run ingest or when triaging lint findings that require judgment calls.
|
|
29
|
+
|
|
30
|
+
## Task from Caller
|
|
31
|
+
|
|
32
|
+
Your specific task for this invocation is defined by the prompt you receive from the calling command. Typical modes are the five canonical operating modes from `llm-wiki`: `ingest-propose`, `ingest-execute`, `query`, `lint-detect`, `lint-apply`. The calling command supplies the mode name and any mode-specific arguments; consult `llm-wiki` for the behavior of each mode.
|
|
33
|
+
|
|
34
|
+
## Output Conventions
|
|
35
|
+
|
|
36
|
+
- Return structured output the calling command can parse — plain text with clear section headers, bullet lists, or fenced blocks as the mode requires.
|
|
37
|
+
- Never prompt the user. `AskUserQuestion` is not in your tool allowlist, and interactive gating is a command-layer concern, not a curator concern.
|
|
38
|
+
- When information is missing, ambiguous, or contradicted, surface it to the caller using the `(Gap)` marker or a flagged note — let the command decide whether to block, escalate, or proceed.
|
|
39
|
+
- Every factual claim in your output must carry a citation in the canonical `llm-wiki` format. If you cannot cite, abstain and mark it `(Gap)`.
|
|
40
|
+
- When a source file is missing required frontmatter fields or is otherwise malformed, report the defect to the caller by name rather than proceeding with partial data or guessing the missing values.
|
|
41
|
+
- When a single source contains contradictory claims, record both verbatim with citations and flag the conflict for the caller; do not pick a winner silently.
|
|
42
|
+
- Prefer updating an existing page over creating a new one when the topic matches an existing schema page type — creation should be reserved for topics with no structural home.
|
|
43
|
+
|
|
44
|
+
## Completion Reports
|
|
45
|
+
|
|
46
|
+
When your mode involves writing files, return a short completion report to the calling command listing: files touched (with paths), claims extracted or cited (with source slugs), gaps surfaced, and any defects encountered during the run. Keep it concise — the calling command is responsible for rendering it to the user.
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Ingest text or a markdown/text file into the wiki, extracting per-claim citations.
|
|
3
|
+
argument-hint: <text or file path>
|
|
4
|
+
model: opus
|
|
5
|
+
allowed-tools: Skill, Agent(wiki-curator-agent), Read, Write, Edit, Grep, Glob, Bash(ls:*), AskUserQuestion
|
|
6
|
+
disable-model-invocation: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /wiki-ingest
|
|
10
|
+
|
|
11
|
+
Ingest the provided content (inline text or a file path passed as `$ARGUMENTS`) into the project's `llm-wiki`. The main agent orchestrates the `wiki-curator-agent`, which performs all file writes. On first run (placeholder schema present) the flow is propose → approve → execute with an `AskUserQuestion` confirmation gate. On subsequent runs the flow is a single-shot ingest. The main agent only reads (preflight + read-back verification) and asks the user for approval; all writes occur inside the curator subagent.
|
|
12
|
+
|
|
13
|
+
Conventions referenced below:
|
|
14
|
+
|
|
15
|
+
- `$ARGUMENTS` — the full string after `/wiki-ingest`. May be inline text or a file path.
|
|
16
|
+
- `SENTINEL` — the literal substring `Schema not yet populated` (matched in `schema.md` to detect first-run mode).
|
|
17
|
+
- `SCAFFOLD_FILES` — the set `{schema.md, index.md, log.md}` checked at preflight.
|
|
18
|
+
- `MAX_PROPOSAL_ITERATIONS` — `3` (the loop cap for `edit-first` feedback rounds).
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Step 1: Parse and Validate Argument
|
|
23
|
+
|
|
24
|
+
Parse `$ARGUMENTS`:
|
|
25
|
+
|
|
26
|
+
1. If `$ARGUMENTS` is empty or whitespace-only, abort with the message:
|
|
27
|
+
> Cannot ingest: no content provided. Usage: `/wiki-ingest <inline text or file path>`.
|
|
28
|
+
2. Otherwise, attempt to detect whether `$ARGUMENTS` is a file path. Use the Bash tool to run `ls -- "$ARGUMENTS"`. If the command exits 0 and the path resolves to a regular file, set `MODE_INPUT = path` and read the file with the Read tool to obtain `RAW_CONTENT`. If `ls` errors or the path does not exist, set `MODE_INPUT = inline` and use `$ARGUMENTS` directly as `RAW_CONTENT`.
|
|
29
|
+
3. If `MODE_INPUT = path` but the Read tool returns empty contents, abort with:
|
|
30
|
+
> File `<path>` exists but is empty. Cannot ingest empty content.
|
|
31
|
+
|
|
32
|
+
**Edge case policy — ambiguous string that looks like a path but is unreadable:** If `$ARGUMENTS` looks like a path (contains `/` or ends in `.md`, `.txt`) but `ls` fails, abort with:
|
|
33
|
+
|
|
34
|
+
> Argument looks like a file path but cannot be read: `<arg>`. Either fix the path or pass inline text without a leading slash.
|
|
35
|
+
|
|
36
|
+
This avoids silently treating `./missing.md` as the literal string `./missing.md` and writing nonsense into the wiki.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Step 2: Preflight — Wiki Scaffold Present
|
|
41
|
+
|
|
42
|
+
Read each of the following files using the Read tool, in order:
|
|
43
|
+
|
|
44
|
+
1. `schema.md`
|
|
45
|
+
2. `index.md`
|
|
46
|
+
3. `log.md`
|
|
47
|
+
|
|
48
|
+
If any read fails, abort with:
|
|
49
|
+
|
|
50
|
+
> Wiki scaffold is missing or incomplete (`<filename>` not found). Run `/wiki-init` first to scaffold the wiki, then re-run this command.
|
|
51
|
+
|
|
52
|
+
Do not attempt to read `sources/` or `pages/` here — they are conventionally directories and may be empty on first run.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Step 3: Detect Mode (first-run vs steady-state)
|
|
57
|
+
|
|
58
|
+
Inspect the contents of `schema.md` (already read in Step 2). If the file contains the substring `Schema not yet populated`, set `MODE = first-run`. Otherwise set `MODE = steady-state`.
|
|
59
|
+
|
|
60
|
+
The exact sentinel line written by `/wiki-init` is:
|
|
61
|
+
|
|
62
|
+
> `_Schema not yet populated. Run `/wiki-ingest <text-or-path>` to seed it._`
|
|
63
|
+
|
|
64
|
+
Match the substring `Schema not yet populated` (case-sensitive); this is robust to minor whitespace or markdown reflow but will not false-positive against a real, populated schema (which would not include that phrase).
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Step 4: Load the `llm-wiki` Skill
|
|
69
|
+
|
|
70
|
+
Invoke the `llm-wiki` skill via the Skill tool to load wiki protocols (frozen citation format, source frontmatter contract, mode-name contract, gap-marker convention) into the main context. Use the exact invocation:
|
|
71
|
+
|
|
72
|
+
> Skill: `llm-wiki`
|
|
73
|
+
|
|
74
|
+
This must happen before spawning the curator so that the main agent can correctly interpret the curator's structured reports and verify frontmatter on read-back.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Step 5: Branch on Mode
|
|
79
|
+
|
|
80
|
+
### Step 5a: First-Run Branch (propose → approve → execute)
|
|
81
|
+
|
|
82
|
+
This branch runs only when `MODE = first-run`.
|
|
83
|
+
|
|
84
|
+
#### Step 5a.i: Spawn curator in `ingest-propose` mode
|
|
85
|
+
|
|
86
|
+
Use the Agent tool to spawn `wiki-curator-agent` with `subagent_type: "wiki-curator-agent"`. The prompt body must be **exactly** the following block (substitute `<RAW_CONTENT>` with the verbatim content captured in Step 1; do not summarize or trim):
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Mode: ingest-propose
|
|
90
|
+
|
|
91
|
+
Task: Analyze the following content and propose a wiki schema for a brand-new wiki being seeded by this content.
|
|
92
|
+
|
|
93
|
+
Content:
|
|
94
|
+
<RAW_CONTENT>
|
|
95
|
+
|
|
96
|
+
Return a structured proposal as Markdown with these top-level sections, in order:
|
|
97
|
+
|
|
98
|
+
## Page Types
|
|
99
|
+
List the page types you propose (e.g., Concept, Study, Method, Person). For each, give a one-line description of what belongs on that page type.
|
|
100
|
+
|
|
101
|
+
## Section Conventions
|
|
102
|
+
For each page type, list the canonical section headings new pages of that type should use.
|
|
103
|
+
|
|
104
|
+
## Linking Rules
|
|
105
|
+
Describe how pages should cross-link (e.g., wikilinks on first mention; `See also` section at page bottom).
|
|
106
|
+
|
|
107
|
+
## Trust Tiers
|
|
108
|
+
Propose a trust-tier set with at least three tiers. For each tier, give the tier name and a one-line description of what kinds of sources qualify.
|
|
109
|
+
|
|
110
|
+
## First Page Preview
|
|
111
|
+
Show the full text of the first page you would write from the supplied content, including frontmatter and per-claim citations in the canonical format `[claim text] ([source-slug], [trust-tier])`.
|
|
112
|
+
|
|
113
|
+
CONSTRAINTS:
|
|
114
|
+
- Do NOT write any files. This is a proposal only.
|
|
115
|
+
- Do NOT fill gaps from training data. If the content does not support a section, leave it empty and mark with `(Gap)`.
|
|
116
|
+
- Draw exclusively from the supplied content for all claims and examples.
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### Step 5a.ii: Receive and parse the proposal
|
|
120
|
+
|
|
121
|
+
The curator returns its proposal as its final assistant message (free-form Markdown). The main agent reads it as the agent-tool result. Validate the result has all five required headings (`## Page Types`, `## Section Conventions`, `## Linking Rules`, `## Trust Tiers`, `## First Page Preview`).
|
|
122
|
+
|
|
123
|
+
**Edge case — malformed proposal (missing required section):** If any required heading is missing, re-spawn the curator (still `Mode: ingest-propose`) with an appended note:
|
|
124
|
+
|
|
125
|
+
> Your previous proposal was missing the following required section(s): `<list>`. Please return a complete proposal including all five required sections.
|
|
126
|
+
|
|
127
|
+
Allow at most **one** correction re-spawn for malformedness. If the second proposal is still malformed, abort with:
|
|
128
|
+
|
|
129
|
+
> Curator returned a malformed proposal twice. Aborting first-run setup. Try re-running with different content or check the curator agent definition.
|
|
130
|
+
|
|
131
|
+
#### Step 5a.iii: Present proposal via `AskUserQuestion`
|
|
132
|
+
|
|
133
|
+
**CONFIRMATION GATE.** This is the critical confirmation gate — `AskUserQuestion` MUST be called from the command layer, never inside the curator (the tool is currently broken in subagent contexts per docs research, GitHub issue #34592).
|
|
134
|
+
|
|
135
|
+
Use a single `AskUserQuestion` call with the following exact shape:
|
|
136
|
+
|
|
137
|
+
- **questions** array of length 1
|
|
138
|
+
- **question:** `The wiki curator proposed the schema below. How would you like to proceed?\n\n<full proposal text from Step 5a.ii>`
|
|
139
|
+
- **header:** `Schema Proposal`
|
|
140
|
+
- **multiSelect:** `false`
|
|
141
|
+
- **options:**
|
|
142
|
+
1. `label: "Approve as proposed"` — `description: "Use this schema as-is and proceed to execute the first ingest."`
|
|
143
|
+
2. `label: "Edit first"` — `description: "Provide feedback and have the curator regenerate the proposal."`
|
|
144
|
+
3. `label: "Abort"` — `description: "Cancel this ingest. No files will be written."`
|
|
145
|
+
|
|
146
|
+
#### Step 5a.iv: Branch on the user's choice
|
|
147
|
+
|
|
148
|
+
- **Approve as proposed** → store the proposal text as `APPROVED_SCHEMA` and proceed to Step 5a.vi.
|
|
149
|
+
- **Abort** → print `Ingest aborted. No files were written.` and exit cleanly. Do not write to `log.md`.
|
|
150
|
+
- **Edit first** → proceed to Step 5a.v.
|
|
151
|
+
|
|
152
|
+
#### Step 5a.v: Edit-first feedback loop
|
|
153
|
+
|
|
154
|
+
Issue a follow-up `AskUserQuestion` call to capture free-text feedback:
|
|
155
|
+
|
|
156
|
+
- **questions** array of length 1
|
|
157
|
+
- **question:** `What would you like the curator to change about the proposed schema? (Provide concrete instructions; the curator will regenerate the full proposal.)`
|
|
158
|
+
- **header:** `Schema Feedback`
|
|
159
|
+
- **multiSelect:** `false`
|
|
160
|
+
- **options:**
|
|
161
|
+
1. `label: "Provide feedback"` — `description: "Type instructions in the follow-up text field."`
|
|
162
|
+
2. `label: "Cancel and abort"` — `description: "Stop the ingest with no files written."`
|
|
163
|
+
|
|
164
|
+
If the user selects `Cancel and abort`, exit as in Step 5a.iv.
|
|
165
|
+
|
|
166
|
+
If the user provides feedback, re-spawn the curator in `ingest-propose` mode with the same prompt as Step 5a.i, but append:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
USER FEEDBACK ON PRIOR PROPOSAL:
|
|
170
|
+
<verbatim user feedback>
|
|
171
|
+
|
|
172
|
+
Please regenerate the full proposal incorporating this feedback while still following all five required sections and the constraints above.
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
After the regenerated proposal returns, loop back to Step 5a.iii (present and ask).
|
|
176
|
+
|
|
177
|
+
**Loop cap:** Track an iteration counter starting at `1` for the initial proposal. After `MAX_PROPOSAL_ITERATIONS = 3` rounds (i.e., the third proposal still gets `Edit first`), force a final choice with the `AskUserQuestion` options reduced to `Approve as proposed` and `Abort` only, and skip `Edit first`. The follow-up question text should explain:
|
|
178
|
+
|
|
179
|
+
> The proposal has been revised three times. Please choose to approve the current version or abort.
|
|
180
|
+
|
|
181
|
+
#### Step 5a.vi: Spawn curator in `ingest-execute` mode (first-run)
|
|
182
|
+
|
|
183
|
+
Use the Agent tool to spawn `wiki-curator-agent` with `subagent_type: "wiki-curator-agent"`. The prompt body must be **exactly** the following block, with substitutions:
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
Mode: ingest-execute (first-run)
|
|
187
|
+
|
|
188
|
+
Approved schema:
|
|
189
|
+
<APPROVED_SCHEMA>
|
|
190
|
+
|
|
191
|
+
Content:
|
|
192
|
+
<RAW_CONTENT>
|
|
193
|
+
|
|
194
|
+
Task:
|
|
195
|
+
1. Write `schema.md` using the approved schema. Replace the existing placeholder. The file MUST contain top-level sections matching the approved schema's Page Types, Section Conventions, Linking Rules, and Trust Tiers (minimum three tiers).
|
|
196
|
+
2. Create `sources/<slug>.md` with frontmatter `{type, origin, ingested-date, trust-tier}` (all four fields required, no missing values). Choose `<slug>` as a kebab-case derivative of the source's title or origin. Set `ingested-date` to today's date in ISO 8601 (YYYY-MM-DD).
|
|
197
|
+
3. Create the corresponding page(s) under `pages/`. Every factual sentence on a page MUST carry an inline citation in the canonical format `[claim text] ([source-slug], [trust-tier])` linked to `sources/<slug>.md`. Each new page MUST end with an empty `## My Notes` section.
|
|
198
|
+
4. Append an entry to `log.md` recording today's ISO date, the source slug, and a one-line summary of what was ingested.
|
|
199
|
+
5. Update `index.md` to reference the new page(s).
|
|
200
|
+
|
|
201
|
+
Return a completion report with these labelled fields:
|
|
202
|
+
- Files written: <list of paths>
|
|
203
|
+
- Source slug(s): <slug>
|
|
204
|
+
- Pages created: <list>
|
|
205
|
+
- Pages updated: <list, or `none`>
|
|
206
|
+
- Claims extracted: <count>
|
|
207
|
+
- Gaps surfaced: <list, or `none`>
|
|
208
|
+
- Defects detected: <list, or `none`>
|
|
209
|
+
|
|
210
|
+
CONSTRAINTS:
|
|
211
|
+
- Draw EXCLUSIVELY from the supplied Content. Do NOT fill gaps from training data. If a claim cannot be supported by the supplied content, omit it or mark `(Gap)`.
|
|
212
|
+
- An uncited factual sentence is a defect. Re-check before returning.
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
#### Step 5a.vii: Receive completion report
|
|
216
|
+
|
|
217
|
+
Parse the curator's labelled fields. Capture `Files written`, `Source slug(s)`, `Pages created`, `Pages updated`, `Claims extracted`, `Gaps surfaced`, `Defects detected`. Proceed to Step 6.
|
|
218
|
+
|
|
219
|
+
### Step 5b: Steady-State Branch (single-shot)
|
|
220
|
+
|
|
221
|
+
This branch runs only when `MODE = steady-state`.
|
|
222
|
+
|
|
223
|
+
#### Step 5b.i: Spawn curator in `ingest-execute` mode (steady-state)
|
|
224
|
+
|
|
225
|
+
Use the Agent tool to spawn `wiki-curator-agent` with `subagent_type: "wiki-curator-agent"`. The prompt body must be **exactly** the following block, with substitutions (substitute `<CURRENT_SCHEMA>` with the full text of `schema.md` read in Step 2):
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
Mode: ingest-execute (steady-state)
|
|
229
|
+
|
|
230
|
+
Current schema:
|
|
231
|
+
<CURRENT_SCHEMA>
|
|
232
|
+
|
|
233
|
+
Content:
|
|
234
|
+
<RAW_CONTENT>
|
|
235
|
+
|
|
236
|
+
Task: Ingest the supplied Content into the existing schema with per-claim citations.
|
|
237
|
+
|
|
238
|
+
1. Determine which page type(s) from the current schema apply to this content.
|
|
239
|
+
2. Extract per-claim citations in the canonical format `[claim text] ([source-slug], [trust-tier])`.
|
|
240
|
+
3. Write `sources/<slug>.md` with frontmatter `{type, origin, ingested-date, trust-tier}` (all four required). Use today's ISO date for `ingested-date`. Pick a kebab-case slug.
|
|
241
|
+
4. Update existing pages where they cover the same topic; create new pages only when no existing page applies. Each new page MUST end with an empty `## My Notes` section. Preserve existing `## My Notes` content on updates.
|
|
242
|
+
5. Append an entry to `log.md` recording today's ISO date, the source slug, and a one-line summary.
|
|
243
|
+
6. Update `index.md` to reference any new page(s).
|
|
244
|
+
|
|
245
|
+
Edge cases:
|
|
246
|
+
- If the new content contradicts an existing claim, record BOTH claims side-by-side with a contradiction flag. Do NOT reconcile, choose, or remove.
|
|
247
|
+
- If the content has gaps the existing schema expects to be filled, mark the gaps inline with `(Gap)` and append an entry to `gaps.md`.
|
|
248
|
+
|
|
249
|
+
Return a completion report with these labelled fields:
|
|
250
|
+
- Files written: <list of paths>
|
|
251
|
+
- Source slug(s): <slug>
|
|
252
|
+
- Pages created: <list, or `none`>
|
|
253
|
+
- Pages updated: <list, or `none`>
|
|
254
|
+
- Claims extracted: <count>
|
|
255
|
+
- Contradictions recorded: <list, or `none`>
|
|
256
|
+
- Gaps surfaced: <list, or `none`>
|
|
257
|
+
- Defects detected: <list, or `none`>
|
|
258
|
+
|
|
259
|
+
CONSTRAINTS:
|
|
260
|
+
- Draw EXCLUSIVELY from the supplied Content. Do NOT fill gaps from training data.
|
|
261
|
+
- An uncited factual sentence is a defect. Re-check before returning.
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### Step 5b.ii: Receive completion report
|
|
265
|
+
|
|
266
|
+
Parse as in Step 5a.vii. Proceed to Step 6.
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Step 6: Read-Back Verification
|
|
271
|
+
|
|
272
|
+
Re-read the new `sources/*.md` file(s) listed in the curator's `Files written` field using the Read tool. For each new source file:
|
|
273
|
+
|
|
274
|
+
1. Verify the frontmatter exists and contains all four required keys: `type`, `origin`, `ingested-date`, `trust-tier`. None may be missing or empty.
|
|
275
|
+
2. Verify `ingested-date` parses as ISO 8601 (YYYY-MM-DD).
|
|
276
|
+
|
|
277
|
+
**On verification failure:**
|
|
278
|
+
|
|
279
|
+
- If a key is missing or empty, surface to the user with:
|
|
280
|
+
> Curator wrote `sources/<slug>.md` but the frontmatter is incomplete. Missing or empty: `<list>`. Re-run `/wiki-lint` after fixing, or edit the file manually.
|
|
281
|
+
- If `ingested-date` is malformed, surface:
|
|
282
|
+
> `sources/<slug>.md` has a malformed `ingested-date` (`<value>`). Expected ISO 8601 (YYYY-MM-DD).
|
|
283
|
+
- If the curator's report claims a file was written but Read returns "file not found," surface:
|
|
284
|
+
> Curator reported writing `<path>` but the file does not exist. The ingest is incomplete. Inspect the curator log and consider re-running.
|
|
285
|
+
|
|
286
|
+
Do NOT auto-correct. Surface and let the user decide.
|
|
287
|
+
|
|
288
|
+
Optionally, perform a light read-back on `index.md` and `log.md` to confirm the new entries appear (search for the new source slug). If absent, surface:
|
|
289
|
+
|
|
290
|
+
> Curator reported updating `<index.md|log.md>` but the new source slug `<slug>` was not found in the file. Inspect manually.
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## Step 7: Print Final Summary
|
|
295
|
+
|
|
296
|
+
Emit a structured summary to the user. The format:
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
Ingest complete (mode: <first-run|steady-state>).
|
|
300
|
+
|
|
301
|
+
Source: <slug>
|
|
302
|
+
Path: sources/<slug>.md
|
|
303
|
+
Trust tier: <tier>
|
|
304
|
+
|
|
305
|
+
Pages created: <list, or "none">
|
|
306
|
+
Pages updated: <list, or "none">
|
|
307
|
+
Claims extracted: <count>
|
|
308
|
+
|
|
309
|
+
Log entry: appended to log.md (date <YYYY-MM-DD>)
|
|
310
|
+
Index: updated
|
|
311
|
+
|
|
312
|
+
[If first-run:]
|
|
313
|
+
Schema: written to schema.md (page types: <list>; trust tiers: <count>)
|
|
314
|
+
|
|
315
|
+
[If contradictions or gaps:]
|
|
316
|
+
Contradictions recorded: <list>
|
|
317
|
+
Gaps surfaced: <list> (also appended to gaps.md)
|
|
318
|
+
|
|
319
|
+
[If defects:]
|
|
320
|
+
Defects detected: <list>
|
|
321
|
+
Action: review the affected files and re-run /wiki-lint.
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
If the curator returned defects or the read-back surfaced issues, end the summary with:
|
|
325
|
+
|
|
326
|
+
> Status: completed-with-warnings. Review surfaced issues above before continuing.
|
|
327
|
+
|
|
328
|
+
Otherwise:
|
|
329
|
+
|
|
330
|
+
> Status: completed.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Error-Handling Policy Matrix
|
|
335
|
+
|
|
336
|
+
| Failure mode | Detection point | Policy |
|
|
337
|
+
|---|---|---|
|
|
338
|
+
| Empty `$ARGUMENTS` | Step 1 | Abort with usage message. |
|
|
339
|
+
| Argument looks like path but unreadable | Step 1 | Abort with explicit "looks like path" message. |
|
|
340
|
+
| File path exists but is empty | Step 1 | Abort with empty-file message. |
|
|
341
|
+
| `schema.md`/`index.md`/`log.md` missing | Step 2 | Abort; instruct to run `/wiki-init`. |
|
|
342
|
+
| Curator returns malformed proposal | Step 5a.ii | Re-spawn once with correction note; if still malformed, abort. |
|
|
343
|
+
| User selects `Abort` at gate | Step 5a.iii or Step 5a.v | Print abort message; no writes. |
|
|
344
|
+
| `Edit first` loop exceeds 3 iterations | Step 5a.v | Force final approve-or-abort question. |
|
|
345
|
+
| Curator reports a file but file doesn't exist | Step 6 | Surface; do not silently succeed. |
|
|
346
|
+
| Source frontmatter incomplete on read-back | Step 6 | Surface specific missing fields; do not auto-fix. |
|
|
347
|
+
| `ingested-date` malformed | Step 6 | Surface. |
|
|
348
|
+
| Curator reports defects in completion report | Step 7 | Include in summary; mark `completed-with-warnings`. |
|
|
349
|
+
| `index.md`/`log.md` not updated despite report | Step 6 | Surface as warning. |
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scaffold a new LLM wiki in the current project (sources/, pages/, schema.md placeholder, index.md, log.md, gaps.md).
|
|
3
|
+
argument-hint: (no arguments)
|
|
4
|
+
model: opus
|
|
5
|
+
allowed-tools: Skill(llm-wiki), Read, Write, Bash(mkdir:*), AskUserQuestion
|
|
6
|
+
disable-model-invocation: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Wiki Init
|
|
10
|
+
|
|
11
|
+
Scaffold the minimal on-disk structure that the `llm-wiki` preset requires: two directories (`sources/`, `pages/`) and four state files (`schema.md`, `index.md`, `log.md`, `gaps.md`) at the project root.
|
|
12
|
+
|
|
13
|
+
**Required Skill**: Before starting Step 3, invoke the `llm-wiki` skill using the Skill tool to load the three-layer wiki model and scaffold-file conventions.
|
|
14
|
+
|
|
15
|
+
## Workflow
|
|
16
|
+
|
|
17
|
+
1. **Preflight — detect existing wiki artifacts.**
|
|
18
|
+
|
|
19
|
+
Check the current working directory for each of the six scaffold targets:
|
|
20
|
+
|
|
21
|
+
- `sources/` (directory)
|
|
22
|
+
- `pages/` (directory)
|
|
23
|
+
- `schema.md` (file)
|
|
24
|
+
- `index.md` (file)
|
|
25
|
+
- `log.md` (file)
|
|
26
|
+
- `gaps.md` (file)
|
|
27
|
+
|
|
28
|
+
For each file target that exists, use `Read` to open it and confirm the first non-blank line is a recognizable wiki header (e.g., `# Schema`, `# Wiki Index`, `# Ingest Log`, `# Open Gaps`, or one of the placeholder sentinels defined in the State File Content section below). This Read is defensive: if a file at `schema.md` exists but starts with something completely unrelated (e.g., a Convex schema file unrelated to wikis), treat it as an "unknown artifact" — count it toward `SCAFFOLD_STATE` but mention it in the subsequent AskUserQuestion text so the user can make an informed choice. Do NOT overwrite silently.
|
|
29
|
+
|
|
30
|
+
Directories do not need to be Read; presence-check only.
|
|
31
|
+
|
|
32
|
+
Classify `SCAFFOLD_STATE`:
|
|
33
|
+
|
|
34
|
+
- All six present → `FULL`.
|
|
35
|
+
- None present → `NONE`.
|
|
36
|
+
- Any other combination → `PARTIAL`.
|
|
37
|
+
|
|
38
|
+
2. **Branch on preflight.**
|
|
39
|
+
|
|
40
|
+
- If `SCAFFOLD_STATE == NONE` → set `WRITE_MODE = FRESH` and proceed directly to Step 3 with no user prompt.
|
|
41
|
+
- If `SCAFFOLD_STATE == PARTIAL` → invoke `AskUserQuestion` with the PARTIAL specification below.
|
|
42
|
+
- If `SCAFFOLD_STATE == FULL` → invoke `AskUserQuestion` with the FULL specification below.
|
|
43
|
+
|
|
44
|
+
`WRITE_MODE` takes one of two values:
|
|
45
|
+
|
|
46
|
+
- `FRESH` — overwrite any matching files without further prompting. Used when `SCAFFOLD_STATE == NONE` or when the user picks `Overwrite all`.
|
|
47
|
+
- `FILL_GAPS` — write only files that do not already exist. Used when the user picks `Complete scaffold`.
|
|
48
|
+
|
|
49
|
+
**PARTIAL branch.** If any wiki artifacts exist but not all, use `AskUserQuestion` to present three options: `Complete scaffold (Recommended)` — fill in missing pieces while preserving everything that exists; `Overwrite all` — destructively rewrite `schema.md`, `index.md`, `log.md`, `gaps.md`; `Abort` — exit without changes. Set `header: "Partial Wiki"` and `multiSelect: false`. Include in the question text the list of artifacts detected in Step 1 so the user sees exactly what is already on disk. Proceed based on the selection:
|
|
50
|
+
|
|
51
|
+
- `Complete scaffold (Recommended)` → `WRITE_MODE = FILL_GAPS` and continue to Step 3.
|
|
52
|
+
- `Overwrite all` → `WRITE_MODE = FRESH` and continue to Step 3.
|
|
53
|
+
- `Abort` → print the abort line from the Report Format section and stop. No further tool calls.
|
|
54
|
+
|
|
55
|
+
**FULL branch.** If all six wiki targets exist, use `AskUserQuestion` to present two options: `Abort (Recommended)` — exit without changes; `Overwrite all` — destructively rewrite the four state files. Set `header: "Full Wiki"` and `multiSelect: false`. Proceed based on the selection:
|
|
56
|
+
|
|
57
|
+
- `Abort (Recommended)` → print the abort line and stop.
|
|
58
|
+
- `Overwrite all` → `WRITE_MODE = FRESH` and continue to Step 3.
|
|
59
|
+
|
|
60
|
+
If `AskUserQuestion` returns the auto-added `Other` option in either branch, treat it as an implicit abort: print the abort line and stop. Do NOT attempt to interpret custom input in this command.
|
|
61
|
+
|
|
62
|
+
3. **Invoke the `llm-wiki` skill.**
|
|
63
|
+
|
|
64
|
+
**Invoke the `llm-wiki` skill using the Skill tool.**
|
|
65
|
+
|
|
66
|
+
This loads the three-layer wiki model (`sources/`, `pages/`, `schema.md`) and the scaffold-file conventions into the main agent's context. The Skill tool's `command` parameter takes the skill name only — no arguments.
|
|
67
|
+
|
|
68
|
+
Step 3 happens AFTER the preflight branching so that if the user aborts in Step 2, no Skill-tool round-trip is wasted.
|
|
69
|
+
|
|
70
|
+
4. **Create directories.**
|
|
71
|
+
|
|
72
|
+
Run a single `Bash` call:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
mkdir -p sources pages
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`-p` makes the command idempotent (no error if the directories already exist), which is safe for both `FRESH` and `FILL_GAPS` modes. The `Bash(mkdir:*)` permission pre-approves `mkdir` with any trailing arguments.
|
|
79
|
+
|
|
80
|
+
If `mkdir` fails (e.g., target path not writable), abort the command and print:
|
|
81
|
+
|
|
82
|
+
> Failed to create sources/ or pages/ at <cwd>. Check filesystem permissions. No state files were written.
|
|
83
|
+
|
|
84
|
+
Do not proceed to Step 5.
|
|
85
|
+
|
|
86
|
+
5. **Write state files.**
|
|
87
|
+
|
|
88
|
+
For each of `schema.md`, `index.md`, `log.md`, `gaps.md` (in that fixed order), evaluate `WRITE_MODE`:
|
|
89
|
+
|
|
90
|
+
- If `WRITE_MODE == FRESH` → Write the file (creating or overwriting).
|
|
91
|
+
- If `WRITE_MODE == FILL_GAPS` → if the file already exists (per Step 1 detection), skip it; otherwise Write.
|
|
92
|
+
|
|
93
|
+
Use the exact literal content from the [State File Content](#state-file-content) section below. Each Write uses the `Write` tool with a path relative to cwd (e.g., `schema.md`, not `./schema.md`).
|
|
94
|
+
|
|
95
|
+
If any Write fails, abort immediately and print:
|
|
96
|
+
|
|
97
|
+
> Failed to write <filename>. Partial scaffold state left on disk: <list of files successfully written before the failure>. Re-run /wiki-init and choose Complete scaffold to recover.
|
|
98
|
+
|
|
99
|
+
Track which files were written (and which were skipped in `FILL_GAPS` mode) so Step 7 can list them accurately.
|
|
100
|
+
|
|
101
|
+
6. **Finalize — read-back verification.**
|
|
102
|
+
|
|
103
|
+
Use `Read` to open `schema.md` and `index.md` and confirm:
|
|
104
|
+
|
|
105
|
+
- `schema.md` contains the sentinel line `_Schema not yet populated. Run \`/wiki-ingest <text-or-path>\` to seed it._` (exact match).
|
|
106
|
+
- `index.md` contains `# Wiki Index` as the first non-blank line.
|
|
107
|
+
|
|
108
|
+
Read-back is only for these two files because they are the files downstream commands key off of; `log.md` and `gaps.md` are append-only and have no sentinels that require verification.
|
|
109
|
+
|
|
110
|
+
If either read-back fails (file not found, or sentinel/header missing), abort the command and use the verification-failure report format from the Report Format section. Do NOT attempt to re-write — a failed read-back indicates something unexpected happened, and the user should intervene manually.
|
|
111
|
+
|
|
112
|
+
7. **Report.**
|
|
113
|
+
|
|
114
|
+
Print the final summary using the exact format specified in the [Report Format](#report-format) section. The report lists:
|
|
115
|
+
|
|
116
|
+
- Directories created (always `sources/` and `pages/`).
|
|
117
|
+
- Files created (depends on `WRITE_MODE`; in `FILL_GAPS` mode, list only the ones actually written).
|
|
118
|
+
- Files preserved (only in `FILL_GAPS` mode — the files that already existed and were skipped).
|
|
119
|
+
- Next step: `/wiki-ingest <text-or-path>`.
|
|
120
|
+
|
|
121
|
+
## State File Content
|
|
122
|
+
|
|
123
|
+
The literal content this command must write. Use these EXACTLY — downstream `/wiki-ingest` and `/wiki-lint` key off the sentinel strings and header shapes.
|
|
124
|
+
|
|
125
|
+
**`schema.md`** (placeholder):
|
|
126
|
+
|
|
127
|
+
```markdown
|
|
128
|
+
# Schema
|
|
129
|
+
|
|
130
|
+
<!--
|
|
131
|
+
This file will be populated by the curator on the first `/wiki-ingest`
|
|
132
|
+
run, after you approve the proposed schema. It is LOCKED thereafter.
|
|
133
|
+
|
|
134
|
+
For the canonical schema shape, see:
|
|
135
|
+
.claude/skills/llm-wiki/templates/schema-template.md
|
|
136
|
+
-->
|
|
137
|
+
|
|
138
|
+
_Schema not yet populated. Run `/wiki-ingest <text-or-path>` to seed it._
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The sentinel line `_Schema not yet populated. Run \`/wiki-ingest <text-or-path>\` to seed it._` MUST be written verbatim — `/wiki-ingest` matches this exact string to detect first-run vs steady-state. Do not alter the phrasing, punctuation, backticks, or italicization.
|
|
142
|
+
|
|
143
|
+
**`index.md`** (placeholder):
|
|
144
|
+
|
|
145
|
+
```markdown
|
|
146
|
+
# Wiki Index
|
|
147
|
+
|
|
148
|
+
_Page list will be populated as you ingest sources._
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**`log.md`** (placeholder):
|
|
152
|
+
|
|
153
|
+
```markdown
|
|
154
|
+
# Ingest Log
|
|
155
|
+
|
|
156
|
+
_Append-only. Every `/wiki-ingest` run adds one entry._
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**`gaps.md`** (placeholder):
|
|
160
|
+
|
|
161
|
+
```markdown
|
|
162
|
+
# Open Gaps
|
|
163
|
+
|
|
164
|
+
_Aggregated from every page's `## Gaps` section. Populated during ingest._
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Report Format
|
|
168
|
+
|
|
169
|
+
Use a single fenced block for the final report. Pick the variant that matches how the run proceeded.
|
|
170
|
+
|
|
171
|
+
**On successful clean-slate scaffold (`SCAFFOLD_STATE == NONE`):**
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
Wiki scaffolded at <absolute path to cwd>.
|
|
175
|
+
|
|
176
|
+
Directories created:
|
|
177
|
+
- sources/
|
|
178
|
+
- pages/
|
|
179
|
+
|
|
180
|
+
Files created:
|
|
181
|
+
- schema.md (placeholder — first `/wiki-ingest` will populate)
|
|
182
|
+
- index.md (empty index)
|
|
183
|
+
- log.md (empty log)
|
|
184
|
+
- gaps.md (empty gaps register)
|
|
185
|
+
|
|
186
|
+
Next step: run /wiki-ingest <text-or-path> to populate the wiki.
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**On `FILL_GAPS` mode (PARTIAL branch, user chose `Complete scaffold`):**
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
Wiki scaffold completed at <absolute path to cwd>.
|
|
193
|
+
|
|
194
|
+
Directories created or confirmed:
|
|
195
|
+
- sources/
|
|
196
|
+
- pages/
|
|
197
|
+
|
|
198
|
+
Files created:
|
|
199
|
+
- <only the files that did not already exist, with same annotations as the clean-slate variant>
|
|
200
|
+
|
|
201
|
+
Files preserved (already existed):
|
|
202
|
+
- <list of files that were skipped>
|
|
203
|
+
|
|
204
|
+
Next step: run /wiki-ingest <text-or-path> to populate the wiki.
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**On `FRESH` mode from PARTIAL or FULL (user chose `Overwrite all`):**
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
Wiki rewritten at <absolute path to cwd>.
|
|
211
|
+
|
|
212
|
+
Directories created or confirmed:
|
|
213
|
+
- sources/
|
|
214
|
+
- pages/
|
|
215
|
+
|
|
216
|
+
Files overwritten:
|
|
217
|
+
- schema.md (placeholder — first `/wiki-ingest` will populate)
|
|
218
|
+
- index.md (empty index)
|
|
219
|
+
- log.md (empty log)
|
|
220
|
+
- gaps.md (empty gaps register)
|
|
221
|
+
|
|
222
|
+
Note: sources/ and pages/ directory contents were not modified.
|
|
223
|
+
|
|
224
|
+
Next step: run /wiki-ingest <text-or-path> to populate the wiki.
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**On abort (user chose `Abort`, or `Other` was returned):**
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
Aborted. No changes made.
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
No further output — the project state is left untouched.
|
|
234
|
+
|
|
235
|
+
**On read-back verification failure (Step 6):**
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
Wiki scaffold FAILED at <absolute path to cwd>.
|
|
239
|
+
|
|
240
|
+
The following file could not be verified after write:
|
|
241
|
+
- <file path>
|
|
242
|
+
|
|
243
|
+
Expected content:
|
|
244
|
+
<expected sentinel or header>
|
|
245
|
+
|
|
246
|
+
This likely indicates a permissions or filesystem issue. Please check
|
|
247
|
+
the directory manually and re-run /wiki-init after resolving.
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Error Handling
|
|
251
|
+
|
|
252
|
+
Failure modes and the expected response:
|
|
253
|
+
|
|
254
|
+
- **Step 1 Read fails on an existing file** (e.g., permission denied) — treat as an "unknown artifact" for classification purposes. If it causes `SCAFFOLD_STATE` to shift to `PARTIAL` or `FULL`, the AskUserQuestion fires normally. Do NOT abort unconditionally — the user may still want to `Overwrite all`.
|
|
255
|
+
- **Step 4 mkdir fails** — abort with the mkdir failure message from Step 4. Do not proceed to Step 5.
|
|
256
|
+
- **Step 5 Write fails for any state file** — abort immediately with the Write failure message from Step 5. Do not continue to subsequent writes.
|
|
257
|
+
- **Step 6 read-back verification fails** — use the verification-failure report format above. Do not retry automatically.
|
|
258
|
+
- **Skill tool invocation fails** (e.g., `llm-wiki` skill not found) — this indicates a setup error (the `llm-wiki` skill is not installed). Abort and print:
|
|
259
|
+
|
|
260
|
+
> The llm-wiki skill is not available. Confirm that .claude/skills/llm-wiki/SKILL.md exists in the project or user scope, then re-run /wiki-init.
|
|
261
|
+
|
|
262
|
+
- **AskUserQuestion returns the auto-added `Other` option** — treat as an implicit abort. Print the abort line and stop. Do NOT attempt to interpret custom input.
|