@c4a/context-cli 0.5.29-alpha.1

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.
Files changed (38) hide show
  1. package/README.md +122 -0
  2. package/cli.js +37711 -0
  3. package/package.json +18 -0
  4. package/plugin/.claude-plugin/plugin.json +16 -0
  5. package/plugin/.claude-plugin/plugin.json.template +16 -0
  6. package/plugin/.codex-plugin/plugin.json +35 -0
  7. package/plugin/.codex-plugin/plugin.json.template +35 -0
  8. package/plugin/commands/align.md +54 -0
  9. package/plugin/commands/capture-aspect.md +17 -0
  10. package/plugin/commands/capture-code.md +25 -0
  11. package/plugin/commands/capture.md +67 -0
  12. package/plugin/commands/compile.md +89 -0
  13. package/plugin/commands/context.md +30 -0
  14. package/plugin/commands/drop.md +17 -0
  15. package/plugin/commands/extract.md +18 -0
  16. package/plugin/commands/init.md +95 -0
  17. package/plugin/commands/purge.md +18 -0
  18. package/plugin/commands/query.md +13 -0
  19. package/plugin/commands/status.md +21 -0
  20. package/plugin/skills/align-finalize/SKILL.md +137 -0
  21. package/plugin/skills/align-propose/SKILL.md +142 -0
  22. package/plugin/skills/align-scan/SKILL.md +161 -0
  23. package/plugin/skills/align-scan/references/data-model.md +343 -0
  24. package/plugin/skills/align-scan/references/user-question-contract.md +155 -0
  25. package/plugin/skills/compile-close/SKILL.md +122 -0
  26. package/plugin/skills/compile-draft/SKILL.md +246 -0
  27. package/plugin/skills/context-query/SKILL.md +166 -0
  28. package/plugin/skills/drop/SKILL.md +163 -0
  29. package/plugin/skills/semantic-reconcile/SKILL.md +106 -0
  30. package/scripts/build-plugin.ts +70 -0
  31. package/scripts/postinstall.mjs +183 -0
  32. package/templates/aspects/code/prompt.md +29 -0
  33. package/templates/aspects/design-system/prompt.md +27 -0
  34. package/templates/aspects/graphql/prompt.md +24 -0
  35. package/templates/aspects/openapi/prompt.md +24 -0
  36. package/wasm/tree-sitter-tsx.wasm +0 -0
  37. package/wasm/tree-sitter-typescript.wasm +0 -0
  38. package/wasm/tree-sitter.wasm +0 -0
