@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.
- package/README.md +122 -0
- package/cli.js +37711 -0
- package/package.json +18 -0
- package/plugin/.claude-plugin/plugin.json +16 -0
- package/plugin/.claude-plugin/plugin.json.template +16 -0
- package/plugin/.codex-plugin/plugin.json +35 -0
- package/plugin/.codex-plugin/plugin.json.template +35 -0
- package/plugin/commands/align.md +54 -0
- package/plugin/commands/capture-aspect.md +17 -0
- package/plugin/commands/capture-code.md +25 -0
- package/plugin/commands/capture.md +67 -0
- package/plugin/commands/compile.md +89 -0
- package/plugin/commands/context.md +30 -0
- package/plugin/commands/drop.md +17 -0
- package/plugin/commands/extract.md +18 -0
- package/plugin/commands/init.md +95 -0
- package/plugin/commands/purge.md +18 -0
- package/plugin/commands/query.md +13 -0
- package/plugin/commands/status.md +21 -0
- package/plugin/skills/align-finalize/SKILL.md +137 -0
- package/plugin/skills/align-propose/SKILL.md +142 -0
- package/plugin/skills/align-scan/SKILL.md +161 -0
- package/plugin/skills/align-scan/references/data-model.md +343 -0
- package/plugin/skills/align-scan/references/user-question-contract.md +155 -0
- package/plugin/skills/compile-close/SKILL.md +122 -0
- package/plugin/skills/compile-draft/SKILL.md +246 -0
- package/plugin/skills/context-query/SKILL.md +166 -0
- package/plugin/skills/drop/SKILL.md +163 -0
- package/plugin/skills/semantic-reconcile/SKILL.md +106 -0
- package/scripts/build-plugin.ts +70 -0
- package/scripts/postinstall.mjs +183 -0
- package/templates/aspects/code/prompt.md +29 -0
- package/templates/aspects/design-system/prompt.md +27 -0
- package/templates/aspects/graphql/prompt.md +24 -0
- package/templates/aspects/openapi/prompt.md +24 -0
- package/wasm/tree-sitter-tsx.wasm +0 -0
- package/wasm/tree-sitter-typescript.wasm +0 -0
- package/wasm/tree-sitter.wasm +0 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: compile-draft
|
|
3
|
+
description: >
|
|
4
|
+
Per-Node skill of `/context:compile`. For one Node at a time, reads
|
|
5
|
+
the CLI-provided `NodeContext` (planned metadata from `align.md` +
|
|
6
|
+
raw snippets from `bind.yaml` + existing Sections if any), classifies
|
|
7
|
+
every raw fragment into a Section kind via the priority chain, writes
|
|
8
|
+
content + detail + confidence + `source_ref_text`, and emits a
|
|
9
|
+
`CompileDraftAgentOutput` JSON. The CLI applies the actions via
|
|
10
|
+
`context compile --draft <slug> --input <file>`. Activates when
|
|
11
|
+
`/context:compile` iterates across the confirmed align plan.
|
|
12
|
+
tools:
|
|
13
|
+
- Read
|
|
14
|
+
- Bash
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# compile-draft — write Section actions for one Node
|
|
18
|
+
|
|
19
|
+
Classify raw evidence for one Node into `add / update / supersede /
|
|
20
|
+
deprecate / skip` actions; emit JSON; the CLI performs every write.
|
|
21
|
+
|
|
22
|
+
## TL;DR — Non-negotiables
|
|
23
|
+
|
|
24
|
+
- One Node per invocation — `target_node` MUST equal `node.slug`; no cross-Node writes.
|
|
25
|
+
- Agent emits JSON only; no markdown, no direct workspace file writes. The caller passes the JSON to `context compile --draft <slug> --input -`; the caller adds `--save-input` when a durable scratch copy is needed.
|
|
26
|
+
- Default compile sends changed-only NodeContext. Treat `raw_snippets[]` as the complete evidence boundary; never use direct workspace file tools to expand it.
|
|
27
|
+
- If `incremental.status` is `full-context`, draft from the full fallback and preserve the `unknown_inputs[]` reasons in any abort/retry explanation.
|
|
28
|
+
- The CLI may deterministically skip unchanged output or update locator-only evidence before writing. Do not force rewrites to bypass fingerprint skip.
|
|
29
|
+
- Actions are candidate write actions, not final semantic decisions. If raw appears similar to existing knowledge, add only a `reconcile_hint`; semantic-reconcile may ignore it.
|
|
30
|
+
- Pick Section kinds per the [Section kind priority chain](${CLAUDE_PLUGIN_ROOT}/skills/align-scan/references/data-model.md#section-kinds); first match wins.
|
|
31
|
+
- `kind × node.type` must satisfy the [Section mount matrix](${CLAUDE_PLUGIN_ROOT}/skills/align-scan/references/data-model.md#section-mount-matrix); mismatches get rejected at write time.
|
|
32
|
+
- `description` is the bottom of the chain, not the default — walk the [Description anti-abuse gates](#description-anti-abuse-gates) before emitting it.
|
|
33
|
+
- Every action cites raw via `source_ref_text` (verbatim quote from the provided snippets) OR a pre-resolved `source_ref` in the [canonical form](${CLAUDE_PLUGIN_ROOT}/skills/align-scan/references/data-model.md#source_ref-canonical-form); never fabricate a locator or cite navigation-only lines.
|
|
34
|
+
- `content` ≤256 chars; long prose goes in `detail`.
|
|
35
|
+
- For `add` and `supersede.new`, omit optional fields when empty; do not emit `detail: null`. `detail: null` only has "clear existing detail" meaning on `update`.
|
|
36
|
+
- `refers_to_nodes[]` only carries slugs present in the context's glossary or existing Sections; never invent one.
|
|
37
|
+
- `supersede` is for semantic replacement; `update` is for typo / wording fixes; `deprecate` needs a `reason`; `skip` is the honest default when raw adds nothing.
|
|
38
|
+
- FAQ collections attach to the most specific Node (Entity → Concept → Action → Domain fallback); never a standalone "FAQ Concept" container.
|
|
39
|
+
- Output language: `content` / `detail` match the raw material; user-facing abort/retry explanations match the user's conversation language; kind / confidence / slug identifiers / `source_ref` format stay English.
|
|
40
|
+
|
|
41
|
+
<reference>
|
|
42
|
+
|
|
43
|
+
## Input — `NodeContext`
|
|
44
|
+
|
|
45
|
+
```jsonc
|
|
46
|
+
{
|
|
47
|
+
"node": {
|
|
48
|
+
"slug": "...", "type": "entity|action|concept|domain",
|
|
49
|
+
"tags": [...], "title": "...",
|
|
50
|
+
"sources": ["..."], "aliases": ["..."], "summary": "...",
|
|
51
|
+
"planned_sections": ["spec", "..."]
|
|
52
|
+
},
|
|
53
|
+
"existing": { // present if the Node already exists
|
|
54
|
+
"sections": [
|
|
55
|
+
{ "id": "section-1", "kind": "description", "content": "...",
|
|
56
|
+
"detail": "...", "status": "active|deprecated",
|
|
57
|
+
"confidence": "...", "source_ref": "src-1#anchor L10-14",
|
|
58
|
+
"refers_to_nodes": [...] }
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"mentions": [ { "file": "raw/...", "line": 12, "quote": "..." } ],
|
|
62
|
+
"raw_snippets": [ { "file": "raw/...", "line": 10,
|
|
63
|
+
"line_range": [10, 18],
|
|
64
|
+
"quote": "...context block...",
|
|
65
|
+
"mention_quote": "...",
|
|
66
|
+
"source_id": "local:billing",
|
|
67
|
+
"snapshot_file": "raw/local/...",
|
|
68
|
+
"block_locator_id": "h2-api",
|
|
69
|
+
"block_hash": "sha256:...",
|
|
70
|
+
"change_status": "changed" } ],
|
|
71
|
+
"incremental": {
|
|
72
|
+
"mode": "changed-only",
|
|
73
|
+
"status": "changed-only|full-context|unchanged",
|
|
74
|
+
"reason": "source_block_changed|unknown-input|first-compile",
|
|
75
|
+
"changed_blocks": [ { "status": "changed", "source_id": "local:billing", "block_locator_id": "h2-api" } ],
|
|
76
|
+
"unknown_inputs": [ { "scope": "compile-changes", "reason": "section-fingerprints-missing" } ]
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`mentions` = raw positions that named this Node. `raw_snippets` =
|
|
82
|
+
wider context blocks around those positions, or the changed raw blocks
|
|
83
|
+
selected by `context compile --changes`. Never reach outside these —
|
|
84
|
+
they are the evidence floor.
|
|
85
|
+
`source_id` is the source registry id, such as `local:billing`; `src-N`
|
|
86
|
+
aliases only appear inside `source_ref` strings.
|
|
87
|
+
|
|
88
|
+
## Output — `CompileDraftAgentOutput`
|
|
89
|
+
|
|
90
|
+
```jsonc
|
|
91
|
+
{
|
|
92
|
+
"target_node": "<matches node.slug>",
|
|
93
|
+
"actions": [
|
|
94
|
+
{ "op": "add", "kind": "spec",
|
|
95
|
+
"content": "...", "detail": "...",
|
|
96
|
+
"confidence": "verified|confirmed|inferred|speculative",
|
|
97
|
+
"refers_to_nodes": ["..."],
|
|
98
|
+
"source_ref_text": "...",
|
|
99
|
+
"source_ref": "src-1#anchor L12-18"
|
|
100
|
+
},
|
|
101
|
+
{ "op": "update", "target_section_id": "section-3",
|
|
102
|
+
"content": "...", "detail": null, // null clears detail
|
|
103
|
+
"confidence": "...", "refers_to_nodes": null,
|
|
104
|
+
"source_ref_text": "...", "source_ref": "..." },
|
|
105
|
+
{ "op": "supersede", "target_section_id": "section-5",
|
|
106
|
+
"reason": "raw published a new retention value",
|
|
107
|
+
"new": { "kind": "spec", "content": "...", "detail": "...",
|
|
108
|
+
"confidence": "...", "refers_to_nodes": ["..."],
|
|
109
|
+
"source_ref_text": "...", "source_ref": "..." } },
|
|
110
|
+
{ "op": "deprecate", "target_section_id": "section-2", "reason": "..." },
|
|
111
|
+
{ "op": "skip", "reason": "no new evidence in raw snippets" }
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Optional `reconcile_hint` shape for any action:
|
|
117
|
+
|
|
118
|
+
```jsonc
|
|
119
|
+
{
|
|
120
|
+
"reconcile_hint": {
|
|
121
|
+
"suggested_relation": "exact_duplicate|near_duplicate|complement|conflicts|keep_separate",
|
|
122
|
+
"suggested_action": "duplicate_skip|merge_update|keep_separate|ask_user",
|
|
123
|
+
"similar_section_id": "section-3",
|
|
124
|
+
"confidence": 0.72,
|
|
125
|
+
"reason": "The new snippet is close to the existing sandbox isolation Section."
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Hints are recall/explanation aids only. The final relation/action must come
|
|
131
|
+
from `context reconcile prepare` candidates and the semantic-reconcile skill.
|
|
132
|
+
|
|
133
|
+
## Confidence rubric
|
|
134
|
+
|
|
135
|
+
Four legal values; pick per raw evidence strength.
|
|
136
|
+
|
|
137
|
+
| `confidence` | When |
|
|
138
|
+
|---|---|
|
|
139
|
+
| `verified` | Raw provides a directly testable / runnable / observably-validated fact (test output, metric, live check) |
|
|
140
|
+
| `confirmed` | Raw explicitly states the fact in normative voice ("X must …", "the retention is N days") without running a test |
|
|
141
|
+
| `inferred` | You combined ≥2 raw fragments; the derivation is load-bearing but not directly stated |
|
|
142
|
+
| `speculative` | Raw only hints; the Section is a best-effort reading and may not survive review |
|
|
143
|
+
|
|
144
|
+
Don't game the rubric. Compile-close flags Nodes dominated by
|
|
145
|
+
`speculative` Sections.
|
|
146
|
+
|
|
147
|
+
## Description anti-abuse gates
|
|
148
|
+
|
|
149
|
+
Before emitting `{op: add, kind: description}`, walk three gates:
|
|
150
|
+
|
|
151
|
+
1. **Atomicity**: single narrative, or multi-step / multi-row / multi-config? Multi → split into the right kinds (each step → its own `spec` / `warning`, each row → a `comparison` Section, each config → a `spec`).
|
|
152
|
+
2. **Kind-precision**: is a higher-priority kind more accurate? A comparison table belongs in `comparison`; a rule with a verification method belongs in `spec`; explicit risks belong in `warning`; Q+A belongs in `faq`.
|
|
153
|
+
3. **Action threshold**: multi-step fragments that clear the Action bar → emit `op: skip` with a note "evidence warrants sub-Action; re-align needed"; do not create Nodes from compile-draft.
|
|
154
|
+
|
|
155
|
+
If the resulting Node has >50% `description` Sections, treat it as a quality smell: redraft only when the raw snippets actually support more precise Section kinds. Sparse Nodes may legitimately end with one concise `description` or a `skip`; do not invent thin `spec` Sections just to improve the ratio.
|
|
156
|
+
|
|
157
|
+
## Glossary and `refers_to_nodes`
|
|
158
|
+
|
|
159
|
+
When raw mentions a name that overlaps the workspace glossary, put
|
|
160
|
+
that name's slug in `refers_to_nodes[]` for the Section that discusses
|
|
161
|
+
it — do NOT substitute it into the prose. This is how cross-Node
|
|
162
|
+
retrieval works ("which Sections mention React?"). Slugs come from
|
|
163
|
+
the context's existing Sections + glossary; never invent one. A
|
|
164
|
+
Section can reference multiple Nodes (common on `comparison` /
|
|
165
|
+
`decision`).
|
|
166
|
+
|
|
167
|
+
## Supersede vs update
|
|
168
|
+
|
|
169
|
+
| Situation | op |
|
|
170
|
+
|---|---|
|
|
171
|
+
| Same meaning, fixing typo / tightening prose / adding detail | `update` — same `section-N` stays active |
|
|
172
|
+
| New rule replaces old rule (values / policy / spec changed) | `supersede` — old flips to `deprecated`; new gets fresh `section-N+k` |
|
|
173
|
+
| Old rule removed without replacement | `deprecate` (with `reason`) |
|
|
174
|
+
|
|
175
|
+
`supersede` preserves the audit trail so readers see the prior
|
|
176
|
+
policy — critical for specs / decisions / principles.
|
|
177
|
+
|
|
178
|
+
## FAQ attachment priority
|
|
179
|
+
|
|
180
|
+
| FAQ topic | Attach to |
|
|
181
|
+
|---|---|
|
|
182
|
+
| About a concrete thing | That thing's Entity (Section `faq`) |
|
|
183
|
+
| About a concept / mechanism | That Concept |
|
|
184
|
+
| About an action / flow | That Action |
|
|
185
|
+
| Cross-topic / generic workspace FAQ | Domain (fallback only) |
|
|
186
|
+
|
|
187
|
+
Never manufacture a "FAQ container" Concept — it violates the
|
|
188
|
+
Concept identity rules. If a FAQ cluster grows too large, a
|
|
189
|
+
sub-Entity is the correct escape hatch; flag it in `decisions.notes`
|
|
190
|
+
for a re-align pass.
|
|
191
|
+
|
|
192
|
+
</reference>
|
|
193
|
+
|
|
194
|
+
<procedures>
|
|
195
|
+
|
|
196
|
+
### Step 1 — Sanity-check the context
|
|
197
|
+
|
|
198
|
+
Confirm `node.slug` is set; abort if not. Note `node.type` — it caps legal kinds per the [Section mount matrix](${CLAUDE_PLUGIN_ROOT}/skills/align-scan/references/data-model.md#section-mount-matrix). If `existing.sections[]` is non-empty, read it; you need `section-N` ids for update / supersede / deprecate.
|
|
199
|
+
If `incremental.status` is `unchanged`, emit one `skip` action. If it is `full-context`, continue with the full context but keep the fallback reason visible in any user-facing explanation.
|
|
200
|
+
|
|
201
|
+
### Step 2 — Classify each raw snippet
|
|
202
|
+
|
|
203
|
+
For each `raw_snippets[]` entry:
|
|
204
|
+
|
|
205
|
+
1. Walk the [Section kind priority chain](${CLAUDE_PLUGIN_ROOT}/skills/align-scan/references/data-model.md#section-kinds); stop at the first kind whose trigger fires.
|
|
206
|
+
2. Verify the kind against the mount matrix for `node.type`. Mismatch → pick the next legal kind down the chain, or emit `skip` with a reason pointing at a better Node. Never "fall through to description" just to place evidence.
|
|
207
|
+
3. If you land on `description`, walk the [Description anti-abuse gates](#description-anti-abuse-gates). Any gate fires → split or `skip`.
|
|
208
|
+
|
|
209
|
+
### Step 3 — Reconcile with existing Sections
|
|
210
|
+
|
|
211
|
+
For each existing Section:
|
|
212
|
+
|
|
213
|
+
- Raw still supports it unchanged → emit nothing (or one summarising `skip`).
|
|
214
|
+
- Raw refines without changing meaning → `update`.
|
|
215
|
+
- Raw changes meaning (new spec value, reversed decision) → `supersede`.
|
|
216
|
+
- Raw removes supporting evidence → `deprecate` with `reason`.
|
|
217
|
+
|
|
218
|
+
### Step 4 — Build actions
|
|
219
|
+
|
|
220
|
+
For each change from Steps 2-3:
|
|
221
|
+
|
|
222
|
+
1. Write `content` ≤256 chars.
|
|
223
|
+
2. Write `detail` for long-form; omit when `content` is self-contained. For `add` / `supersede.new`, never write `detail: null`; the CLI tolerates it as omitted, but it is not the intended output.
|
|
224
|
+
3. Assign `confidence` per the [Confidence rubric](#confidence-rubric).
|
|
225
|
+
4. Fill `refers_to_nodes[]` per [Glossary and refers_to_nodes](#glossary-and-refers_to_nodes).
|
|
226
|
+
5. Cite evidence via `source_ref_text` (a verbatim substring from `raw_snippets[].quote` or `mentions[].quote`). Prefer a substring from the same snippet/block that supports this Section; do not cite a broad title or navigation line when the claim comes from a deeper block. The CLI resolves to the canonical form and ignores navigation headings as anchors; if you already have `(src-N, anchor, line-range)`, include `source_ref` pre-resolved per the [canonical form](${CLAUDE_PLUGIN_ROOT}/skills/align-scan/references/data-model.md#source_ref-canonical-form).
|
|
227
|
+
|
|
228
|
+
### Step 5 — Emit the JSON
|
|
229
|
+
|
|
230
|
+
Emit one `CompileDraftAgentOutput` document for the caller to pass to `context compile --draft <slug> --input -` (or `context compile --draft <slug> --input - --save-input` when a durable scratch copy is needed). No markdown wrapper, no leading prose, no trailing commentary.
|
|
231
|
+
|
|
232
|
+
### Step 6 — Self-verify
|
|
233
|
+
|
|
234
|
+
- [ ] `target_node` equals `node.slug` — if not, **Step 5**.
|
|
235
|
+
- [ ] Every `add` / `supersede.new` has a legal kind × type combination — if not, **Step 2**.
|
|
236
|
+
- [ ] Every `source_ref_text` appears in `raw_snippets[]` or `mentions[]` — if not, **Step 4**; replace with `skip`.
|
|
237
|
+
- [ ] No `add` / `supersede.new` action contains `detail: null` — omit `detail` instead.
|
|
238
|
+
- [ ] No `description` action that would fail the anti-abuse gates — if any, **Step 2**.
|
|
239
|
+
- [ ] Every `update` / `supersede` / `deprecate` targets a known `section-N` — if not, **Step 3**.
|
|
240
|
+
- [ ] `refers_to_nodes[]` only contains slugs from `existing` / glossary — if not, **Step 4**.
|
|
241
|
+
- [ ] If the Node ends up >50% `description`, verify this is due to sparse evidence; otherwise **Step 2**. Do not create unsupported non-description Sections for ratio reasons.
|
|
242
|
+
- [ ] When raw adds nothing, exactly one `op: skip` with a reason; not `actions: []`.
|
|
243
|
+
- [ ] Changed-only context was not expanded by direct workspace reads — if any were used, restart from the CLI-provided NodeContext.
|
|
244
|
+
- [ ] No Read / Glob / Grep / Write was used against `WORKSPACE_DIR` — if any, restart from the CLI-provided NodeContext.
|
|
245
|
+
|
|
246
|
+
</procedures>
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: context-query
|
|
3
|
+
description: >
|
|
4
|
+
Local knowledge question answering for `/context:query`. The agent uses
|
|
5
|
+
`context query` hit/miss/select results first, supplements only with scoped
|
|
6
|
+
context-query views when needed, and answers with Node slug, Section id,
|
|
7
|
+
and source_ref citations plus explicit gaps for unsupported claims.
|
|
8
|
+
Activates when `/context:query` is invoked or when an agent needs to
|
|
9
|
+
answer a question using local Context workspace knowledge with citations.
|
|
10
|
+
tools:
|
|
11
|
+
- Read
|
|
12
|
+
- Bash
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# context-query — answer from local knowledge with CLI citations
|
|
16
|
+
|
|
17
|
+
Answer a user question from the local Context workspace without reading
|
|
18
|
+
workspace files directly. The CLI is the only source of local knowledge.
|
|
19
|
+
|
|
20
|
+
## TL;DR — Non-negotiables
|
|
21
|
+
|
|
22
|
+
- First tool call must start with `context query --intent description_search --format json --query`. Use `--scope <slug>` only when the user explicitly names a known Node/title/alias.
|
|
23
|
+
- Do not Read, Glob, Grep, or Write `raw/`, `knowledge/`, `archive/`, `decisions/`, or any workspace file to answer the question.
|
|
24
|
+
- Use only `context query` output as evidence. If the CLI returns `miss` or fails, report that result instead of searching files yourself.
|
|
25
|
+
- Every key conclusion must cite `node_slug`, `section_id`, and `source_ref`. `source_ref` follows `${CLAUDE_PLUGIN_ROOT}/skills/align-scan/references/data-model.md#source_ref-canonical-form`.
|
|
26
|
+
- If returned entries do not support a conclusion, mark it as a gap. Do not turn missing local knowledge into a definite answer.
|
|
27
|
+
- If `state` is `select`, choose a candidate only when the user's wording makes it unambiguous; otherwise ask the user which `slug` to use.
|
|
28
|
+
- If recall diagnostics return `blocked: true`, `truncated: true`, or `reason: "broad_query"`, say recall was limited and ask for a narrower Node, term, version, or scope.
|
|
29
|
+
- If the question names a Node title, alias, or slug, state the actual Node slug used in the answer.
|
|
30
|
+
- When the first query is insufficient, supplement only with scoped query views named in the Supplemental context section or anchors from entry `refers_to_nodes`.
|
|
31
|
+
- Output language follows the user's conversation language. CLI flags, JSON keys, slugs, source refs, and Section ids stay as printed.
|
|
32
|
+
|
|
33
|
+
<reference>
|
|
34
|
+
|
|
35
|
+
## Evidence fields
|
|
36
|
+
|
|
37
|
+
Primary evidence comes from the top-level knowledge-query response:
|
|
38
|
+
|
|
39
|
+
| Field | Use |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `state` | `hit`, `miss`, or `select`; controls the next step |
|
|
42
|
+
| `routing.intent` | Confirms which high-level query intent ran |
|
|
43
|
+
| `routing.intent_source` | `explicit` or CLI fallback |
|
|
44
|
+
| `routing.search_path` | `graph_walk`, `section_search`, `impact_graph`, or `recall` |
|
|
45
|
+
| `data.entries[]` | Evidence entries used for answer claims |
|
|
46
|
+
| `entry.node_slug` | Required citation field for Section entries |
|
|
47
|
+
| `entry.section_id` | Required citation field for Section entries |
|
|
48
|
+
| `entry.source_ref` | Required citation field for Section entries |
|
|
49
|
+
| `entry.refers_to_nodes[]` | Optional supplemental anchors |
|
|
50
|
+
| `data.candidates[]` | Disambiguation candidates when `state: "select"` |
|
|
51
|
+
|
|
52
|
+
Supplemental context can come from:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
context query --intent node_search --scope <node_slug> --format json
|
|
56
|
+
context query --intent impact_analysis --scope <node_slug> --format json
|
|
57
|
+
context query --intent node_search --refers-to <node_slug> --format json
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Answer citation shape
|
|
61
|
+
|
|
62
|
+
Use compact citations next to each key claim:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
<claim> [node_slug / section_id / source_ref]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
If multiple Sections support the same claim, cite the strongest one or two.
|
|
69
|
+
Avoid citation-only dumps: summarize what the cited Section supports.
|
|
70
|
+
|
|
71
|
+
## Gap shape
|
|
72
|
+
|
|
73
|
+
Use a visible gap when the CLI evidence cannot support the requested fact:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
Gap: local knowledge did not return evidence for <missing point>.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If the likely cause is stale workflow state, suggest the relevant context
|
|
80
|
+
workflow (`/context:align` or `/context:compile`) only when the CLI output or
|
|
81
|
+
the user's wording indicates newly captured material is not yet knowledge.
|
|
82
|
+
|
|
83
|
+
</reference>
|
|
84
|
+
|
|
85
|
+
<procedures>
|
|
86
|
+
|
|
87
|
+
## Step 1: Query
|
|
88
|
+
|
|
89
|
+
If `$ARGUMENTS` is empty or whitespace-only, ask the user for a question first;
|
|
90
|
+
do not run the query.
|
|
91
|
+
|
|
92
|
+
Run description search first:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
context query --intent description_search --format json --query "$ARGUMENTS"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
If the user explicitly asks for archive comparison, source cleanup audit, or
|
|
99
|
+
semantic reconciliation candidates, use recall with the matching profile:
|
|
100
|
+
|
|
101
|
+
- duplicate / near duplicate / dedupe → `--profile reconcile-dedupe`
|
|
102
|
+
- support check / source support → `--profile reconcile-support`
|
|
103
|
+
- refresh / stale source comparison → `--profile reconcile-refresh`
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
context query --intent recall --format json --profile reconcile-dedupe --query "$ARGUMENTS"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Do not use recall archive profiles for ordinary questions.
|
|
110
|
+
|
|
111
|
+
## Step 2: Parse and gate
|
|
112
|
+
|
|
113
|
+
Parse JSON before answering.
|
|
114
|
+
|
|
115
|
+
- If the command fails, report the CLI failure and stop.
|
|
116
|
+
- If `state` is `miss`, report no local knowledge hit and stop.
|
|
117
|
+
- If `state` is `select`, use `data.candidates[]` to ask for a specific `slug`, unless the user's wording already identifies one candidate.
|
|
118
|
+
- If `data.recall.blocked` or `data.recall.truncated` is true, or `data.recall.reason` is `broad_query`, mark the answer as incomplete, say recall was limited, and ask for a narrower Node, term, version, or scope.
|
|
119
|
+
- Keep a working set of `data.entries[]` fields: `node_slug`, `section_id`, `source_ref`, `content`, and `refers_to_nodes`.
|
|
120
|
+
|
|
121
|
+
## Step 3: Anchor explicit Node mentions
|
|
122
|
+
|
|
123
|
+
If the user's question contains a likely Node title, alias, slug, code symbol,
|
|
124
|
+
or version:
|
|
125
|
+
|
|
126
|
+
1. Prefer candidates whose `reasons[]` include structural or lexical anchor hits.
|
|
127
|
+
2. State the actual Node slug used.
|
|
128
|
+
3. If the candidate set points to multiple plausible slugs, say which slugs were used and keep claims scoped to those slugs.
|
|
129
|
+
|
|
130
|
+
## Step 4: Supplement only when needed
|
|
131
|
+
|
|
132
|
+
Use supplemental commands only when the first query has entries but lacks
|
|
133
|
+
enough surrounding structure to answer the question.
|
|
134
|
+
|
|
135
|
+
Use supplements per the Supplemental context section, only after the first query
|
|
136
|
+
and only for slugs present in returned entries, entry `refers_to_nodes`, or
|
|
137
|
+
the user's explicit question. Use `refers_to_nodes` as extra anchors only when
|
|
138
|
+
they appear in returned Sections. Do not discover extra anchors by reading
|
|
139
|
+
workspace files.
|
|
140
|
+
|
|
141
|
+
## Step 5: Compose
|
|
142
|
+
|
|
143
|
+
Answer only from the parsed query and supplemental outputs.
|
|
144
|
+
|
|
145
|
+
Required response behavior:
|
|
146
|
+
|
|
147
|
+
1. Start with the direct answer if evidence supports one.
|
|
148
|
+
2. Cite every key conclusion with Node slug, Section id, and source_ref.
|
|
149
|
+
3. Include a short "Used nodes" line when the question was anchored by title, alias, slug, code symbol, or version.
|
|
150
|
+
4. Include "Gap:" lines for requested points that are not supported.
|
|
151
|
+
5. Include a blocked / truncated / broad-query note when recall diagnostics report it.
|
|
152
|
+
6. Do not include raw JSON unless the user asks for diagnostics.
|
|
153
|
+
|
|
154
|
+
## Self-check before final answer
|
|
155
|
+
|
|
156
|
+
- [ ] First tool call was `context query --intent description_search --format json --query` or an explicit reconcile `--intent recall` query — if not, go back to **Step 1**.
|
|
157
|
+
- [ ] No direct file Read / Glob / Grep / Write was used against workspace local knowledge — if not, discard that evidence and go back to **Step 1**.
|
|
158
|
+
- [ ] Direct answer is given when evidence supports one — if not, go back to **Step 5**.
|
|
159
|
+
- [ ] Every key conclusion has `node_slug / section_id / source_ref` — if not, go back to **Step 5**.
|
|
160
|
+
- [ ] If the question carried a Node title / alias / slug / code symbol / version, the answer includes a "Used nodes" line — if not, go back to **Step 3** and **Step 5**.
|
|
161
|
+
- [ ] Any unsupported conclusion is marked as a gap — if not, go back to **Step 5**.
|
|
162
|
+
- [ ] `data.recall.blocked`, `data.recall.truncated`, or `data.recall.reason: "broad_query"` is surfaced when present — if not, go back to **Step 2** and **Step 5**.
|
|
163
|
+
- [ ] No raw JSON is included unless the user requested diagnostics — if not, go back to **Step 5**.
|
|
164
|
+
- [ ] Archive entries appear only for explicit reconcile profiles — if not, go back to **Step 1** with the correct profile.
|
|
165
|
+
|
|
166
|
+
</procedures>
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: drop
|
|
3
|
+
description: >
|
|
4
|
+
Source retraction through CLI-owned planning and application. The agent
|
|
5
|
+
calls `context drop --plan` for a structured impact plan, presents the
|
|
6
|
+
user-facing summary for confirmation, runs semantic reconciliation, then
|
|
7
|
+
calls `context drop --apply-plan --decisions` so the CLI archives raw and
|
|
8
|
+
removed knowledge, cleans active knowledge, applies source alias reindexing,
|
|
9
|
+
source stamp, changelog append, semantic ledger write, and verify.
|
|
10
|
+
Activates when `/context:drop` is invoked with a source-id, raw snapshot
|
|
11
|
+
path, or URL.
|
|
12
|
+
tools:
|
|
13
|
+
- Bash
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# drop — retract a source without losing the audit trail
|
|
17
|
+
|
|
18
|
+
Ask the CLI for a structured cleanup plan, confirm the user-visible impact,
|
|
19
|
+
run semantic reconciliation on affected knowledge items, then ask the CLI to
|
|
20
|
+
apply the plan with the confirmed decision document. Do not inspect or mutate
|
|
21
|
+
workspace files directly.
|
|
22
|
+
|
|
23
|
+
`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.
|
|
24
|
+
|
|
25
|
+
## TL;DR — Non-negotiables
|
|
26
|
+
|
|
27
|
+
- Plan + semantic prepare/review + apply are CLI-owned. The agent only presents the plan, asks semantic questions when required, and waits for confirmation.
|
|
28
|
+
- Drop removes affected raw / unsupported knowledge from the active workspace and stores them under `archive/` for restore/audit.
|
|
29
|
+
- Do not Read / Glob / Grep / Write anything under `WORKSPACE_DIR`; all impact analysis and mutation must go through `context drop --plan`, `context reconcile prepare --mode drop`, `context reconcile review`, and `context drop --apply-plan --decisions`.
|
|
30
|
+
- `context drop --plan <source-id|raw-path|url> --format json` resolves source-id, computes affected topics / knowledge items, and reports alias reindex impact.
|
|
31
|
+
- `context drop --apply-plan <plan-file> --decisions <decisions-file> --reason "<text>" --yes` archives affected active content, consumes semantic decisions, removes unsupported Sections / empty Nodes from active knowledge, applies source alias reindexing, writes the semantic ledger, source stamp, changelog append, and verify.
|
|
32
|
+
- User confirmation required unless `--yes` was passed; abort on any non-`y` answer without writing. `--yes` does not skip semantic `ask_user` questions.
|
|
33
|
+
- Confirmation prose follows `${CLAUDE_PLUGIN_ROOT}/skills/align-scan/references/user-question-contract.md`: describe affected topics and claims, not source-ref mechanics.
|
|
34
|
+
- Source evidence, section, and verify rule meanings stay anchored to `${CLAUDE_PLUGIN_ROOT}/skills/align-scan/references/data-model.md`.
|
|
35
|
+
- Output language: impact plan + report match the user's language; CLI commands, flag names, source-ids, comment attributes stay English.
|
|
36
|
+
|
|
37
|
+
<reference>
|
|
38
|
+
|
|
39
|
+
## Plan fields
|
|
40
|
+
|
|
41
|
+
The JSON plan has:
|
|
42
|
+
|
|
43
|
+
| Field | Meaning |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `source_id` | Canonical source id resolved from user input |
|
|
46
|
+
| `resolved_from.kind` | `source-id`, `snapshot-path`, or `url` |
|
|
47
|
+
| `affected_nodes[]` | Topics whose source list contains the dropped source |
|
|
48
|
+
| `affected_nodes[].sections[]` | Knowledge items that require semantic reconciliation before the source is dropped |
|
|
49
|
+
| `affected_nodes[].reindex_sections[]` | Knowledge items whose internal source alias will be renumbered after the source is removed |
|
|
50
|
+
| `affected_nodes[].will_be_sourceless` | Topic may be archived if it has no remaining active content after cleanup |
|
|
51
|
+
| `affected_graph_edges[]` | Explicit graph edges that will be removed because one endpoint leaves active knowledge |
|
|
52
|
+
| `unaffected_references[]` | Topic relationships that mention affected topics but are not source evidence |
|
|
53
|
+
| `summary` | Counts for confirmation and changelog |
|
|
54
|
+
|
|
55
|
+
## User-facing impact summary shape
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
Affected: N topics · M knowledge items
|
|
59
|
+
|
|
60
|
+
<topic title>
|
|
61
|
+
"short claim preview" → remove from active knowledge and archive
|
|
62
|
+
"short claim preview" → keep, supported by another source document
|
|
63
|
+
<topic title>
|
|
64
|
+
"short claim preview" → remove from active knowledge and archive
|
|
65
|
+
|
|
66
|
+
Proceed? [y/N]
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Keep the internal node slug, Section id, and source-ref patch data in your
|
|
70
|
+
working notes for Step 4; show them only if the user asks for implementation
|
|
71
|
+
details.
|
|
72
|
+
|
|
73
|
+
## CLI shapes
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
context drop --plan <source-id|raw-path|url> --format json
|
|
77
|
+
context reconcile prepare --mode drop --drop-plan <plan-file> --format json
|
|
78
|
+
context reconcile review --context <context-file> --decisions <decisions-file> --format json
|
|
79
|
+
context drop --apply-plan <plan-file> --decisions <decisions-file> --reason "<text>" --yes
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The apply command writes a source-specific archive under `archive/sources/`,
|
|
83
|
+
moves affected raw out of active `raw/`, consumes semantic decisions for
|
|
84
|
+
reanchor / remove_unsupported / split_then_reanchor, removes unsupported
|
|
85
|
+
Sections / empty Nodes from active `knowledge/`, flips the source registry entry to
|
|
86
|
+
`status: dropped`, stamps `drop_reason` + `dropped_at` + `archive_path`,
|
|
87
|
+
appends a `[drop]` line to `knowledge/changelog.md`, records
|
|
88
|
+
`decisions/semantic.yaml`, and runs verify. It exits
|
|
89
|
+
non-zero if the source-id is unknown, already dropped, plan shape is invalid,
|
|
90
|
+
the plan is stale, semantic decisions are unresolved/invalid, or verify reports errors.
|
|
91
|
+
|
|
92
|
+
</reference>
|
|
93
|
+
|
|
94
|
+
<procedures>
|
|
95
|
+
|
|
96
|
+
### Step 1 — Parse arguments
|
|
97
|
+
|
|
98
|
+
From `$ARGUMENTS`: `<source-id|raw-path|url>` (required), `--reason <text>` (optional), `--yes` (optional). If the target is missing, stop and ask for the source id or raw snapshot path. If the reason is missing but the user's wording gives a clear reason, infer a concise reason such as `用户主动撤回`; otherwise collect it before Step 4.
|
|
99
|
+
|
|
100
|
+
### Step 2 — Ask CLI for a plan
|
|
101
|
+
|
|
102
|
+
Run `context drop --plan <source-id|raw-path|url> --format json`. Do not inspect
|
|
103
|
+
workspace files yourself. If the CLI reports source-not-found or
|
|
104
|
+
source-already-dropped, relay the error and stop.
|
|
105
|
+
|
|
106
|
+
### Step 3 — Present the impact plan
|
|
107
|
+
|
|
108
|
+
Render the [User-facing impact summary shape](#user-facing-impact-summary-shape)
|
|
109
|
+
from the plan JSON in the user's language. Make clear that dropping a source
|
|
110
|
+
removes listed content from active knowledge but keeps it restorable under
|
|
111
|
+
`archive/` until `context purge`. Mention graph edge cleanup when
|
|
112
|
+
`affected_graph_edges[]` is non-empty. Include the reason that will be stamped; if
|
|
113
|
+
it is still unknown, ask for the reason before continuing. If `--yes`, log
|
|
114
|
+
"auto-confirmed per --yes" and continue. Otherwise wait for `y`; abort on
|
|
115
|
+
anything else without writing.
|
|
116
|
+
|
|
117
|
+
### Step 4 — Reconcile affected knowledge
|
|
118
|
+
|
|
119
|
+
Write the exact plan JSON to a temporary file outside `WORKSPACE_DIR`, then run:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
context reconcile prepare --mode drop --drop-plan <plan-file> --format json
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Invoke `${CLAUDE_PLUGIN_ROOT}/skills/semantic-reconcile/SKILL.md` with that
|
|
126
|
+
prepare payload. Save its decision document outside `WORKSPACE_DIR`, then run
|
|
127
|
+
`context reconcile review --context <context-file> --decisions <decisions-file> --format json`.
|
|
128
|
+
If review returns any `questions[]`, ask the user and rewrite those decisions
|
|
129
|
+
from `ask_user` into one of `reanchor`, `remove_unsupported`, or
|
|
130
|
+
`split_then_reanchor` before continuing. Do not let `--yes` bypass this step.
|
|
131
|
+
|
|
132
|
+
### Step 5 — Apply the plan
|
|
133
|
+
|
|
134
|
+
Write the exact plan JSON and confirmed semantic decision document to temporary
|
|
135
|
+
files outside `WORKSPACE_DIR`, then call:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
context drop --apply-plan <plan-file> --decisions <decisions-file> --reason "<text>" --yes
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Do not call `context mdrive section ...` or `context mdrive node ...` for the
|
|
142
|
+
standard drop flow; `drop --apply-plan --decisions` owns cleanup, ledger write,
|
|
143
|
+
and verify.
|
|
144
|
+
|
|
145
|
+
### Step 6 — Report
|
|
146
|
+
|
|
147
|
+
The apply command already verifies. Run `context source get <source-id>` and
|
|
148
|
+
report in the user's language: topics affected, knowledge items marked
|
|
149
|
+
archived/removed from active knowledge, source alias reindex count, archive
|
|
150
|
+
path, changelog timestamp.
|
|
151
|
+
|
|
152
|
+
### Step 7 — Self-verify
|
|
153
|
+
|
|
154
|
+
- [ ] No Read / Glob / Grep / Write was used against `WORKSPACE_DIR` — if any was used, restart from **Step 2** with CLI-only flow.
|
|
155
|
+
- [ ] `context drop --plan` succeeded before asking the user — if not, **Step 2**.
|
|
156
|
+
- [ ] `context reconcile prepare --mode drop` was run from the exact drop plan — if not, **Step 2**.
|
|
157
|
+
- [ ] `context reconcile review` returned zero `questions[]` before apply; if any question remains, ask the user and regenerate the decisions document.
|
|
158
|
+
- [ ] User confirmed unless `--yes` was passed — if not, abort without writing.
|
|
159
|
+
- [ ] `context drop --apply-plan` exited 0 — if not, surface the CLI error and stop.
|
|
160
|
+
- [ ] `context source get <source-id>` shows the source as dropped — if not, surface the mismatch.
|
|
161
|
+
- [ ] The reported source entry includes `archive_path` — if missing, surface the mismatch.
|
|
162
|
+
|
|
163
|
+
</procedures>
|