@c4a/context-cli 0.5.29-alpha.1 → 0.5.29-beta.16

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 (49) hide show
  1. package/README.md +71 -34
  2. package/cli.js +39951 -15792
  3. package/package.json +1 -1
  4. package/plugin/.claude-plugin/plugin.json.template +1 -1
  5. package/plugin/.codex-plugin/plugin.json.template +8 -5
  6. package/plugin/.cursor-plugin/plugin.json.template +29 -0
  7. package/plugin/README.md +99 -0
  8. package/plugin/README_CN.md +97 -0
  9. package/plugin/assets/icon.svg +3 -0
  10. package/plugin/assets/logo.svg +3 -0
  11. package/plugin/commands/align.md +44 -44
  12. package/plugin/commands/capture.md +28 -12
  13. package/plugin/commands/compile.md +97 -34
  14. package/plugin/commands/context.md +7 -4
  15. package/plugin/commands/drop.md +14 -6
  16. package/plugin/commands/extract.md +4 -4
  17. package/plugin/commands/init.md +49 -10
  18. package/plugin/commands/purge.md +8 -4
  19. package/plugin/commands/query.md +11 -3
  20. package/plugin/commands/status.md +4 -2
  21. package/plugin/skills/skill-align-workflow/SKILL.md +55 -0
  22. package/plugin/skills/skill-align-workflow/references/candidate-resolution.md +60 -0
  23. package/plugin/skills/skill-align-workflow/references/density-profile.md +23 -0
  24. package/plugin/skills/skill-align-workflow/references/gates.md +95 -0
  25. package/plugin/skills/skill-compile-close/SKILL.md +127 -0
  26. package/plugin/skills/skill-compile-draft/SKILL.md +409 -0
  27. package/plugin/skills/skill-context-query/SKILL.md +184 -0
  28. package/plugin/skills/skill-drop/SKILL.md +190 -0
  29. package/plugin/skills/skill-semantic-reconcile/SKILL.md +249 -0
  30. package/scripts/build-plugin.ts +674 -45
  31. package/templates/aspects/code/aspect.yaml +21 -0
  32. package/templates/aspects/code/prompt.md +33 -18
  33. package/templates/aspects/design-system/prompt.md +2 -3
  34. package/templates/aspects/graphql/prompt.md +2 -2
  35. package/templates/aspects/openapi/prompt.md +2 -2
  36. package/plugin/.claude-plugin/plugin.json +0 -16
  37. package/plugin/.codex-plugin/plugin.json +0 -35
  38. package/plugin/commands/capture-aspect.md +0 -17
  39. package/plugin/commands/capture-code.md +0 -25
  40. package/plugin/skills/align-finalize/SKILL.md +0 -137
  41. package/plugin/skills/align-propose/SKILL.md +0 -142
  42. package/plugin/skills/align-scan/SKILL.md +0 -161
  43. package/plugin/skills/align-scan/references/data-model.md +0 -343
  44. package/plugin/skills/align-scan/references/user-question-contract.md +0 -155
  45. package/plugin/skills/compile-close/SKILL.md +0 -122
  46. package/plugin/skills/compile-draft/SKILL.md +0 -246
  47. package/plugin/skills/context-query/SKILL.md +0 -166
  48. package/plugin/skills/drop/SKILL.md +0 -163
  49. package/plugin/skills/semantic-reconcile/SKILL.md +0 -106
