@c4a/context-cli 0.5.29-beta.17 → 0.5.29-beta.20

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 (26) hide show
  1. package/README.md +3 -3
  2. package/cli.js +5039 -2615
  3. package/package.json +1 -1
  4. package/plugin/README.md +4 -3
  5. package/plugin/README_CN.md +4 -3
  6. package/plugin/commands/align.md +40 -4
  7. package/plugin/commands/capture.md +17 -1
  8. package/plugin/commands/compile.md +17 -12
  9. package/plugin/commands/query.md +1 -0
  10. package/plugin/skills/skill-align-workflow/SKILL.md +42 -9
  11. package/plugin/skills/skill-align-workflow/references/gates.md +85 -45
  12. package/plugin/skills/skill-compile-close/SKILL.md +3 -4
  13. package/plugin/skills/skill-compile-draft/SKILL.md +106 -305
  14. package/plugin/skills/skill-compile-draft/references/action-domain-gates.md +34 -0
  15. package/plugin/skills/skill-compile-draft/references/notes.md +34 -0
  16. package/plugin/skills/skill-compile-draft/references/refresh-and-update.md +71 -0
  17. package/plugin/skills/skill-compile-draft/references/structural-challenges.md +76 -0
  18. package/plugin/skills/skill-compile-judge/SKILL.md +106 -0
  19. package/plugin/skills/skill-context-query/SKILL.md +137 -92
  20. package/plugin/skills/skill-drop/SKILL.md +2 -3
  21. package/plugin/skills/skill-semantic-reconcile/SKILL.md +67 -183
  22. package/plugin/skills/skill-semantic-reconcile/references/leakage-and-ownership.md +31 -0
  23. package/plugin/skills/skill-semantic-reconcile/references/mode-semantics.md +41 -0
  24. package/plugin/skills/skill-semantic-reconcile/references/scope-review-and-omit.md +60 -0
  25. package/plugin/skills/skill-semantic-reconcile/references/temporal-and-evidence.md +66 -0
  26. package/plugin/skills/skill-semantic-reconcile/references/user-confirmation.md +69 -0