@@ -0,0 +1,343 @@
1
+ # Data model — canonical tables
2
+
3
+ The authoritative lookup for Node / Section / Edge / Section-kind
4
+ semantics. Every other skill in the pipeline cites this file rather
5
+ than re-stating the tables. When the rules change, change them here.
6
+
7
+ ## Scope
8
+
9
+ All lookup data; no imperative steps. Consumers:
10
+
11
+ - `align-scan` — Node type + Entity tag classification
12
+ - `align-propose` — identity, establishment, Edge enumeration
13
+ - `align-finalize` — layout rules, mount matrix re-check
14
+ - `compile-draft` — Section kind priority, mount matrix, `source_ref`
15
+ - `compile-close` — verify rule codes
16
+
17
+ <reference>
18
+
19
+ ## Node types
20
+
21
+ | Type | Nature | Judgement | Typical examples |
22
+ |---|---|---|---|
23
+ | `domain` | Space / container | Not executed; holds other Nodes | Payment domain; frontend engineering; product handbook |
24
+ | `entity` | Thing / object | Concrete, nameable thing (deployable / installable / renderable / importable) | Checkout app; `@acme/payment-api`; React; a config-file instance |
25
+ | `action` | Event / flow | Independently-scoped ordered event with actors + value output | "Buyer initiates refund"; "DB scale-up runbook"; "New-hire onboarding" |
26
+ | `concept` | Abstract idea | Principle / term / pattern; not executable, not a thing | "Unidirectional data flow"; "SKU"; "Idempotent design" |
27
+
28
+ Closed set. Anything that doesn't fit one of these is not a Node —
29
+ demote to a Section on a host Node.
30
+
31
+ ## Entity vs Concept test
32
+
33
+ | Signal | → Entity | → Concept |
34
+ |---|---|---|
35
+ | Has a concrete integration surface (CLI / config file / API / hook / importable package) | ✓ | |
36
+ | Describes a behaviour / mechanism / capability without a specific thing | | ✓ |
37
+ | User asks "what is X" → definitional | | ✓ |
38
+ | User asks "how do I use / integrate X" → instantiable | ✓ | |
39
+
40
+ Spec / convention / pattern names are always Concepts. A specific
41
+ file instance of a spec is an Entity; the spec rules describing that
42
+ file are a Concept.
43
+
44
+ ## Entity tag groups
45
+
46
+ Entity candidates carry tags from two independent groups; at least
47
+ one of (A ∪ B) must be set.
48
+
49
+ **Group A — code-implementation layer** (≤1):
50
+
51
+ | tag | Meaning |
52
+ |---|---|
53
+ | `app` | End-to-end application with a user interface |
54
+ | `service` | Deployable with a network port; serves an API |
55
+ | `lib` | Framework / SDK referenced by other code; no standalone runtime |
56
+ | `cli` | Executable command-line tool |
57
+ | `module` | Code organisation unit that fits none of the above |
58
+ | `symbol` | Code symbol (function / class / method / component) |
59
+
60
+ **Group B — product-concept layer** (≤1):
61
+
62
+ | tag | Meaning |
63
+ |---|---|
64
+ | `application` | Directly creates user-visible value; users experience it |
65
+ | `system` | Supports other applications; users don't experience it directly |
66
+
67
+ **Legal states**:
68
+
69
+ | State | Tags | Example |
70
+ |---|---|---|
71
+ | Pure code unit | A only | `[lib]` for React |
72
+ | Pure product concept | B only | `[application]` for "Order management module" |
73
+ | Shippable + user value | A + B (one each) | `[app, application]` for a checkout app |
74
+
75
+ Illegal: two in A; two in B; neither group. Neither-group means the
76
+ candidate is not a valid Entity — see [False-Entity smell](#false-entity-smell).
77
+
78
+ ## Action tags
79
+
80
+ Exactly one, chosen from:
81
+
82
+ | tag | When |
83
+ |---|---|
84
+ | `user-story` | A user / role acts on a product surface |
85
+ | `runbook` | Emergency response / fault-handling / alert response |
86
+ | `howto` | Routine operational guide (team process, release, how-to) |
87
+ | `roadmap` | Time-bound planning / milestone / quarterly delivery |
88
+
89
+ Never invent `procedure` / `milestone` / `release`.
90
+
91
+ Action tags are Node tags only. Never place `user-story`, `runbook`,
92
+ `howto`, or `roadmap` in `planned_sections[]`; that field only accepts
93
+ Section kinds from the table below.
94
+
95
+ ## Concept tags
96
+
97
+ 0 or 1 of:
98
+
99
+ | tag | When |
100
+ |---|---|
101
+ | `term` | Atomic term / jargon (SKU, GMV, "authorised transaction") |
102
+ | `pattern` | Architectural / design / behavioural pattern |
103
+ | (none) | Pure abstract idea with no finer sub-kind |
104
+
105
+ ## Domain tags
106
+
107
+ Usually none. A Domain is a bucket, not a category.
108
+
109
+ ## Deprecated tags
110
+
111
+ Reject at classification time; map to the canonical replacement.
112
+
113
+ | Deprecated | Reason | Canonical replacement |
114
+ |---|---|---|
115
+ | `capability` | Mixed three meanings | Business-area → `application` or Domain; sub-capability → A-group; requirement → Action |
116
+ | `third-party` | Annotational | Put origin in `summary` |
117
+ | `product` | Overlaps B `application` | `application` |
118
+ | `subsystem` | Parent/child already in `contains` | A / B specific tag |
119
+ | `infrastructure` | Overlaps B `system` | `system` |
120
+ | `procedure` | Indistinguishable from `howto` / `runbook` | `howto` or `runbook` |
121
+ | `architecture` | `pattern` covers it | `pattern` |
122
+ | `principle` / `faq` | Collide with Section kinds | Section `principle` / Section `faq` |
123
+
124
+ ## False-Entity smell
125
+
126
+ Relational titles are almost always not Entities:
127
+
128
+ | Pattern | Handle |
129
+ |---|---|
130
+ | "X affects Y" / "X under Y" | Section (spec / warning / decision) on target-Node with `refers_to_nodes: [y]` |
131
+ | "Y-side of X" / "X's Y part" | Section on the actual target Node |
132
+ | "X rework / migration / refactor" | Usually an `action` describing the work, not an Entity |
133
+
134
+ Rule: if no A-group AND no B-group tag fits naturally, the candidate
135
+ is not an Entity. Mark `ambiguous` with a re-route note, never silently
136
+ drop.
137
+
138
+ ## Node establishment thresholds
139
+
140
+ | Type | Minimum to establish |
141
+ |---|---|
142
+ | `domain` | `contains` ≥1 child Node |
143
+ | `entity` | None beyond tag validity |
144
+ | `action` | ≥2 Section intents OR ≥1 sub-Action, with temporal / multi-party signal |
145
+ | `concept` | Passes the three-test gate AND will be referenced by ≥1 Node |
146
+
147
+ Below-bar candidates demote to a Section on a host Node.
148
+
149
+ ## Concept three-test gate
150
+
151
+ All three must pass.
152
+
153
+ | Test | Pass (✅) | Fail (❌) |
154
+ |---|---|---|
155
+ | Universality | Stands on its own outside this system / business | Only meaningful under one Entity / Action |
156
+ | Reusability | Other unrelated Nodes will cite it | One-off story context |
157
+ | Non-incarnation | Pure idea; no specific thing / process equivalent | An Entity / Action already holds it |
158
+
159
+ Any ❌ → demote to Section. Never invent Concepts to group Sections.
160
+
161
+ ## Identity uniqueness
162
+
163
+ | Type | Scope |
164
+ |---|---|
165
+ | `domain` | Global within the source_id scope |
166
+ | `entity` | `(name, source_id, parent Entity or Domain)` |
167
+ | `action` | Same `name` unique under the same parent |
168
+ | `concept` | Same `name` unique under the same parent |
169
+
170
+ ## Edge types
171
+
172
+ Five logical types. AST-layer edges (`imports / calls / extends /
173
+ implements`) are emitted by the extractor, never by a skill.
174
+
175
+ | type | Semantics | Directions |
176
+ |---|---|---|
177
+ | `contains` | Hierarchy | Domain → Entity/Action/Concept/Domain ; Entity → Entity ; Action → Action |
178
+ | `depends_on` | Runtime / business dependency | Entity → Entity ; Action → Action |
179
+ | `realizes` | Abstract landing on concrete | Entity → Concept (target MUST be Concept) |
180
+ | `refines` | Same-type refinement | Action → Action ; Concept → Concept |
181
+ | `related_to` | Loose association | Any → Any |
182
+
183
+ `refers_to_nodes` is a Section field, not an Edge. It names Nodes a
184
+ Section discusses. Never emit it as an edge entry.
185
+
186
+ ## Layout rules
187
+
188
+ Physical organisation of `contains`:
189
+
190
+ | Relation | File layout | Physical form |
191
+ |---|---|---|
192
+ | Same-file parent/child (Action→Action, Entity→Entity) | One file | Heading depth (`##` parent, `###` child) |
193
+ | Cross-file parent/child | Separate files | Parent has `## Contains` markdown list linking to child files |
194
+ | Domain → any child | Separate files always | Domain file holds `# title` + `## Contains` list only |
195
+
196
+ **Domain hard rule**: Domain files never nest children inline; every
197
+ child under a Domain is a standalone file. `contains` never appears in
198
+ frontmatter.
199
+
200
+ ## Section kinds
201
+
202
+ Ten kinds; priority chain (highest → lowest) governs stage-2
203
+ classification:
204
+
205
+ | # | kind | Trigger |
206
+ |---|---|---|
207
+ | 1 | `changelog` | Versioned change record (`valid_from` / `valid_until`) |
208
+ | 2 | `principle` | Long-term invariant / design rule |
209
+ | 3 | `spec` | Verifiable constraint with an explicit validation method |
210
+ | 4 | `decision` | Choice with rationale + rejected options |
211
+ | 5 | `comparison` | ≥2 subjects × ≥2 dimensions (usually a table) |
212
+ | 6 | `warning` | Risk / gotcha / caveat explicitly flagged |
213
+ | 7 | `incident` | Actual fault / outage case with time / impact |
214
+ | 8 | `example` | Concrete snippet / sample / config |
215
+ | 9 | `faq` | Question + answer pair; title is a question |
216
+ | 10 | `description` | Fallback narrative — definition / explanation / spine |
217
+
218
+ First match wins. `description` is the bottom, NOT the default.
219
+
220
+ ## Section mount matrix
221
+
222
+ Section kind × Node type. `✓` = allowed; `—` = rejected at write time.
223
+
224
+ | Section kind | Domain | Entity | Action | Concept |
225
+ |---|:---:|:---:|:---:|:---:|
226
+ | description | ✓ | ✓ | ✓ | ✓ |
227
+ | spec | — | ✓ | ✓ | ✓ |
228
+ | warning | ✓ | ✓ | ✓ | ✓ |
229
+ | principle | ✓ | ✓ | — | ✓ |
230
+ | decision | ✓ | ✓ | ✓ | ✓ |
231
+ | incident | — | ✓ | ✓ | — |
232
+ | example | — | ✓ | — | ✓ |
233
+ | changelog | — | ✓ | — | — |
234
+ | comparison | — | ✓ | — | ✓ |
235
+ | faq | ✓ | ✓ | ✓ | ✓ |
236
+
237
+ Hard rules worth emphasising:
238
+
239
+ - `principle` never mounts on Action
240
+ - `spec` never mounts on Domain
241
+ - `incident` only on Entity / Action
242
+ - `example` / `comparison` only on Entity / Concept
243
+ - `changelog` only on Entity
244
+
245
+ ## `source_ref` canonical form
246
+
247
+ Written in each Section's comment header:
248
+
249
+ ```
250
+ src-N#<anchor> L<a>-<b>
251
+ ```
252
+
253
+ All three segments required. `src-N` is a 1-based index into the
254
+ Node's `frontmatter.sources[]`. `<anchor>` is a raw-file heading slug
255
+ covering the line range, or the literal `document` when the raw has
256
+ no usable heading. `L<a>-<b>` is an inclusive line range; `a` can
257
+ equal `b`.
258
+
259
+ Invalid forms:
260
+
261
+ ```
262
+ src-1 L200-260 # missing #<anchor>
263
+ src-1#intro # missing L range
264
+ ```
265
+
266
+ Prefer `source_ref_text` (verbatim raw quote) when anchor + lines
267
+ aren't obvious. The CLI's compile-draft resolver computes the
268
+ canonical form.
269
+
270
+ ## Glossary
271
+
272
+ Workspace-derived from committed Entity + Action + Concept Nodes.
273
+ Each entry:
274
+
275
+ ```
276
+ <type>:<slug>
277
+ title: <human title>
278
+ aliases: [<alt>, ...]
279
+ tags: [...]
280
+ summary: <one-liner, optional>
281
+ ```
282
+
283
+ Matching precedence for a raw name:
284
+
285
+ 1. Exact title (case-insensitive, NFC) → `existing`
286
+ 2. Alias → `existing` (record which alias matched)
287
+ 3. Fuzzy with high confidence (minor whitespace / punctuation / known
288
+ language variants) → `existing`
289
+ 4. Miss + ≥2 mentions OR authoritative signal → `new`
290
+ 5. Miss + single peripheral mention → noise; omit
291
+
292
+ Conflict handling: most-specific wins (entity > concept > domain).
293
+ If genuinely ambiguous, emit an `ambiguous` entry listing all hits.
294
+
295
+ ## Section status and deprecation
296
+
297
+ Section status lives in the `<!-- ... -->` comment header, never in
298
+ the blockquote. The blockquote is always `> **[${kind}]** <content>`;
299
+ the parser rejects any file where the marker kind differs from the
300
+ comment kind.
301
+
302
+ Comment-header shape:
303
+
304
+ ```
305
+ <!-- section-N <kind> <source-ref-or-dash> [status=<s>] [confidence=<c>] [refers_to_nodes=<a>,<b>] [valid_until=<v>] -->
306
+ ```
307
+
308
+ - `status` attribute appears only when non-`active` (e.g. `deprecated`)
309
+ - `confidence` attribute appears only when non-`confirmed`
310
+ - Source-ref token is either a canonical `src-N#<anchor> L<a>-<b>` OR
311
+ a single `-` when cleared
312
+
313
+ To deprecate: set source-ref token to `-` (when evidence is gone),
314
+ insert `status=deprecated`. Never touch the blockquote.
315
+
316
+ To re-anchor: replace the source-ref token with a new
317
+ `src-M#<anchor> L<x>-<y>`; add `confidence=inferred` to record the
318
+ downgrade.
319
+
320
+ ## Verify rule codes
321
+
322
+ Close-time `context verify` / `context compile --close` emits these.
323
+ Warnings don't block; errors flip exit to 2.
324
+
325
+ | Code | Level | Meaning | Minimum fix |
326
+ |---|---|---|---|
327
+ | `dropped-source-reference` | error | Node `sources[]` lists a dropped source | Run `/context:drop` to complete cleanup; it uses `context mdrive node update` to remove the id |
328
+ | `dangling-source-alias` | error | Section `src-N` past end of `sources[]` | Re-run `context compile --draft <slug>` with correct `source_ref` |
329
+ | `sourceless-node` | warning | Node `sources[]` is empty after cleanup | Keep only if intentionally orphaned by `/context:drop`; otherwise re-anchor or add a source via `context mdrive node update` |
330
+ | `body-ad-hoc-heading` | error | Node body has a heading the parser reads as a nested Node | Re-run `/context:compile` so the draft loop moves that content into Sections |
331
+ | `invalid-section-mount` | error | Kind × Node type mismatch | Re-run `/context:compile`; or deprecate via `context mdrive section deprecate` |
332
+ | `contains-cycle` / `refines-cycle` | error | Edge graph has a cycle | Re-align; structural issue |
333
+ | `duplicate-slug` | error | Two Nodes share a slug | User picks winner; run `context mdrive node rename --from <old> --to <new>` |
334
+ | `domain-same-file-child` | error | Domain md has inline child Nodes | Move child to standalone file; register in Domain's `## Contains` |
335
+ | `invalid-frontmatter-schema` | error | Missing / malformed field | Fix frontmatter via `context mdrive node update` |
336
+ | `heading-title-mismatch` | error | Root H1 differs from `title:` | Run `context mdrive workspace compact` |
337
+ | `description-dominates` | warning (experimental) | >50% of Node's Sections are `description` | Re-draft with priority chain honoured |
338
+
339
+ For structural errors (`contains-cycle`, `refines-cycle`,
340
+ `duplicate-slug`, `invalid-node-type`), do NOT resolve from
341
+ compile-close — the fix requires `/context:align` again.
342
+
343
+ </reference>
@@ -0,0 +1,155 @@
1
+ # User Question Contract
2
+
3
+ This reference defines how agents ask users for decisions during
4
+ agent-driven workflows. It does not change the data model. The agent still
5
+ maps every answer back to the canonical Node / Section / Edge schema.
6
+
7
+ ## Goal
8
+
9
+ Ask the user for business intent, not storage mechanics. A good question lets
10
+ the user answer from domain knowledge: "how should people find this later?",
11
+ "does this relationship mean dependency or comparison?", "is this old content
12
+ still valid?" The agent owns the translation into types, tags, sections,
13
+ edges, slugs, and source references.
14
+
15
+ ## Hard Rules
16
+
17
+ - Before the first decision question, give a two-sentence framing note: what
18
+ was found, what the align / compile / drop step is trying to decide, and
19
+ that implementation-only choices are handled automatically.
20
+ - Do not expose model terms in user-facing question text or option labels:
21
+ `Node`, `Section`, `Concept`, `Entity`, `Domain`, `contains`,
22
+ `related_to`, `depends_on`, `source_ref`, `src-N`, `raw`, `frontmatter`,
23
+ `slug`, `mount matrix`, `re-anchor`.
24
+ - Use "source document", "material", "topic", "detail", "standalone entry",
25
+ "relationship", "old claim", and "supporting evidence" in user-facing
26
+ prose.
27
+ - Ask only when the answer changes business meaning, retrieval granularity,
28
+ source validity, or user-visible organization.
29
+ - Do not ask when the choice is only about duplicate headings, navigation
30
+ blocks, storage shape, source-ref arithmetic, or safe defaults. Apply the
31
+ default and mention it in the summary.
32
+ - Each multi-choice question has one short context line, one direct question,
33
+ 2-4 concrete choices, and an "Other" escape hatch when the host does not
34
+ add one automatically.
35
+ - Option descriptions describe user-visible consequences, not schema actions.
36
+ - Question text follows the user's conversation language. CLI commands,
37
+ paths, ids, and machine tokens stay English.
38
+
39
+ ## Ask vs Decide Locally
40
+
41
+ | Situation | Ask the user? | Default if not asking |
42
+ |---|---:|---|
43
+ | A repeated "Related links" / "References" / navigation block appears in several source documents | No, unless it contains a new business claim | Treat it as navigation and represent the useful relationship once |
44
+ | A subtopic may need to be found directly later | Yes | If weak evidence, keep it under the parent topic |
45
+ | Two products / systems / ideas might be alternatives, dependency, or merely co-mentioned | Yes | If unclear and no user answer, keep only the shared parent; no direct relationship |
46
+ | A stale source conflicts with a newer active source | Yes | Keep both candidates and ask which claim is current |
47
+ | A source is being dropped and a claim has no replacement evidence | No | Mark the claim as no longer supported |
48
+ | A source is being dropped and another source appears to support the same claim, but the match is inferred | Usually no; show it in the impact plan | Move support to the surviving source and mark the confidence as inferred |
49
+ | A proposed rename changes the user's vocabulary | Yes | Keep the original title / alias |
50
+ | A section kind, edge type, source-ref, or file layout choice is required | No | Agent maps from the user's intent to the model |
51
+
52
+ ## Question Templates
53
+
54
+ ### Align: standalone topic or detail
55
+
56
+ Context: "I found several Vmok subsections such as 'Core capabilities',
57
+ 'Scenarios', and 'Integration example'. The decision is whether people will
58
+ search these directly later."
59
+
60
+ Question: "How should these Vmok subsections be organized?"
61
+
62
+ Choices:
63
+
64
+ - "Keep them as parts of Vmok" — choose this if people normally read them
65
+ while looking at Vmok.
66
+ - "Make them separate searchable entries" — choose this if people will ask
67
+ for "Vmok integration example" or "Vmok scenarios" directly.
68
+ - "Keep only the strongest one separate" — choose this when only one
69
+ subsection deserves direct lookup.
70
+
71
+ ### Align: relationship meaning
72
+
73
+ Context: "Vmok and Garfish appear near each other in the source documents, but
74
+ the text does not clearly say how they relate."
75
+
76
+ Question: "What is the business relationship between Vmok and Garfish?"
77
+
78
+ Choices:
79
+
80
+ - "Comparable alternatives" — people may compare them or choose one.
81
+ - "Vmok is based on Garfish" — Vmok needs Garfish or builds on it.
82
+ - "Same area, no direct relationship" — both belong under the same broader
83
+ topic, but there is no direct link.
84
+
85
+ ### Align: repeated references block
86
+
87
+ Do not ask this when the block only lists links or nearby topics. Apply the
88
+ default and summarize:
89
+
90
+ "I found repeated related-links sections in three source documents. They look
91
+ like navigation, so I will not copy them as new content; I will keep the useful
92
+ relationships once in the structure."
93
+
94
+ Ask only if the block contains real prose:
95
+
96
+ Question: "Do these 'related content' sections contain business information we
97
+ must preserve, or are they only navigation?"
98
+
99
+ Choices:
100
+
101
+ - "Only navigation" — use them to understand relationships, not as content.
102
+ - "Preserve the explanation" — keep the useful prose in the relevant topic.
103
+ - "Not sure" — keep a short summary for now.
104
+
105
+ ### Align: old or conflicting source
106
+
107
+ Context: "One source describes the old access path, while a newer source
108
+ describes a different path."
109
+
110
+ Question: "Which version should readers trust now?"
111
+
112
+ Choices:
113
+
114
+ - "Use the newer version" — old wording stays only as historical context.
115
+ - "Keep both with dates" — both are valid for different periods or cases.
116
+ - "Use the old version" — the newer source is not authoritative for this
117
+ workspace.
118
+
119
+ ### Compile plan: replacing existing content
120
+
121
+ Context: "The new material changes a statement that already exists in the
122
+ knowledge base."
123
+
124
+ Question: "How should the existing statement be handled?"
125
+
126
+ Choices:
127
+
128
+ - "Replace it" — readers should see only the newer statement as current.
129
+ - "Keep both with context" — both statements matter for different cases.
130
+ - "Do not change it" — the new material should not override the current
131
+ knowledge.
132
+
133
+ ### Drop: source removal impact
134
+
135
+ Context: "Dropping this source affects 2 topics and 4 pieces of knowledge. Some
136
+ claims can still be supported by other source documents; others cannot."
137
+
138
+ Question: "Proceed with this cleanup?"
139
+
140
+ Choices:
141
+
142
+ - "Proceed" — unsupported claims are marked old, and supported claims move to
143
+ surviving evidence.
144
+ - "Stop" — no files are changed.
145
+ - "Show details first" — list the affected topics before deciding.
146
+
147
+ ## Bad to Good
148
+
149
+ | Bad | Good |
150
+ |---|---|
151
+ | "Keep as Section or promote to Concept?" | "Will people search this as its own topic, or only read it inside the parent topic?" |
152
+ | "Choose related_to / depends_on / no edge." | "Are these alternatives, does one build on the other, or are they only in the same area?" |
153
+ | "3 raw files all have Relations blocks. Drop or keep as Section?" | "I found repeated related-links sections. They look like navigation, so I will treat them as structure and not copy them as content." |
154
+ | "Re-anchor section-3 from src-1 to src-2?" | "Another source still supports this claim, so I will keep it but mark the support as inferred." |
155
+ | "Rename slug vmok-core-capability?" | "Should readers see this as 'Vmok core capabilities', or do you prefer another title?" |
@@ -0,0 +1,122 @@
1
+ ---
2
+ name: compile-close
3
+ description: >
4
+ Final skill of `/context:compile`. Runs after every `compile-draft`
5
+ iteration. Triggers `context compile --close`, which in one invocation
6
+ verifies the workspace, refreshes locator-only evidence, compacts
7
+ knowledge, rebuilds `knowledge/_index.md`, appends a changelog
8
+ entry, rebuilds section fingerprints + incremental cache, and
9
+ archives compile scratch files. Agent intervention is
10
+ limited to interpreting the CLI's output and routing any verify
11
+ error back to its upstream command (`/context:compile` for Section
12
+ issues, `/context:align` for structural issues, `/context:drop`
13
+ for dropped-source references). The skill never edits `knowledge/`.
14
+ Activates once all draft actions are applied and before user-visible
15
+ success is declared.
16
+ tools:
17
+ - Read
18
+ - Bash
19
+ ---
20
+
21
+ # compile-close — global verify + index + changelog
22
+
23
+ Close a compile run. The CLI does the work; the skill reads the
24
+ CLI's output and routes any failure back to the correct upstream
25
+ command. It does not write or edit anything under `knowledge/`.
26
+
27
+ ## TL;DR — Non-negotiables
28
+
29
+ - Script-driven. `context compile --close` verifies first, then performs close writes, rebuilds section fingerprints + incremental cache, and archives compile scratch files. Read the command's stdout + exit code; that's the close's full output.
30
+ - **Agent NEVER edits `knowledge/` from compile-close.** The CLI is the sole writer under `knowledge/` — `_index.md`, `changelog.md`, every `<type>/<slug>.md`. If verify reports an error here, route it back, not around:
31
+ - Content / Section issues (`invalid-section-mount`, `body-ad-hoc-heading`, `dangling-source-alias`) → user re-runs `/context:compile` (draft loop fixes its own Section actions; compile-close does not patch)
32
+ - Structural issues (`contains-cycle`, `refines-cycle`, `duplicate-slug`, `invalid-node-type`, `domain-same-file-child`) → user runs `/context:align` to revise the plan
33
+ - Source issues (`dropped-source-reference`) → user runs `/context:drop <id>` to complete the drop
34
+ - Exit 0 → summarise node/section totals, verify, `recompiled`, `locator_updates`, `rebuilt`, fingerprint rebuild count, and archive path when printed; then stop.
35
+ - Exit 2 → report the full issue list verbatim + point at the right re-entry command above. Do not open the affected Node md.
36
+ - Never re-run `context compile --draft` from close to paper over verify failures. Draft failures belong in the draft loop.
37
+ - Derivable files self-heal: missing `_index.md` or `changelog.md` is rebuilt inside `compile --close` before the append. No pre-check needed.
38
+ - LLM-assisted repair (`--fix-with-llm`) is not available in the current release.
39
+ - Output language: summary prose matches the user's language; CLI output, issue codes, file paths stay as printed.
40
+ - Successful close archives `compile.*` scratch files under the workspace `output/archive/` directory, copies the consumed `align.md` + `bind.yaml`, and rebuilds the user-level incremental cache. The current root `align.md` + `bind.yaml` remain available for recompile/status. The CLI owns this lifecycle — the agent must not move, delete, or archive workspace `output/` files by hand.
41
+ - Semantic decisions are applied and recorded before close. Compile-close does not judge or rewrite semantic decisions; it only verifies the already-applied workspace and rebuilds derived indexes.
42
+
43
+ <reference>
44
+
45
+ ## Stages inside `context compile --close`
46
+
47
+ Close is one in-process command with one exit code:
48
+
49
+ 1. **Workspace verify** — runs the full rule set before close writes. Any error flips exit to 2 and no success stamp is written.
50
+ 2. **Locator refresh** — if evidence moved but block hashes are unchanged, updates only section locators.
51
+ 3. **Workspace compact** — re-renders every `knowledge/<type>/*.md` canonically (Section order, frontmatter field order, `## Contains` list ordering, heading depth).
52
+ 4. **Rebuild `_index.md`** — regenerates the index from the current workspace state; previous content overwritten.
53
+ 5. **Append changelog** — appends one compile list item to `knowledge/changelog.md`; existing entries preserved.
54
+ 6. **Rebuild incremental cache** — rebuilds section fingerprints and cache indexes from workspace truth sources.
55
+ 7. **Archive scratch files** — moves `compile.*` context/draft payloads under `output/archive/` and copies the align/bind inputs used for this compile.
56
+
57
+ ## Outcome routing
58
+
59
+ | Outcome | Agent action |
60
+ |---|---|
61
+ | Exit 0, 0 issues | Summarise those counts in the user's language: Nodes touched; Sections added / updated / superseded / deprecated / skipped; `recompiled`; `locator_updates`; `rebuilt`; verify green. Stop. |
62
+ | Exit 0, warnings only | Summarise + list warnings verbatim. Point at `/context:status` or `context cache status` when the warning is incremental-cache-related. Stop. |
63
+ | Exit 2, Section / content issue | Surface the full issue list; point the user at re-running `/context:compile` (the draft loop owns Section writes). Do NOT Edit the affected Node md. |
64
+ | Exit 2, structural issue (cycle, duplicate slug, `invalid-node-type`, `domain-same-file-child`) | Surface the full issue list; point the user at `/context:align` to revise structure. Do not re-run compile. |
65
+ | Exit 2, `dropped-source-reference` | Surface the source-id; point the user at `/context:drop <id>` to complete the drop cleanup. |
66
+
67
+ Compile-close never edits `knowledge/` on the agent side. Every verify error routes back to the correct upstream command (compile / align / drop), never sideways into a hand Edit. See the [Verify rule codes](${CLAUDE_PLUGIN_ROOT}/skills/align-scan/references/data-model.md#verify-rule-codes) lookup for the error→command mapping.
68
+
69
+ ## Changelog entry shape
70
+
71
+ `context compile --close` appends one markdown list item per run to
72
+ `knowledge/changelog.md` with aggregate counts — not a multi-line
73
+ block:
74
+
75
+ ```
76
+ - [compile] nodes=N sections=M recompiled=R locator_updates=L @ <ISO timestamp>
77
+ ```
78
+
79
+ `[drop]` lines from `/context:drop` follow the same single-line list-
80
+ item convention (see the drop skill for the exact shape).
81
+
82
+ </reference>
83
+
84
+ <procedures>
85
+
86
+ ### Step 1 — Invoke close
87
+
88
+ Run `context compile --close`. The caller (typically `/context:compile`) may have already invoked it; check for existing output before re-running.
89
+
90
+ ### Step 2 — Interpret
91
+
92
+ Read stdout + stderr. The exit code selects the path via [Outcome routing](#outcome-routing).
93
+
94
+ ### Step 3 — Route errors to the correct upstream command
95
+
96
+ For each error in the CLI's report, classify via [Outcome routing](#outcome-routing) and name the re-entry command in your report. Do NOT Edit any file under `knowledge/` — that violates the CLI-sole-writer principle and masks the real upstream fix. Specifically:
97
+
98
+ - Section / content issue → user re-runs `/context:compile` (draft loop produces new Section actions; the CLI re-writes).
99
+ - Structural issue → user runs `/context:align` (revise the plan; re-compile afterwards).
100
+ - `dropped-source-reference` → user runs `/context:drop <id>` to finish drop cleanup.
101
+
102
+ One pass. If the CLI reports multiple errors, list them all and let the user choose the order; do not loop compile-close itself.
103
+
104
+ ### Step 4 — Report
105
+
106
+ Summarise in the user's language:
107
+
108
+ - Nodes touched and counts per op (add / update / supersede / deprecate / skip / locator-only).
109
+ - `_index.md` rebuilt / updated; `changelog.md` appended at `<timestamp>`.
110
+ - Incremental close counts printed by the CLI: `recompiled`, `locator_updates`, `rebuilt`, and section fingerprint rebuild count.
111
+ - Verify result: green / `<n>` warnings / `<n>` errors (issue codes verbatim).
112
+
113
+ Stop. Do not auto-invoke follow-on commands.
114
+
115
+ ### Step 5 — Self-verify
116
+
117
+ - [ ] `context compile --close` ran exactly once per close call — if not, **Step 1**.
118
+ - [ ] If exit 2, every error is surfaced to the user with a re-entry command (compile / align / drop); no silent ignores — **Step 3**.
119
+ - [ ] No agent-hand edits anywhere under `knowledge/` — if any, revert; compile-close is read-only on `knowledge/`.
120
+ - [ ] No Read / Glob / Grep / Write was used against `WORKSPACE_DIR`; CLI-owned archival under `output/archive/` is allowed.
121
+
122
+ </procedures>