@@ -1,161 +0,0 @@
1
- ---
2
- name: align-scan
3
- description: >
4
- First skill of `/context:align`. Reads `WORKSPACE_DIR/output/align.scan.yaml` + the
5
- workspace glossary, inspects the raw outlines/full raw evidence, classifies
6
- raw material into existing / new / ambiguous / orphan, and writes a
7
- structured JSON decisions file for align-propose to consume. The CLI only
8
- provides weak candidate seeds and deterministic context; semantic
9
- classification is the agent's job. Activates when `/context:align` starts,
10
- or when an agent has raw material ready and needs a first-cut candidate list before the
11
- structural proposal step.
12
- tools:
13
- - Read
14
- - Bash
15
- ---
16
-
17
- # align-scan — classify raw material
18
-
19
- Classify raw material in `WORKSPACE_DIR/output/align.scan.yaml` against the
20
- workspace glossary. The scan file is a context package, not a final classifier:
21
- `new_candidates[]` are weak seeds and `raw_outlines[]` is the main reading map.
22
- Output one JSON payload; no markdown.
23
-
24
- `WORKSPACE_DIR` is provided by the caller from `context workspace locate --format json` (`ctxDir`). It is `.context/` in embedded layout and the repository root in root layout.
25
-
26
- ## TL;DR — Non-negotiables
27
-
28
- - Output is JSON only; the CLI owns every rendered markdown file.
29
- - Input is `WORKSPACE_DIR/output/align.scan.yaml` produced by `context align --scan`; scan v2 is structural-first and deliberately avoids semantic type guesses.
30
- - Read `raw_outlines[]` for every scanned raw file. When the outline or previews are insufficient, read the full raw file with `context workspace read <path> --format text`.
31
- - Treat `scan.new_candidates[]` as weak seeds only. `semantic_type: "unresolved"` / `classification_required: true` means the CLI intentionally did not classify it.
32
- - `type` is one of `domain / entity / action / concept` (see [Node types](references/data-model.md#node-types)); nothing else.
33
- - Every `entity` candidate carries ≥1 tag from group A or B (see [Entity tag groups](references/data-model.md#entity-tag-groups)).
34
- - Every candidate has ≥1 `mention` with `{file, line, quote}` (quote ≤180 chars); no fabrication.
35
- - Glossary hits become `existing`, not new candidates (see [Glossary](references/data-model.md#glossary)).
36
- - Relational titles ("X affects Y", "Y-side of X", "X migration") are not Entities — re-route via [False-Entity smell](references/data-model.md#false-entity-smell).
37
- - Raw file paths in the scan are relative to `WORKSPACE_DIR`; read raw evidence only with `context workspace read <path>`. Never use Read / Glob / Grep against workspace files.
38
- - Save the decisions file only with `context align --save-scan-decisions -`; do not touch `knowledge/`, raw files, or cache files.
39
- - Output language: user-facing prose matches the user's conversation language; JSON keys / slug / tag values stay English.
40
-
41
- <reference>
42
-
43
- ## Output schema (agent decisions)
44
-
45
- This is the JSON you write with `context align --save-scan-decisions -`.
46
- It is not the raw CLI scan schema. In `output/align.scan.yaml`,
47
- `scan.new_candidates[]` may omit `suggested_type` / `suggested_tags`;
48
- the agent must fill them after reading raw evidence. When a candidate has
49
- `semantic_type: "unresolved"` and `classification_required: true`, that is the
50
- expected scan-v2 shape, not an error.
51
-
52
- ```jsonc
53
- {
54
- "scan_version": 2,
55
- "workspace": "<workspace-name from scan>",
56
- "existing_nodes": [
57
- { "slug": "...", "type": "entity|action|concept|domain",
58
- "confirmed_mentions": [ { "file": "...", "line": 12, "quote": "..." } ] }
59
- ],
60
- "new_candidates": [
61
- { "name": "<human title>", "suggested_slug": "<kebab-case>",
62
- "suggested_type": "entity|action|concept|domain",
63
- "suggested_tags": ["lib"],
64
- "confidence": "high|medium|low",
65
- "mentions": [ { "file": "...", "line": 45, "quote": "..." } ],
66
- "suggested_parent": "<slug>",
67
- "suggested_realizes": "<slug>",
68
- "notes": "<optional>"
69
- }
70
- ],
71
- "ambiguous": [
72
- { "phrase": "...",
73
- "candidates": [
74
- { "kind": "existing", "slug": "..." },
75
- { "kind": "new", "name": "...", "suggested_type": "...", "suggested_tags": [] }
76
- ],
77
- "mentions": [ ... ],
78
- "reroute_as": "<optional: Section on target-slug>"
79
- }
80
- ],
81
- "orphans": [ { "slug": "...", "reason": "...", "mentions": [ ... ] } ],
82
- "decisions": { "notes": "<free-form rationale>" }
83
- }
84
- ```
85
-
86
- ## Confidence calibration
87
-
88
- | `confidence` | When |
89
- |---|---|
90
- | `high` | Multiple direct mentions + clear integration signal (authoritative "X is our X library" prose) |
91
- | `medium` | ≥2 mentions OR a single authoritative mention (section heading) |
92
- | `low` | Single peripheral mention; prefer `ambiguous` over a low-confidence `new` |
93
-
94
- </reference>
95
-
96
- <procedures>
97
-
98
- ### Step 1 — Read the scan
99
-
100
- Read `output/align.scan.yaml` with `context workspace read output/align.scan.yaml --format text`
101
- and verify `scan_version: 2` (legacy `scan_version: 1` is readable). If missing, stop and tell the user to run `context align --scan` first.
102
- Skim `glossary[]` to remember the existing slug + alias set.
103
- For `scan_version: 2`, first inspect `incremental`:
104
-
105
- - `structure_changed[]` and `new_sources[]` are the only reasons to classify structure.
106
- - `content_changed_only[]` means compile work, not align work; do not create candidates from those sources.
107
- - `skipped_sources[]` are unchanged; do not classify them.
108
- - `unknown_sources[]` cannot be treated as unchanged. Return control to the caller with the reason unless the caller chose a full scan.
109
-
110
- When source context is needed, run `context workspace read <path> --format text` where
111
- `<path>` comes from `raw_files_scanned[]` or `mentions[].file`; for example,
112
- `raw/local/2026-04-25-vmok.md`. Do not attempt to read only `2026-04-25-vmok.md`
113
- from the current directory, and do not use the Read tool against `WORKSPACE_DIR`.
114
-
115
- Then inspect every `raw_outlines[]` entry:
116
-
117
- - `headings[]` shows the full H1-H6 shape so H3/H4 content is not ignored.
118
- - `relation_lines[]` shows protocol-like navigation hints. Treat them as structure, not content claims, unless the surrounding raw prose adds a business claim.
119
- - `relation_hints[]` is the structured version of those navigation lines (`parent` / `children` / `related` / `relations` plus link targets). Use it to preserve explicit raw links, but do not infer semantic type from it.
120
- - `evidence_blocks[]` gives short previews for all parsed blocks. If a candidate decision depends on text outside the preview, read the full raw file through `context workspace read`.
121
-
122
- ### Step 2 — Promote `existing_nodes`
123
-
124
- Copy every `scan.existing_nodes[]` entry into `output.existing_nodes[]`
125
- with its `confirmed_mentions`. If any raw quote contradicts the
126
- glossary summary (sunset / replaced), also emit an `orphan` entry;
127
- never silently drop.
128
-
129
- ### Step 3 — Classify raw material
130
-
131
- Use `scan.new_candidates[]` as a seed list, then check `raw_outlines[]` and full raw evidence before deciding. A new Node can come from a seed, a heading visible only in `raw_outlines[]`, or a repeated/raw-supported concept discovered while reading the full source. Conversely, a seed can be demoted to a Section or ignored as navigation.
132
-
133
- For each potential topic:
134
-
135
- 1. Match against glossary per [Glossary](references/data-model.md#glossary). A hit moves the item to `existing_nodes`.
136
- 2. Pick `suggested_type` per [Node types](references/data-model.md#node-types). Use [Entity vs Concept test](references/data-model.md#entity-vs-concept-test) when torn between entity and concept.
137
- 3. For `entity`, pick tags per [Entity tag groups](references/data-model.md#entity-tag-groups). If neither group has a legal tag, route via [False-Entity smell](references/data-model.md#false-entity-smell) into `ambiguous`; do not force a tag.
138
- 4. Map any deprecated tag from the raw to its canonical form per [Deprecated tags](references/data-model.md#deprecated-tags).
139
- 5. Assign `confidence` per [Confidence calibration](#confidence-calibration).
140
- 6. Record demoted headings / seeds in `decisions.notes` so align-propose can explain why they became Sections or navigation instead of Nodes.
141
-
142
- ### Step 4 — Carry ambiguities and orphans
143
-
144
- For each `scan.ambiguous[]`, fill in a best-guess `suggested_type + suggested_tags` on the `new`-side candidates so align-propose can render them. Do not resolve ambiguities here — the user owns that decision. Copy `scan.orphans[]` through; add discoveries from Step 2.
145
-
146
- ### Step 5 — Save the JSON
147
-
148
- Pass one UTF-8 JSON document to `context align --save-scan-decisions -`.
149
- No markdown wrapper, no leading prose.
150
-
151
- ### Step 6 — Self-verify
152
-
153
- - [ ] Every `new_candidates[]` entry has ≥1 mention — if not, back to **Step 3**.
154
- - [ ] Every `entity` `new_candidates[]` has an A or B tag — if not, **Step 3** (re-route via False-Entity smell).
155
- - [ ] Every `ambiguous[]` entry has a candidate that is either `existing` OR a fully-typed `new` — if not, **Step 4**.
156
- - [ ] Output is pure JSON — if any markdown leaked, **Step 5**.
157
- - [ ] No Read / Glob / Grep / Write was used against `WORKSPACE_DIR` — if any, restart with `context workspace` commands.
158
-
159
- Return control to the caller; do not invoke subsequent skills yourself.
160
-
161
- </procedures>
@@ -1,343 +0,0 @@
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>
@@ -1,155 +0,0 @@
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?" |