@@ -0,0 +1,34 @@
1
+ # Action and Domain gates
2
+
3
+ Consult this reference when **`node.type` is `action` or `domain`**. For `entity` Nodes, ignore this file and follow the main SKILL.md procedure.
4
+
5
+ ## Action Nodes (`node.type === "action"`)
6
+
7
+ Treat `node.action_gate` as the compile boundary for procedural claims. An Action Node exists because align found both scale and process evidence: at least two meaningful Sections or a child Action, plus steps/phases/trigger-handling-result/role collaboration/repeatable plan evidence. Actor, goal/outcome, repeatability, answerability, trigger, step, and phase claims **must** come from cited `raw_snippets[]` or the structured `action_gate.inference_sources` entries.
8
+
9
+ | Gate block | What it authorizes |
10
+ |---|---|
11
+ | `step_blocks` / `phase_blocks` / cited step snippets | `spec` or `example` Sections for procedure content |
12
+ | `actor_blocks`, `goal_blocks`, `outcome_blocks`, `repeatability_or_plan_blocks` | concise `description` / `spec` Sections when the same source refs are citation-eligible |
13
+ | Empty `trigger_blocks` | **No trigger Section.** Write goal or applicability if supported, but do not fabricate a trigger sentence. |
14
+ | `inference_sources.answerability.ref_nodes` | Becomes `refers_to_nodes[]` when the current Section depends on those Nodes; do **not** summarize those Nodes' facts inside this Node. |
15
+
16
+ If `action_gate` is absent on a Node whose `type` is `action`, treat it as a structural defect — emit a `structure_challenge` (see `references/structural-challenges.md`) instead of inventing process semantics.
17
+
18
+ If the current evidence can only support one thin Section or only a parallel option/config list, do not stretch it into procedure prose. Emit `skip` or `structure_challenge` so align can downgrade it to the owning Entity/Domain Section.
19
+
20
+ ## Domain Nodes (`node.type === "domain"`)
21
+
22
+ Treat `node.domain_gate` as **grouping metadata only**. It explains scope and child grouping; it does **not** authorize new Section facts by itself.
23
+
24
+ - `scope_blocks` may help orient your Section coverage of the Domain's range but are not write authority.
25
+ - `child_refs` belong to the align graph, not to active Sections — do not turn the list into a Section.
26
+ - `grouping_reason` is align-time reasoning. Do **not** turn it into a `description` Section unless citation-eligible raw snippets state the same claim.
27
+
28
+ Recall the mount matrix limit: Domain Nodes allow only `description`, `warning`, `principle`, `decision`, `faq`. A spec / example / comparison / incident / changelog landing here is a kind/type mismatch — drop down the priority chain or `skip`.
29
+
30
+ ## How this slots into the main procedure
31
+
32
+ - **Step 1 — Sanity-check**: after the standard `node.slug` / mount-matrix check, run the action_gate / domain_gate inspection above.
33
+ - **Step 2 — Classify**: respect the gate's authorization boundary when picking kinds.
34
+ - **Step 5 — Self-verify**: confirm no Section was written from evidence the gate disallowed.
@@ -0,0 +1,34 @@
1
+ # Note snippets
2
+
3
+ Consult this reference when **any `raw_snippets[].source_type` is `"note"`**. Note snippets came from `context capture --note` and carry conversation material (revisions, decisions, brainstorms) rather than primary source documents.
4
+
5
+ ## TL;DR
6
+
7
+ Note snippets are **prioritization hints, not write authority**. `note_intent`, `anchored_to[]`, and `revision_kind` may suggest update / supersede / complement / skip, but they never authorize a write without semantic review.
8
+
9
+ ## How to route a note snippet
10
+
11
+ When a `raw_snippets[]` entry has `source_type: "note"`:
12
+
13
+ 1. **Compare against the anchor first.** If `anchored_to[]` names this Node or one of its Sections, treat that target as the candidate for `update` / `supersede` / `add` (as a complement) / `skip`. **Do not create a new Node** from the note title here — that is an align-time concern.
14
+
15
+ 2. **Use `note_intent` and `revision_kind` to bias the action**:
16
+
17
+ | `note_intent` | typical action |
18
+ |---|---|
19
+ | `revision` | `update` or `supersede` against the anchored Section |
20
+ | `decision` | `add` a `decision` Section when no equivalent exists; otherwise `update` |
21
+ | `brainstorm` | usually `skip` unless the brainstorm explicitly confirms a fact the Node should record |
22
+
23
+ `revision_kind` (`replace` / `clarify` / ...) refines the choice within `revision`.
24
+
25
+ 3. **No-write reviewed-no-write case.** If the note says "don't modify active knowledge yet" or the correct outcome is no-write after review, emit `skip` with `source_refs[]` containing the note's `raw_snippets[].source_ref`. This lets semantic review record `reviewed_no_write` instead of treating the skip as an unreviewed no-op.
26
+
27
+ 4. **Bare skip is not allowed for notes.** A bare `skip` (no `source_refs[]`) is only for deterministic no-op cases such as unchanged input or pure navigation. Notes always carry an anchor and an intent; the skip must cite the note's source_ref.
28
+
29
+ ## Where this lives in the main procedure
30
+
31
+ - **Step 2 — Classify**: run the note-first comparison **before** the generic kind priority chain. If the note resolves to `update` / `supersede` / `skip` (reviewed), record the action and move on; do not also process the same note through the generic chain.
32
+ - **Step 5 — Self-verify**: every note snippet was either consumed by an anchored action or carried into a `skip` with `source_refs[]`.
33
+
34
+ Notes never become structure_challenge or pending_ownership_challenge on their own. If a note describes a structural problem (missing Action, wrong parent, etc.), capture the underlying evidence in raw form and emit the challenge from that — see `references/structural-challenges.md`.
@@ -0,0 +1,71 @@
1
+ # Refresh and update
2
+
3
+ Consult this reference when **any** of the following holds:
4
+
5
+ - `existing.sections[]` is non-empty (Node already has active knowledge; this is a refresh, not a first compile).
6
+ - `incremental.status` is `unchanged` or `full-context` (non-default incremental signals).
7
+ - `incremental.locator_only_changes[]` is non-empty (locator-only deltas without content changes).
8
+
9
+ For first compile of a fresh Node with `incremental.status === "changed-only"`, skip this file.
10
+
11
+ ## Incremental status handling
12
+
13
+ | `incremental.status` | What to do |
14
+ |---|---|
15
+ | `changed-only` (default) | Normal path — main SKILL.md procedure applies as written. |
16
+ | `unchanged` | Emit exactly one `skip` action with a brief reason. Do not iterate snippets. |
17
+ | `full-context` | Draft from the full fallback. **Preserve `unknown_inputs[]` reasons** in any abort/retry explanation so the caller sees why the fallback was needed. |
18
+
19
+ The CLI may deterministically skip unchanged output or update locator-only evidence before writing. **Do not force rewrites to bypass fingerprint skip** — those skips are part of the protocol, not a problem to route around.
20
+
21
+ ## Locator-only changes
22
+
23
+ `incremental.locator_only_changes[]` entries always carry `agent_action: "none"` and `handled_by: "compile-close"`. **Do not emit a draft action for those Sections** unless the same Section also appears in `changed_blocks[]` with a real content change.
24
+
25
+ ## Reconciling with `existing.sections[]`
26
+
27
+ When `existing.sections[]` is non-empty, every `section-N` id you read here is a potential `update` / `supersede` / `deprecate` target. Walk the existing Sections in order and decide:
28
+
29
+ | Raw evidence vs existing Section | op |
30
+ |---|---|
31
+ | Raw still supports the existing claim unchanged | Emit nothing (or one summarising `skip`) |
32
+ | Raw clarifies or rephrases without changing meaning | `update` — same `section-N` stays active |
33
+ | Raw changes meaning (new spec value, reversed decision) | `supersede` — old flips to `deprecated`; new gets fresh `section-N+k` |
34
+ | Raw removes the supporting evidence | `deprecate` with `reason` |
35
+
36
+ ### `supersede` vs `update` semantics
37
+
38
+ `supersede` preserves the audit trail so readers see the prior policy — **critical for specs / decisions / principles**. Use `supersede` whenever the new statement *replaces* the old one's content; use `update` only for typo / wording fixes / detail additions that do not change meaning.
39
+
40
+ `deprecate` is for "old rule removed without replacement". It needs a `reason`.
41
+
42
+ ### `update` / `supersede.new` mechanics
43
+
44
+ - `update` keeps the same `section-N` id; provide a new `body` (and optional new `source_refs[]`) but do not include `kind` unless the kind itself is changing.
45
+ - `supersede.new` is a fresh Section; it needs `kind`, `body`, `source_refs[]`, and may carry `refers_to_nodes[]` and `confidence` per the same rules as `add`.
46
+ - `deprecate` only needs `target_section_id` and `reason`. Do not pass `body` or `source_refs[]`.
47
+
48
+ ## Output schema (refresh ops)
49
+
50
+ ```jsonc
51
+ {
52
+ "actions": [
53
+ { "op": "update", "target_section_id": "section-3",
54
+ "body": "...",
55
+ "refers_to_nodes": null,
56
+ "source_refs": ["src-1#api L18-21@c0d4e5f61728"] },
57
+ { "op": "supersede", "target_section_id": "section-5",
58
+ "reason": "raw published a new retention value",
59
+ "new": { "kind": "spec", "body": "...",
60
+ "refers_to_nodes": ["..."],
61
+ "source_refs": ["src-1#limits L30-34@9d1e2f3a4b5c"] } },
62
+ { "op": "deprecate", "target_section_id": "section-2", "reason": "..." }
63
+ ]
64
+ }
65
+ ```
66
+
67
+ ## How this slots into the main procedure
68
+
69
+ - **Step 1 — Sanity-check**: when `existing.sections[]` is non-empty, read every `section-N` id and `status` (active vs deprecated) before classifying snippets. When `incremental.status` is `unchanged`, short-circuit with one `skip`.
70
+ - **Step 2 — Classify**: still walk the kind priority chain for each citation-eligible snippet; the reconciliation table above governs which `op` to emit for snippets that map to an existing Section.
71
+ - **Step 5 — Self-verify**: every `update` / `supersede` / `deprecate` targets a known `section-N` from `existing.sections[]`. If not, return here.
@@ -0,0 +1,76 @@
1
+ # Structural and ownership challenges
2
+
3
+ Consult this reference when the cited evidence **cannot be written as a Section under the current align structure**:
4
+
5
+ - The evidence describes a coherent process that should be its own `action` Node (not a Section here).
6
+ - The evidence implies a missing `depends_on` edge between Nodes.
7
+ - The evidence belongs under a different parent Node.
8
+ - A finalized shared-block split leaves this Node with only secondary, non-citable evidence.
9
+ - A visible `context_only` or secondary-shared block contains facts that need citation, requiring an ownership upgrade.
10
+
11
+ In these cases, do **not** force the content into a Section. Emit a challenge action instead; the CLI stores it as a workflow payload and compile-close exposes it as debt until an align resolution handles it.
12
+
13
+ ## When to challenge vs. when to skip
14
+
15
+ | Situation | Action |
16
+ |---|---|
17
+ | Evidence is a repeatable procedure with steps that clearly warrant a sub-Action | `structure_challenge` with `kind: missing_action_node` |
18
+ | Evidence depends on a Node that the current align graph does not link to this Node | `structure_challenge` with `kind: missing_depends_on_edge` |
19
+ | Evidence belongs under a different parent | `structure_challenge` with `kind: wrong_parent` |
20
+ | A finalized shared block split removed all primary evidence from this Node | `structure_challenge` with `kind: wrong_shared_block_split` |
21
+ | The Node should not exist (its evidence belongs elsewhere) | `structure_challenge` with `kind: extra_action_node` |
22
+ | A `context_only` or secondary-shared block holds facts this Node needs to cite | `pending_ownership_challenge` with `requested_role: "shared"` or `"owned"` |
23
+
24
+ Supported `structure_challenge.kind` values: `missing_action_node`, `extra_action_node`, `wrong_shared_block_split`, `missing_depends_on_edge`, `wrong_parent`.
25
+
26
+ `pending_ownership_challenge.requested_role` is `owned` (the Node should be sole author) or `shared` (the Node should join an existing owners list).
27
+
28
+ ## Required fields
29
+
30
+ ```jsonc
31
+ {
32
+ "op": "structure_challenge",
33
+ "challenge_id": "ch_0001",
34
+ "kind": "missing_action_node",
35
+ "node_slug": "<matches node.slug>",
36
+ "action_tag": "rollout-runbook",
37
+ "summary": "The cited evidence is a repeatable procedure.",
38
+ "source_ref": "src-1#ops L40-55@c0d4e5f61728",
39
+ "reason": "Align must review structure before compile writes process prose."
40
+ }
41
+ ```
42
+
43
+ ```jsonc
44
+ {
45
+ "op": "structure_challenge",
46
+ "challenge_id": "ch_0002",
47
+ "kind": "wrong_shared_block_split",
48
+ "node_slug": "<matches node.slug>",
49
+ "unresolved_target": "rollout-runbook",
50
+ "reason": "The finalized shared block split leaves this Node with only secondary, non-citable evidence."
51
+ }
52
+ ```
53
+
54
+ ```jsonc
55
+ {
56
+ "op": "pending_ownership_challenge",
57
+ "challenge_id": "och_0001",
58
+ "node_slug": "<matches node.slug>",
59
+ "block_id": "2f4b8c1e9a03",
60
+ "requested_role": "shared",
61
+ "reason": "A visible context_only or secondary shared block contains facts that need citation."
62
+ }
63
+ ```
64
+
65
+ Different `kind` values demand different sub-fields. The CLI returns `agent_hints[].correct_shape` on shape errors; follow that hint rather than guessing.
66
+
67
+ ## What these are NOT
68
+
69
+ - **Not a substitute for `skip`** when raw simply has no write-worthy fact for this Node.
70
+ - **Not a Section.** Challenges never appear in active knowledge; they only travel through workflow state.
71
+ - **Not a free upgrade path.** `request_full_text` may expose visible evidence text for inspection, but it does not change citation eligibility. If you need to cite secondary content, emit `pending_ownership_challenge` — do not paraphrase the secondary content into a Section.
72
+
73
+ ## How this slots into the main procedure
74
+
75
+ - **Step 3 — Build actions**: when evidence implies a missing Action, missing `depends_on`, wrong parent, or needed ownership upgrade, emit the corresponding challenge instead of writing a Section.
76
+ - **Step 5 — Self-verify**: no Section write cites a `context_only` or secondary-shared block; if any did, replace the Section with a `pending_ownership_challenge`.
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: skill-compile-judge
3
+ description: >
4
+ Packaged skill invoked by `/context:compile`; not a user slash command. Consumes the full compile prepare payload,
5
+ judges each draft action's source support and relation to listed candidates,
6
+ and emits a compile.judge-decisions.v1 document for `context reconcile review`.
7
+ tools:
8
+ - Bash
9
+ ---
10
+
11
+ # skill-compile-judge — judge compile support and relation
12
+
13
+ Decide whether each prepared compile item is supported by cited raw evidence
14
+ and how it relates to the candidate Sections listed by the CLI. Emit judge
15
+ decisions only; the CLI reviews, applies, and writes every workspace change.
16
+
17
+ ## TL;DR — Non-negotiables
18
+
19
+ - Input is the full compile prepare payload. Compact summaries are only a pointer; if needed, load the full payload with the `workflow_payload.show_command` from `context compile --draft ... --prepare`.
20
+ - Do not inspect workspace storage directly or run ad-hoc scripts to reconstruct candidates. Use only `items[]`, `evidence[]`, `source_support` diagnostics, `candidates[]`, `previous_decisions[]`, and `judge_handoff`.
21
+ - Output exactly one JSON or YAML document with `schema_version: "compile.judge-decisions.v1"` and `decisions[]`.
22
+ - Keep one decision per prepared `item_id`, preserving prepare order.
23
+ - For support, output `support_verdict: supported | weak | unsupported` plus `support_reason`.
24
+ - For relation, output `relation_verdict: new | duplicate | supersede | conflict | merge_into` plus `relation_reason`.
25
+ - Compare only the candidates listed on that item. Do not perform workspace-wide BM25, grep, or source-file searches.
26
+ - Fill `compared_section_ids` with every visible candidate Section id you inspected and set `compared_count` to the total candidate count inspected across pages. If candidates are paged, continue until `compared_count >= candidate_total` before final output.
27
+ - Escape hatch: when an item has no candidates, `relation_verdict: new` with `compared_section_ids: []` and `compared_count: 0` is valid and expected.
28
+ - For `duplicate`, `supersede`, `conflict`, or `merge_into`, set `target_section_id` to the matched candidate Section id.
29
+ - Same `source_ref` can support different Section kinds only when the semantic role differs. Detect and explain same-source-ref multi-kind cases instead of treating them as automatic duplicates.
30
+ - Weak support is a warning-level verdict, not permission to invent missing facts. Unsupported support should normally pair with `conflict` or a later user question rather than a write decision.
31
+
32
+ <reference>
33
+
34
+ ## Output Shape
35
+
36
+ ```yaml
37
+ schema_version: "compile.judge-decisions.v1"
38
+ mode: compile
39
+ decisions:
40
+ - item_id: claim-001
41
+ support_verdict: supported
42
+ support_reason: "The cited raw block explicitly states the same invoice handling behavior."
43
+ relation_verdict: new
44
+ relation_reason: "No listed candidate covers this claim."
45
+ compared_section_ids: []
46
+ compared_count: 0
47
+ ```
48
+
49
+ For a relation against an existing candidate:
50
+
51
+ ```yaml
52
+ schema_version: "compile.judge-decisions.v1"
53
+ mode: compile
54
+ decisions:
55
+ - item_id: claim-002
56
+ support_verdict: supported
57
+ support_reason: "The cited evidence covers the correction."
58
+ relation_verdict: supersede
59
+ relation_reason: "section-3 states the older behavior and should be replaced."
60
+ target_section_id: section-3
61
+ compared_section_ids: [section-3, section-7]
62
+ compared_count: 2
63
+ ```
64
+
65
+ ## Verdict Meanings
66
+
67
+ | field | value | Meaning |
68
+ |---|---|---|
69
+ | `support_verdict` | `supported` | Cited raw evidence covers the claim's hard facts. |
70
+ | `support_verdict` | `weak` | The evidence plausibly supports an ordinary summary, but review may ask for confirmation. |
71
+ | `support_verdict` | `unsupported` | The claim adds facts or boundaries not present in cited raw evidence. |
72
+ | `relation_verdict` | `new` | No listed candidate already covers the proposed knowledge. |
73
+ | `relation_verdict` | `duplicate` | A listed candidate already covers the same claim. |
74
+ | `relation_verdict` | `supersede` | A listed candidate is stale or wrong and should be replaced by the new claim. |
75
+ | `relation_verdict` | `conflict` | The prepared claim and candidate disagree and need user resolution. |
76
+ | `relation_verdict` | `merge_into` | The prepared claim should update or refine one listed candidate. |
77
+
78
+ </reference>
79
+
80
+ <procedures>
81
+
82
+ ### Step 1 — Load Full Prepare Payload
83
+
84
+ If the caller gave compact prepare output, use its workflow payload command to
85
+ load the full `prepare` payload. Do not infer missing candidates from memory.
86
+
87
+ ### Step 2 — Judge Support
88
+
89
+ For each item, read the proposed content and cited evidence. Use
90
+ `source_support` only as a diagnostic hint; final support is your semantic
91
+ verdict from the cited raw evidence.
92
+
93
+ ### Step 3 — Judge Relation
94
+
95
+ Compare the proposed claim against each listed candidate. Track every
96
+ visible candidate Section id in `compared_section_ids`, and set
97
+ `compared_count` to the total candidate count inspected across pages. If the
98
+ candidate list is empty, emit `new` with an empty compared list and
99
+ `compared_count: 0`.
100
+
101
+ ### Step 4 — Emit Judge Decisions
102
+
103
+ Return only the `compile.judge-decisions.v1` document. The caller passes it
104
+ directly to `context reconcile review --decisions -`.
105
+
106
+ </procedures>