@c4a/context-cli 0.5.29-alpha.2 → 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.
- package/README.md +71 -34
- package/cli.js +42978 -20206
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json.template +1 -1
- package/plugin/.codex-plugin/plugin.json.template +8 -5
- package/plugin/.cursor-plugin/plugin.json.template +29 -0
- package/plugin/README.md +99 -0
- package/plugin/README_CN.md +97 -0
- package/plugin/assets/icon.svg +3 -0
- package/plugin/assets/logo.svg +3 -0
- package/plugin/commands/align.md +44 -44
- package/plugin/commands/capture.md +27 -11
- package/plugin/commands/compile.md +90 -36
- package/plugin/commands/context.md +7 -4
- package/plugin/commands/drop.md +14 -6
- package/plugin/commands/extract.md +3 -3
- package/plugin/commands/init.md +48 -9
- package/plugin/commands/purge.md +6 -6
- package/plugin/commands/query.md +11 -3
- package/plugin/commands/status.md +4 -2
- package/plugin/skills/skill-align-workflow/SKILL.md +55 -0
- package/plugin/skills/skill-align-workflow/references/candidate-resolution.md +60 -0
- package/plugin/skills/skill-align-workflow/references/density-profile.md +23 -0
- package/plugin/skills/skill-align-workflow/references/gates.md +95 -0
- package/plugin/skills/skill-compile-close/SKILL.md +127 -0
- package/plugin/skills/skill-compile-draft/SKILL.md +409 -0
- package/plugin/skills/skill-context-query/SKILL.md +184 -0
- package/plugin/skills/skill-drop/SKILL.md +190 -0
- package/plugin/skills/skill-semantic-reconcile/SKILL.md +249 -0
- package/scripts/build-plugin.ts +674 -45
- package/templates/aspects/code/aspect.yaml +21 -0
- package/templates/aspects/code/prompt.md +33 -18
- package/templates/aspects/design-system/prompt.md +2 -3
- package/templates/aspects/graphql/prompt.md +2 -2
- package/templates/aspects/openapi/prompt.md +2 -2
- package/plugin/.claude-plugin/plugin.json +0 -16
- package/plugin/.codex-plugin/plugin.json +0 -35
- package/plugin/commands/capture-aspect.md +0 -17
- package/plugin/commands/capture-code.md +0 -25
- package/plugin/skills/align-finalize/SKILL.md +0 -137
- package/plugin/skills/align-propose/SKILL.md +0 -163
- package/plugin/skills/align-scan/SKILL.md +0 -161
- package/plugin/skills/align-scan/references/data-model.md +0 -343
- package/plugin/skills/align-scan/references/user-question-contract.md +0 -159
- package/plugin/skills/compile-close/SKILL.md +0 -122
- package/plugin/skills/compile-draft/SKILL.md +0 -252
- package/plugin/skills/context-query/SKILL.md +0 -166
- package/plugin/skills/drop/SKILL.md +0 -170
- package/plugin/skills/semantic-reconcile/SKILL.md +0 -129
|
@@ -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> --plan` 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,159 +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 explicitly supports the same claim | No | Move support to the surviving source and mark the confidence based on evidence strength |
|
|
49
|
-
| A source is being dropped and another source only appears to support the claim by inference | Yes | Do not silently re-anchor; ask the user or mark the claim as unsupported |
|
|
50
|
-
| A proposed rename changes the user's vocabulary | Yes | Keep the original title / alias |
|
|
51
|
-
| A section kind, edge type, source-ref, or file layout choice is required | No | Agent maps from the user's intent to the model |
|
|
52
|
-
|
|
53
|
-
## Question Templates
|
|
54
|
-
|
|
55
|
-
### Align: standalone topic or detail
|
|
56
|
-
|
|
57
|
-
Context: "I found several payment runtime subsections such as 'Isolation
|
|
58
|
-
model', 'Retry policy', and 'Integration example'. The decision is whether
|
|
59
|
-
people will search these directly later."
|
|
60
|
-
|
|
61
|
-
Question: "How should these payment runtime subsections be organized?"
|
|
62
|
-
|
|
63
|
-
Choices:
|
|
64
|
-
|
|
65
|
-
- "Keep them as parts of payment runtime" — choose this if people normally
|
|
66
|
-
read them while looking at payment runtime.
|
|
67
|
-
- "Make them separate searchable entries" — choose this if people will ask
|
|
68
|
-
for "payment retry policy" or "payment runtime integration example" directly.
|
|
69
|
-
- "Keep only the strongest one separate" — choose this when only one
|
|
70
|
-
subsection deserves direct lookup.
|
|
71
|
-
|
|
72
|
-
### Align: relationship meaning
|
|
73
|
-
|
|
74
|
-
Context: "Portal Shell and Plugin Runtime appear near each other in the source
|
|
75
|
-
documents, but the text does not clearly say how they relate."
|
|
76
|
-
|
|
77
|
-
Question: "What is the business relationship between Portal Shell and Plugin
|
|
78
|
-
Runtime?"
|
|
79
|
-
|
|
80
|
-
Choices:
|
|
81
|
-
|
|
82
|
-
- "Comparable alternatives" — people may compare them or choose one.
|
|
83
|
-
- "Portal Shell is based on Plugin Runtime" — Portal Shell needs Plugin
|
|
84
|
-
Runtime or builds on it.
|
|
85
|
-
- "Same area, no direct relationship" — both belong under the same broader
|
|
86
|
-
topic, but there is no direct link.
|
|
87
|
-
|
|
88
|
-
### Align: repeated references block
|
|
89
|
-
|
|
90
|
-
Do not ask this when the block only lists links or nearby topics. Apply the
|
|
91
|
-
default and summarize:
|
|
92
|
-
|
|
93
|
-
"I found repeated related-links sections in three source documents. They look
|
|
94
|
-
like navigation, so I will not copy them as new content; I will keep the useful
|
|
95
|
-
relationships once in the structure."
|
|
96
|
-
|
|
97
|
-
Ask only if the block contains real prose:
|
|
98
|
-
|
|
99
|
-
Question: "Do these 'related content' sections contain business information we
|
|
100
|
-
must preserve, or are they only navigation?"
|
|
101
|
-
|
|
102
|
-
Choices:
|
|
103
|
-
|
|
104
|
-
- "Only navigation" — use them to understand relationships, not as content.
|
|
105
|
-
- "Preserve the explanation" — keep the useful prose in the relevant topic.
|
|
106
|
-
- "Not sure" — keep only raw-backed prose in the relevant topic and flag the
|
|
107
|
-
uncertainty in the summary.
|
|
108
|
-
|
|
109
|
-
### Align: old or conflicting source
|
|
110
|
-
|
|
111
|
-
Context: "One source describes the old access path, while a newer source
|
|
112
|
-
describes a different path."
|
|
113
|
-
|
|
114
|
-
Question: "Which version should readers trust now?"
|
|
115
|
-
|
|
116
|
-
Choices:
|
|
117
|
-
|
|
118
|
-
- "Use the newer version" — old wording stays only as historical context.
|
|
119
|
-
- "Keep both with dates" — both are valid for different periods or cases.
|
|
120
|
-
- "Use the old version" — the newer source is not authoritative for this
|
|
121
|
-
workspace.
|
|
122
|
-
|
|
123
|
-
### Compile plan: replacing existing content
|
|
124
|
-
|
|
125
|
-
Context: "The new material changes a statement that already exists in the
|
|
126
|
-
knowledge base."
|
|
127
|
-
|
|
128
|
-
Question: "How should the existing statement be handled?"
|
|
129
|
-
|
|
130
|
-
Choices:
|
|
131
|
-
|
|
132
|
-
- "Replace it" — readers should see only the newer statement as current.
|
|
133
|
-
- "Keep both with context" — both statements matter for different cases.
|
|
134
|
-
- "Do not change it" — the new material should not override the current
|
|
135
|
-
knowledge.
|
|
136
|
-
|
|
137
|
-
### Drop: source removal impact
|
|
138
|
-
|
|
139
|
-
Context: "Dropping this source affects 2 topics and 4 pieces of knowledge. Some
|
|
140
|
-
claims can still be supported by other source documents; others cannot."
|
|
141
|
-
|
|
142
|
-
Question: "Proceed with this cleanup?"
|
|
143
|
-
|
|
144
|
-
Choices:
|
|
145
|
-
|
|
146
|
-
- "Proceed" — unsupported claims are marked old, and supported claims move to
|
|
147
|
-
surviving evidence.
|
|
148
|
-
- "Stop" — no files are changed.
|
|
149
|
-
- "Show details first" — list the affected topics before deciding.
|
|
150
|
-
|
|
151
|
-
## Bad to Good
|
|
152
|
-
|
|
153
|
-
| Bad | Good |
|
|
154
|
-
|---|---|
|
|
155
|
-
| "Keep as Section or promote to Concept?" | "Will people search this as its own topic, or only read it inside the parent topic?" |
|
|
156
|
-
| "Choose related_to / depends_on / no edge." | "Are these alternatives, does one build on the other, or are they only in the same area?" |
|
|
157
|
-
| "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." |
|
|
158
|
-
| "Re-anchor section-3 from src-1 to src-2?" | "Another source explicitly supports this claim, so I will keep it; if the support is only inferred, I will ask before changing it." |
|
|
159
|
-
| "Rename slug payment-retry-policy?" | "Should readers see this as 'payment retry policy', or do you prefer another title?" |
|