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

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c4a/context-cli",
3
- "version": "0.5.29-beta.17",
3
+ "version": "0.5.29-beta.18",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "context": "./cli.js"
@@ -11,7 +11,7 @@ Run the beta.8 align workflow. `/context:align` is the user entrypoint; internal
11
11
  Keep the prompt shape stable: read fixed schema/protocol first, then existing knowledge lookup, then the current source-specific payload. Do not reorder CLI JSON, add timestamps, or invent scratch paths.
12
12
 
13
13
  1. Run `context align --scan --format json`. Use the returned workflow payload name, scope id, digest, and `next_command` / `show_command` fields as the continuation handles.
14
- - If the align-segments payload includes `generation_policy`, use it as the language contract for generated Node titles, summaries, rationale prose, and planned Section wording. Preserve product names, code identifiers, slugs, flags, and citation tokens exactly when needed.
14
+ - If the align-segments payload includes `generation_policy`, use it as the language contract for generated Node titles, summaries, rationale prose, and planned Section wording. Preserve product names, code identifiers, slugs, flags, `block_id` handles, and citation tokens exactly when needed.
15
15
  2. Read schema and payloads through CLI only:
16
16
  - `context schema align-segments`
17
17
  - `context schema align-coarse-read`
@@ -28,10 +28,11 @@ Keep the prompt shape stable: read fixed schema/protocol first, then existing kn
28
28
  4. Submit generated workflow payloads directly through stdin, preferably as JSON. Use YAML schemas only for reading examples when helpful; generated artifacts should avoid YAML quoting/indentation failure loops. Do not create `/tmp` or workspace scratch files for align payloads. The CLI owns ids, reducer validation, workflow payload storage, and mechanical aggregate. You own semantic discovery, Node type/tag decisions, structure decisions, and user-facing questions.
29
29
  - Save coarse-read with `context align --coarse-read - --format json`.
30
30
  The latest `align-coarse-read` payload is only the most recent checkpoint; durable multi-source reading notes are stored under `align-candidate-ledger.source_readings`.
31
- Submit coarse-read payloads serially within one workflow; workflow payload writes are not a parallel ingestion API.
31
+ For multiple sources, submit one envelope with `coarse_reads[]`; single-source payloads remain valid.
32
32
  - Submit each candidate batch with `context align --ops - --format json`.
33
- - After the first batch, pass the current ledger digest as `--ledger-digest <digest>` so stale batches are rejected.
33
+ - `--ledger-digest <digest>` is optional. Usually omit it and let the CLI merge against the current ledger; pass it only when you intentionally want stale-batch rejection for a high-assurance retry.
34
34
  - Read the resulting payloads with `context workflow show --payload align-candidate-ledger --view ledger --unwrap --format json` and `context workflow show --payload align-candidate-aggregate --view aggregate --unwrap --format json`. To revisit one source's coarse-read notes, add `--source <source-id>` to the ledger view; candidates do not carry source ids, so add `--status` or `--candidate-id` only when you also need candidate rows.
35
+ - Review `anomaly_signals[]` as warnings: fix clear mistakes with another ops batch, otherwise continue to finalize and carry the warning rationale in your final decision/report.
35
36
  5. If any CLI command returns `agent_hints[]`, follow those hints before retrying. Legacy-protocol hints mean the submitted payload or schema name is retired; switch to the beta.8 schema named in the hint instead of adapting old fields.
36
37
  6. Finalize only with `align-structure-decision`:
37
38
 
@@ -39,6 +40,19 @@ Keep the prompt shape stable: read fixed schema/protocol first, then existing kn
39
40
  context align --finalize - --digest <segments-digest>
40
41
  ```
41
42
 
43
+ If finalize returns an `align-finalize-draft` payload, patch that saved draft with JSON Pointer paths from the returned issues instead of resubmitting the full document:
44
+
45
+ ```json
46
+ {
47
+ "schema_version": "align.finalize-patch.v1",
48
+ "operations": [
49
+ { "op": "replace", "path": "/block_ownership/3/primary_owner", "value": "rspack" }
50
+ ]
51
+ }
52
+ ```
53
+
54
+ Submit the patch with `context align --finalize-patch - --payload-digest <draft-digest> --format json`.
55
+
42
56
  If `align-segments.incremental.mode` is `incremental`, the finalize step is a delta merge: submit only the Nodes and block ownership supported by the current scanned sources, and reference previous finalized Nodes when they are parents, dependencies, domain children, owners, or visibility targets. Absence of an old Node or edge is not a delete signal. Do not redeclare an old parent/domain just to attach a new child. `sections[].owner` must be a Node declared in the current payload; previous finalized Nodes can be referenced structurally but do not receive new section plans from this incremental payload. Existing or previously removed Node slugs cannot change `node_type`; `context align --scan --full` does not bypass that guard. Use a new slug for a different type, or retire the old slug through `context drop` or explicit structure correction before re-aligning.
43
57
 
44
58
  For large finalize decisions, use `block_ownership_defaults[]` instead of enumerating every block. Each default names a `source_id` plus the same ownership fields as a block-level entry except `block_id`; the CLI expands it across that source's coverable blocks. Put only exceptions in `block_ownership[]`, which override defaults for their `block_id`. Keep the payload on stdin; do not generate temp JSON files just to list hundreds of ownership rows.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: "Capture URLs, local Markdown, source code, stdin path lists, inbox/refresh sources, or conversation notes as Context sources."
3
3
  argument-hint: "[url | ./path.md [./more.md...] | --code [path] | --stdin | --inbox | --refresh | note]"
4
- allowed-tools: Bash(context:*, brew:*, curl:*, sh:*, scoop:*, choco:*, lark-cli:*), WebFetch
4
+ allowed-tools: Bash(context:*, bun:*, brew:*, curl:*, sh:*, scoop:*, choco:*, lark-cli:*), WebFetch
5
5
  ---
6
6
 
7
7
  <!--
@@ -14,6 +14,18 @@ length exemption for self-contained slash commands.
14
14
 
15
15
  Capture is entirely CLI-driven — your role is to route the right `context capture` invocation and relay its output. Never hand-write captured source snapshots: the CLI owns normalisation (NFC, BOM strip, line endings) and the `content_hash` contract, so any manual edit breaks idempotency.
16
16
 
17
+ ### Code capture dependency preflight
18
+
19
+ Before any `context capture --code` command, including `--plan`, refresh, or explicit `--module` runs, verify that the TypeScript extraction plugin is installed in the same global package environment as the `context` executable:
20
+
21
+ ```bash
22
+ sh -c 'CTX_BIN="$(command -v context)" && node -e "const { createRequire } = require(\"node:module\"); createRequire(process.argv[1]).resolve(\"@c4a/extract-ts\");" "$CTX_BIN"'
23
+ ```
24
+
25
+ If the check fails, stop the capture task. Tell the user to install the plugin globally with `bun install -g @c4a/extract-ts` (or the exact version from a CLI `agent_hints[].command` if present), then rerun their original `context capture --code ...` command. Do not inline `@c4a/extract-ts`, do not hand-write code snapshots, and do not continue with partial capture.
26
+
27
+ Invocation note: code capture does not run through `npx`. `context capture --code` resolves `@c4a/extract` and `@c4a/extract-ts` from the installed `@c4a/context-cli` package using Node package resolution, prepares `.context/.cache/aspect-runners/<cacheKey>/c4a-extract-code.mjs`, and executes that wrapper directly. The plugin must therefore be available to the same global install that provides `context`.
28
+
17
29
  ### Route by argument
18
30
 
19
31
  - `$ARGUMENTS` starts with `http://` / `https://` → `context capture $ARGUMENTS` (feishu URLs need `lark-cli`).
@@ -59,6 +71,8 @@ Never suggest `/context:compile` when no align plan exists or when the only acti
59
71
 
60
72
  ### Missing dependency recovery
61
73
 
74
+ If the CLI returns `agent_hints[]` with `code: "capture-code-typescript-plugin-missing"`, stop. Surface the hint to the user and use `agent_hints[0].command` as the install command if the user asks you to install it for them.
75
+
62
76
  If the CLI prints a missing-dependency error like `lark-cli not installed`, walk the user through installation:
63
77
 
64
78
  1. Ask once up-front whether to proceed with install. If no → stop and tell the user to install manually from the tool's official README, then re-run.
@@ -26,7 +26,7 @@ Modes:
26
26
  - **Default (no flag)** — draft plan + semantic reconciliation + apply writes + close.
27
27
  - **`--plan`** (opt-in when `$ARGUMENTS` contains `--plan`) — per Node, run `context compile --draft <slug> --input - --plan` so the CLI validates stdin draft content without writing active knowledge; surface a user-facing change list (new knowledge, replaced knowledge, unchanged knowledge, and why) while keeping internal Section ids / source refs in details only when needed, then **stop at the end of the per-Node loop — do NOT run close**. The user re-runs `/context:compile` without `--plan` to apply; that run does the real writes + close.
28
28
 
29
- Language policy: your explanatory prose and final reports follow the user's conversation language. Knowledge drafts, Section `content` / `detail`, and Node-facing summaries follow `NodeContext.generation_policy.language` when the CLI provides it; preserve product names, code identifiers, CLI flags, slugs, `source_ref` tokens, and exact quoted evidence as printed. CLI stdout/stderr, the canonical `processing <slug>` lines, paths, slugs, source refs, issue codes, flags, and command names stay as printed.
29
+ Language policy: your explanatory prose and final reports follow the user's conversation language. Compile draft `body`, Node-facing summaries, and generated knowledge follow `NodeContext.generation_policy.language` when the CLI provides it; preserve product names, code identifiers, CLI flags, slugs, `block_id` / `source_ref` tokens, and exact quoted evidence as printed. CLI stdout/stderr, the canonical `processing <slug>` lines, paths, slugs, block ids, source refs, issue codes, flags, and command names stay as printed.
30
30
 
31
31
  Stable prompt/output policy: keep fixed protocol, schema, mount matrix, and workspace lookup context before per-Node payloads. For repeated Nodes, use the same command order and consume CLI JSON as-is. Do not add current timestamps, random ids, storage paths, or host absolute paths to draft payloads or reports unless the CLI explicitly returned them as semantic workspace facts.
32
32
 
@@ -62,14 +62,14 @@ Per-Node loop:
62
62
 
63
63
  Process Nodes sequentially. `/context:compile` may cover a multi-Node workset, but each Node must finish its own `context → draft → prepare → review → apply` loop before you apply another Node. Do not run multiple Node draft/reconcile/apply chains in parallel or bury several Node failures inside one shell batch. Capture/align can be broad; compile write decisions must be per-Node and complete.
64
64
 
65
- 1. For every workset Node, run `context compile --context <slug> --format json`. If the refreshed-source loop applied any source, append the same `--ignore-source <source-id>` flags used for the filtered workset. The JSON stdout is a compact summary with `node_context_payload.scope_id` and `node_context_payload.digest`. First inspect citation handles with `context workflow show --payload node-context --scope <scope-id> --digest <digest> --view source-refs --unwrap --format json` or `context compile --source-refs <slug> --format json`; only read the full durable NodeContext once when you are ready to pass its returned `.value` object to the draft skill. NodeContext is derived only from finalized ownership: `primary_evidence` and citation-eligible `shared_evidence` may be cited; `context_only` and every secondary shared snippet are background only and must not be cited. If NodeContext includes `generation_policy`, apply it to every generated title, summary, Section content/detail, and user-facing draft explanation; do not default to English scaffolding when the workspace language is not English. `context compile --context <slug> --request-full-text <block_id> --format json` may expose full text for inspection, but it does not promote secondary shared evidence into citation eligibility; if the block should support this Node, emit `pending_ownership_challenge` or `structure_challenge` instead of writing a Section. When the workset requires full context, the NodeContext payload has `incremental.status: "full-context"` with the `unknown_inputs[]` reasons from the same entrypoint. `incremental.locator_only_changes[]` entries with `agent_action: "none"` are close-time maintenance only; do not draft them. The CLI stores the durable NodeContext and coverage candidates as workflow payloads, not root scratch files. Do not expand the context with direct file tools; the NodeContext payload is the evidence boundary. Prefer citation-eligible refs for citeable evidence and treat `context_only` as background. Do not repeatedly slice saved NodeContext JSON manually; use the compact `source-refs`, `summary`, and coverage views returned by the CLI.
66
- 2. Invoke packaged `context:skill-compile-draft` and follow its procedure to emit draft JSON. Do not reconstruct the draft shape from memory. Cite raw via `source_refs: [...]` chosen from `raw_snippets[].source_ref`; use a single-element array for one citation. The CLI rejects singular `source_ref` and quoted-evidence fields with canonical repair hints. If a note or changed raw snippet should be reviewed but intentionally not written, emit `op: "skip"` with the relevant `source_refs: [...]`; a bare skip is only for deterministic no-op cases. If a NodeContext contains only navigation or placeholder evidence (`Parent` / `Children` / `Related` / `Relations`, "no detailed content", etc.), emit `skip`; do not create a low-value `description` Section from that navigation line just to satisfy the workflow.
65
+ 1. For every workset Node, run `context compile --context <slug> --format json`. If the refreshed-source loop applied any source, append the same `--ignore-source <source-id>` flags used for the filtered workset. The JSON stdout is a compact summary with `node_context_payload.scope_id` and `node_context_payload.digest`. First inspect citation handles with `context workflow show --payload node-context --scope <scope-id> --digest <digest> --view source-refs --unwrap --format json` or `context compile --source-refs <slug> --format json`; only read the full durable NodeContext once when you are ready to pass its returned `.value` object to the draft skill. NodeContext is derived only from finalized ownership: `primary_evidence` and citation-eligible `shared_evidence` may be cited; `context_only` and every secondary shared snippet are background only and must not be cited. If NodeContext includes `generation_policy`, apply it to every generated title, summary, draft `body`, and user-facing draft explanation; do not default to English scaffolding when the workspace language is not English. `context compile --context <slug> --request-full-text <block_id> --format json` may expose full text for inspection, but it does not promote secondary shared evidence into citation eligibility; if the block should support this Node, emit `pending_ownership_challenge` or `structure_challenge` instead of writing a Section. When the workset requires full context, the NodeContext payload has `incremental.status: "full-context"` with the `unknown_inputs[]` reasons from the same entrypoint. `incremental.locator_only_changes[]` entries with `agent_action: "none"` are close-time maintenance only; do not draft them. The CLI stores the durable NodeContext and coverage candidates as workflow payloads, not root scratch files. Do not expand the context with direct file tools; the NodeContext payload is the evidence boundary. Prefer citation-eligible refs for citeable evidence and treat `context_only` as background. Do not repeatedly slice saved NodeContext JSON manually; use the compact `source-refs`, `summary`, and coverage views returned by the CLI.
66
+ 2. Invoke packaged `context:skill-compile-draft` and follow its procedure to emit draft JSON. Do not reconstruct the draft shape from memory. Section writes use `body` plus optional `rewrite`; new Sections do not need `section_id`. Cite raw via `source_refs: [...]` chosen from `raw_snippets[].source_ref`; use a single-element array for one citation. The CLI rejects singular `source_ref` and quoted-evidence fields with canonical repair hints. If a note or changed raw snippet should be reviewed but intentionally not written, emit `op: "skip"` with the relevant `source_refs: [...]`; a bare skip is only for deterministic no-op cases. If a NodeContext contains only navigation or placeholder evidence (`Parent` / `Children` / `Related` / `Relations`, "no detailed content", etc.), emit `skip`; do not create a low-value `description` Section from that navigation line just to satisfy the workflow.
67
67
  3. Fast path: pass the draft to `context compile --node-cycle <slug> --input - --accept-safe-defaults --format json`. This validates the draft, prepares reconcile, reviews mechanically safe defaults, and applies only when no semantic judgment remains. If stdout returns `status: "applied"`, continue to the next Node. If it returns `status: "review-required"`, use the returned `prepare` / `review` handles and continue with the manual path below; do not rerun the earlier context/source-ref reads.
68
- 4. Manual path: pass the draft to `context compile --draft <slug> --input - --plan --prepare --format json`. This validates schema, source refs, and mount matrix, stores the compile draft as a workflow payload, and prepares the semantic reconcile payload without writing active knowledge. Default stdout is a compact prepare summary; use it to inspect readiness and capture `workflow_payload.digest` / `scope_id`. If semantic judgment is needed, load the full prepare payload with `context workflow show --payload prepare --scope <scope-id> --digest <digest> --unwrap --format json` and feed that full payload to packaged `context:skill-semantic-reconcile`. For triage-only inspection, use `context workflow show --payload prepare --scope <scope-id> --digest <digest> --view issues --unwrap --format json`; add `--status unsupported`, `--status weak`, `--item-id <claim-id>`, or `--page-size <n>` instead of expanding huge prepare payloads. If all pending items are mechanically safe defaults, prefer `context reconcile review --prepare-digest <digest> --scope <scope-id> --accept-safe-defaults --view status` instead of invoking the skill. If most items are safe and only a few need explicit decisions, combine `--accept-safe-defaults` with `--decisions -` and submit only those explicit decisions. If the CLI returns draft revision hints, use `context compile --draft-status <slug> --format json` and `context compile --draft-patch <slug> --input - --payload-digest <digest> --plan` so only the affected action is revised, then rerun `context compile --draft ... --plan --prepare`. On hard rejection before a draft session exists, read the error verbatim, fix the draft via the skill's self-verify, and retry up to 3 times.
69
- 5. Review the prepared context before accepting defaults. If it reports unsupported `source_support`, repair/split evidence before review; unsupported items cannot be accepted with `accept_default` or user confirmation. Treat `temporal_prior` and candidate `temporal_disposition` as context for your rationale only; they do not change `default_decision` or make merge/supersede mechanically safe. If the prepare output has `items: []`, use its `next_decisions_template` as the decisions document for review; do not pass the whole prepare context as `--decisions`.
68
+ 4. Manual path: pass the draft to `context compile --draft <slug> --input - --plan --prepare --format json`. This validates schema, source refs, and mount matrix, stores the compile draft as a workflow payload, and prepares the semantic reconcile payload without writing active knowledge. Default stdout is a compact prepare summary; use it to inspect readiness and capture `workflow_payload.digest` / `scope_id`. If semantic judgment is needed, load the full prepare payload with `context workflow show --payload prepare --scope <scope-id> --digest <digest> --unwrap --format json` and feed that full payload to packaged `context:skill-compile-judge`. The judge output is the decision input for `context reconcile review`; keep `skill-semantic-reconcile` for refresh/drop or non-compile reconcile flows. For triage-only inspection, use `context workflow show --payload prepare --scope <scope-id> --digest <digest> --view issues --unwrap --format json`; add `--status unsupported`, `--status weak`, `--item-id <claim-id>`, or `--page-size <n>` instead of expanding huge prepare payloads. If all pending items are mechanically safe defaults, prefer `context reconcile review --prepare-digest <digest> --scope <scope-id> --accept-safe-defaults --view status` instead of invoking the skill. If most items are safe and only a few need explicit decisions, combine `--accept-safe-defaults` with `--decisions -` and submit only those explicit decisions. If the CLI returns draft revision hints, use `context compile --draft-status <slug> --format json` and `context compile --draft-patch <slug> --input - --payload-digest <digest> --plan` so only the affected action is revised, then rerun `context compile --draft ... --plan --prepare`. On hard rejection after a draft session is saved, read `context compile --draft-status <slug> --format json`, patch only the failed actions, and retry.
69
+ 5. Review the prepared context before accepting defaults. Treat lexical `source_support` as a diagnostic; final support and relation judgment belong to `context:skill-compile-judge`, which must compare only listed candidates and include the same-source-ref multi-kind semantic-role check. Treat `temporal_prior` and candidate `temporal_disposition` as context for your rationale only; they do not change `default_decision` or make merge/supersede mechanically safe. If the prepare output has `items: []`, use its `next_decisions_template` as the decisions document for review; do not pass the whole prepare context as `--decisions`.
70
70
  - If `agent_hints[]` contains `compact-source-low-coverage` or `dense-source-low-coverage`, return to the same compile draft and add actions for the suggested uncovered evidence before semantic review. Treat the reported coverage count (`covered/total`, remaining snippets) as a required self-check, not polish. A supported first quote only proves that one action is valid; it does not prove the Node is complete.
71
- - If close later reports `coverage-high-signal-unresolved` for a dense document and every unresolved candidate in that node-scoped payload is intentionally excluded for the same reason, use `context compile --coverage-skip-unresolved --coverage-disposition-node <slug> --payload-digest <digest> --reason "<reason>"` instead of hand-writing a long disposition JSON. Use targeted `coverage-disposition` only when candidates need different outcomes.
72
- 6. Pass the skill output to `context reconcile review --prepare-digest <prepare-digest> --decisions - --view status`. Use stdout for compact readiness/issues/questions. If questions are returned, ask the user in business language and convert unresolved `ask_user` items into final actions before applying. For `support_confirmation`, use `question.group_key` when present: group only questions that share that key and are all ordinary summary/compression checks; ask once with a compact list of claims and cited evidence. If the user confirms the group, keep each final write action and add `decided_by: user`. Do not group questions that add new facts, have missing hard facts, or have different source/evidence boundaries. If review reports unsupported evidence, choose or split the draft `source_refs[]` so each action is independently supported (use `source_support.evidence_block_candidates` to pick prepared evidence blocks or split unrelated claims), then rerun review. For `scope_review_required`, run `context:skill-semantic-reconcile` once more over the prepare context and current decisions before asking the user; if it still cannot resolve the scope, ask the user. For `omit_confirmation`, ask the user; only a confirmed no-write answer may become `action: omit` with `decided_by: user`. Never mark `decided_by: user` on your own; auto mode or permission to continue is not user confirmation.
71
+ - If close later reports unresolved coverage, first use `context compile --context <slug> --cover-uncovered-only --format json` to start a targeted repair draft that contains only unresolved candidates. If every unresolved candidate in that node-scoped payload is intentionally excluded for the same reason, use `context compile --coverage-skip-unresolved --coverage-disposition-node <slug> --payload-digest <digest> --reason "<reason>"` instead of hand-writing a long disposition JSON. Use targeted `coverage-disposition` only when candidates need different outcomes.
72
+ 6. Pass the judge skill output to `context reconcile review --prepare-digest <prepare-digest> --decisions - --view status`. Use stdout for compact readiness/issues/questions. If questions are returned, ask the user in business language and convert unresolved `ask_user` items into final actions before applying. For `support_confirmation`, use `question.group_key` when present: group only questions that share that key and are all ordinary summary/compression checks; ask once with a compact list of claims and cited evidence. If the user confirms the group, keep each final write action and add `decided_by: user`. Do not group questions that add new facts, have missing hard facts, or have different source/evidence boundaries. If review reports unsupported evidence, revise the draft or rerun the judge with corrected source_refs rather than forcing a decision. For `scope_review_required`, run `context:skill-semantic-reconcile` once more over the prepare context and current decisions before asking the user; if it still cannot resolve the scope, ask the user. For `omit_confirmation`, ask the user; only a confirmed no-write answer may become `action: omit` with `decided_by: user`. Never mark `decided_by: user` on your own; auto mode or permission to continue is not user confirmation.
73
73
  7. Default mode only: run plain `context reconcile apply` after `context reconcile review --prepare-digest ... --view status` returns `ready_to_apply: true`; the CLI applies the unique ready review for the current workflow scope. If questions were answered, rerun review on the updated decisions, then run `context reconcile apply` again. This writes active knowledge, verifies, and records the semantic ledger. In `--plan` mode, stop after review and report the not-written decisions.
74
74
  8. Persistent failure → stop and surface the full rejection list; never edit rendered files to bypass.
75
75
 
@@ -110,7 +110,7 @@ context compile --draft billing-api --input - --plan --prepare --format json <<'
110
110
  {
111
111
  "op": "skip",
112
112
  "reason": "reviewed; intentionally not written",
113
- "source_refs": ["src-1#reviewed-note L12-14@ab12cd34ef56"]
113
+ "source_refs": ["src-1#reviewed-note L12-14@7a6f4c9d2e10"]
114
114
  }
115
115
  ]
116
116
  }
@@ -19,7 +19,7 @@ Run the align workflow through the CLI-owned beta.8 payload chain: scan segments
19
19
  - Retired payloads include candidate tables, decision patches, and full-tree finalize documents.
20
20
  - Existing knowledge is the lookup registry. Use `context mdrive glossary match <name>` / `context mdrive node list --format json` for term/entity reuse; do not read `knowledge/**` and do not create a separate registry file.
21
21
  - Keep cache-friendly prompt order: fixed protocol and schemas first, existing knowledge lookup second, source-shared payload views third, current candidate batch last. Preserve CLI JSON order and do not add timestamps, random ids, scratch paths, or host paths to generated payloads.
22
- - `align-segments.generation_policy` is the workspace language contract for generated Node titles, summaries, rationale prose, and planned Section wording. Preserve product names, code identifiers, slugs, flags, and `source_ref` tokens exactly when needed.
22
+ - `align-segments.generation_policy` is the workspace language contract for generated Node titles, summaries, rationale prose, and planned Section wording. Preserve product names, code identifiers, slugs, flags, `block_id` handles, and `source_ref` tokens exactly when needed.
23
23
  - Gate rules for `domain` and `action` proposals are in `references/gates.md`.
24
24
  - Coarse-read density and neutral signal rules are in `references/density-profile.md`.
25
25
  - Candidate anomaly handling, `label_hint`, and `llm_slug_hint` reference rules are in `references/candidate-resolution.md`.
@@ -33,9 +33,9 @@ Use this only inside `/context:align`.
33
33
  1. Start from `align-segments`.
34
34
  2. Inspect it through compact CLI views, not shell parsing: `context workflow show --payload align-segments --view segment --unwrap --format json`, `--view blocks`, and `--view windows`. Read and obey `generation_policy` before authoring any title, summary, rationale, or planned Section wording. The default `blocks` view is a structure summary; drill into content with `--window <window-id>`, `--heading <prefix>`, `--range <start:end>`, or `--token-budget <n>`. `--unwrap` only removes the workflow metadata envelope; it does not change summary/detail behavior.
35
35
  3. Query existing knowledge for reusable names before proposing new term/service/system/action Nodes. `context mdrive glossary match <name>` returns deterministic `match.kind`, `match.matched`, and `match.rank`; exact title/slug/alias hits should usually become references to the existing Node, not duplicate candidates.
36
- 4. Produce coarse-read anchors and neutral content signals as JSON. Pick `density_profile` using `references/density-profile.md`; content signals describe text shape only, not final Node type. Submit the artifact through stdin with `context align --coarse-read - --format json`. The latest `align-coarse-read` payload is only the most recent checkpoint; durable multi-source reading notes live in `align-candidate-ledger.source_readings`. Submit coarse-read payloads serially within one workflow; workflow payload writes are not a parallel ingestion API.
37
- 5. Produce candidate ops batches as JSON. Before each batch, refresh the Term Entity Boundary in `references/gates.md`; its TTL is one batch or about ten candidates, whichever comes first. Use `local:<name>` only inside the current batch; submit each batch through stdin with `context align --ops - --format json` and pass `--ledger-digest <digest>` after the first batch. The CLI reducer assigns durable candidate ids. For `merge_into`, `supersede`, and `reject`, include the required `*_label_hint` fields from the visible candidate labels.
38
- 6. Read the CLI-written candidate ledger and aggregate with `context workflow show --payload align-candidate-ledger --view ledger --unwrap --format json` and `context workflow show --payload align-candidate-aggregate --view aggregate --unwrap --format json`. To revisit one source's coarse-read notes, add `--source <source-id>` to the ledger view; candidates do not carry source ids, so add `--status` or `--candidate-id` only when you also need candidate rows. Treat aggregate fields as mechanical statistics and warnings, not semantic recommendations. Resolve every `anomaly_signals[]` entry as accept, dismiss, or unresolved before finalizing.
36
+ 4. Produce coarse-read anchors and neutral content signals as JSON. Pick `density_profile` using `references/density-profile.md`; content signals describe text shape only, not final Node type. Submit the artifact through stdin with `context align --coarse-read - --format json`. The latest `align-coarse-read` payload is only the most recent checkpoint; durable multi-source reading notes live in `align-candidate-ledger.source_readings`. For multiple sources, submit one envelope with `coarse_reads[]`; single-source payloads remain valid.
37
+ 5. Produce candidate ops batches as JSON. Before each batch, refresh the Term Entity Boundary in `references/gates.md`; its TTL is one batch or about ten candidates, whichever comes first. Use `local:<name>` only inside the current batch; submit each batch through stdin with `context align --ops - --format json`. `--ledger-digest <digest>` is optional; usually omit it and pass it only when you intentionally want stale-batch rejection for a high-assurance retry. The CLI reducer assigns durable candidate ids. For `merge_into`, `supersede`, and `reject`, include the required `*_label_hint` fields from the visible candidate labels.
38
+ 6. Read the CLI-written candidate ledger and aggregate with `context workflow show --payload align-candidate-ledger --view ledger --unwrap --format json` and `context workflow show --payload align-candidate-aggregate --view aggregate --unwrap --format json`. To revisit one source's coarse-read notes, add `--source <source-id>` to the ledger view; candidates do not carry source ids, so add `--status` or `--candidate-id` only when you also need candidate rows. Treat aggregate fields as mechanical statistics and warnings, not semantic recommendations. Review `anomaly_signals[]`; address clear mistakes with another ops batch, otherwise continue. These signals are warnings and do not by themselves block finalizing.
39
39
  7. If the CLI returns `agent_hints[]`, follow them before retrying. Legacy-protocol hints mean the submitted payload/schema is retired; switch to the beta.8 schema named in the hint instead of reshaping old fields.
40
40
  8. Before producing `align-structure-decision`, refresh and apply `references/gates.md`: re-run the Term Entity Boundary decision tree, every `action` needs the five action probes plus structured `inference_sources`, and every `domain` needs `scope_blocks`, resolvable `child_refs`, and `grouping_reason`.
41
41
  9. Produce `align-structure-decision` as JSON with finalized nodes, `contains_parent`, `depends_on`, and one `block_ownership[]` entry per coverable block. Node titles and summaries must follow the latest `generation_policy` language; do not default to English scaffolding such as "How-To", "Strategy", or "Architecture" when the workspace language is not English. Submit it through stdin with `context align --finalize - --digest <segments-digest>`. Prefer stable `llm_slug_hint` values for `contains_parent_ref`, `from_ref`, `to_ref`, owners, and section owners while the final slug is still being normalized.
@@ -56,6 +56,19 @@ Use this only inside `/context:align`.
56
56
 
57
57
  After finalize, a second `context align --finalize` is rejected with `workflow-finalize-locked`; follow the returned `remediation_options[]` instead of resubmitting into the finalized workflow. Use `context workflow list --format json` when you need to audit finalize history.
58
58
 
59
+ If finalize returns an `align-finalize-draft` payload, patch the saved draft instead of rewriting the whole finalize document. Use JSON Pointer paths from the returned issues and submit only the corrections:
60
+
61
+ ```json
62
+ {
63
+ "schema_version": "align.finalize-patch.v1",
64
+ "operations": [
65
+ { "op": "replace", "path": "/block_ownership/3/primary_owner", "value": "rspack" }
66
+ ]
67
+ }
68
+ ```
69
+
70
+ Submit it with `context align --finalize-patch - --payload-digest <draft-digest> --format json`. If issues remain, patch the remaining issue paths; if validation passes, the CLI commits the finalized workflow artifacts.
71
+
59
72
  Never write raw, cache, knowledge, `/tmp`, or workspace scratch files. Never pipe `context ... --format json` through `jq`, `head`, `tail`, `sed`, `cat`, `2>&1`, Python, Node.js, or shell scripts. Never read host persisted output files such as Claude `tool-results/**`; rerun a narrower `context workflow show` command instead. Never submit old candidate-table, decision-patch, or full-tree payloads.
60
73
 
61
74
  </procedures>
@@ -55,19 +55,19 @@ Not `term`:
55
55
  inference_sources:
56
56
  actor:
57
57
  source_type: explicit-block
58
- evidence_blocks: [b0001]
58
+ evidence_blocks: [7a6f4c9d2e10]
59
59
  rationale: "The block names the operator role."
60
60
  outcome_or_goal:
61
61
  source_type: inferred-from-block
62
- evidence_blocks: [b0001]
62
+ evidence_blocks: [7a6f4c9d2e10]
63
63
  rationale: "The block describes recovery as the expected result."
64
64
  repeatability_or_plan:
65
65
  source_type: heading-and-block
66
- evidence_blocks: [b0001]
66
+ evidence_blocks: [7a6f4c9d2e10]
67
67
  rationale: "The runbook heading and ordered list indicate planned reuse."
68
68
  answerability:
69
69
  source_type: explicit-block
70
- evidence_blocks: [b0001]
70
+ evidence_blocks: [7a6f4c9d2e10]
71
71
  rationale: "The steps answer how the operation is performed."
72
72
  ```
73
73
 
@@ -30,9 +30,9 @@ command. It does not hand-edit rendered knowledge.
30
30
  - Content / Section issues (`invalid-section-mount`, `body-ad-hoc-heading`, `dangling-source-alias`) → user re-runs `/context:compile` (draft loop fixes its own Section actions; the close stage does not patch)
31
31
  - Structural issues (`contains-cycle`, `edge-dangling-node`, `duplicate-slug`, `invalid-node-type`, `domain-same-file-child`) → user runs `/context:align` to revise the plan
32
32
  - Source issues (`dropped-source-reference`) → user runs `/context:drop <id>` to complete the drop
33
- - Exit 0 → summarise node/section totals, verify, `recompiled`, `locator_updates`, `rebuilt`, fingerprint rebuild count, and archive status / archived file count when printed; then stop.
33
+ - Exit 0 → summarise node/section totals, verify, `recompiled`, `locator_updates`, `rebuilt`, fingerprint rebuild count, archive status / archived file count, and any `ready_with_debt` coverage warnings when printed; then stop.
34
34
  - Exit 2 → report the full issue list verbatim + point at the right re-entry command above. Do not hand-open the affected rendered article.
35
- - If exit 2 includes `coverage-high-signal-unresolved`, follow the CLI hint. Read the node-scoped payload with `context workflow show --payload coverage-candidates --scope <node-run-scope> --view coverage`. If all unresolved candidates are intentionally excluded for the same reason, use `context compile --coverage-skip-unresolved --coverage-disposition-node <slug> --payload-digest <digest> --reason "<reason>"`; otherwise inspect `context schema coverage-disposition`. Do not guess workspace-scope payload paths.
35
+ - Coverage warning choice: `ready_with_debt` means close succeeded and unresolved coverage remains visible. You may either continue with the warning recorded, or run an uncovered-only repair/skip round. If all unresolved candidates are intentionally excluded for the same reason, use `context compile --coverage-skip-unresolved --coverage-disposition-node <slug> --payload-digest <digest> --reason "<reason>"`; otherwise inspect `context schema coverage-disposition`.
36
36
  - Never re-run `context compile --draft` from close to paper over verify failures. Draft failures belong in the draft loop.
37
37
  - Do not use Python, Node.js, shell scripts, `ls`, `find`, `rg`, `cat`, or similar ad-hoc commands to inspect `WORKSPACE_DIR`, `.context`, knowledge files, or `/tmp` workflow artifacts.
38
38
  - Derivable files self-heal: missing `_index.md` or `changelog.md` is rebuilt inside `compile --close` before the append, locator-only source moves are refreshed, non-canonical but hash-valid `source_ref` locators are canonicalized, and high-signal coverage candidates already backed by active Sections are marked covered. No pre-check needed.
@@ -62,11 +62,10 @@ Close is one in-process command with one exit code:
62
62
  | Outcome | Agent action |
63
63
  |---|---|
64
64
  | Exit 0, 0 issues | Summarise those counts in the user's language: Nodes touched; Sections added / updated / superseded / deprecated / skipped; `recompiled`; `locator_updates`; `rebuilt`; verify green. Stop. |
65
- | Exit 0, warnings only | Summarise + list warnings verbatim. Point at `/context:status` or `context cache status` when the warning is incremental-cache-related. Stop. |
65
+ | Exit 0, warnings only | Summarise + list warnings verbatim. For coverage warnings, name both choices: continue with `ready_with_debt`, or run an uncovered-only repair/skip round through `context compile --coverage-skip-unresolved` or `context schema coverage-disposition`. Stop. |
66
66
  | Exit 2, Section / content issue | Surface the full issue list; point the user at re-running `/context:compile` (the draft loop owns Section writes). Do NOT Edit the affected rendered article. |
67
67
  | Exit 2, structural issue (cycle, duplicate slug, `invalid-node-type`, `domain-same-file-child`) | Surface the full issue list; point the user at `/context:align` to revise structure. Do not re-run compile. |
68
68
  | Exit 2, `dropped-source-reference` | Surface the source-id; point the user at `/context:drop <id>` to complete the drop cleanup. |
69
- | Exit 2, `coverage-high-signal-unresolved` | Read the node-scoped coverage payload named in the CLI hint. If all unresolved candidates are intentionally covered by sibling Nodes or should not be written for this Node for the same reason, run `context compile --coverage-skip-unresolved --coverage-disposition-node <slug> --payload-digest <digest> --reason "<reason>"`; otherwise submit targeted dispositions from `context schema coverage-disposition`. |
70
69
 
71
70
  The close stage never edits rendered knowledge on the agent side. Every verify error routes back to the correct upstream command (compile / align / drop), never sideways into a hand Edit. Use the CLI issue code and hint printed by `context compile --close` for the error→command mapping.
72
71
 
@@ -4,7 +4,7 @@ description: >
4
4
  Packaged skill invoked by `/context:compile`; not a user slash command. For one Node at a time, reads
5
5
  the CLI-provided `NodeContext` (planned metadata, raw snippets, and
6
6
  existing Sections if any), classifies every raw fragment into a Section
7
- kind via the priority chain, writes content + detail + `source_refs[]`,
7
+ kind via the priority chain, writes `body` + `source_refs[]`,
8
8
  and emits a compile draft JSON document. The CLI
9
9
  validates the actions via `context compile --draft <slug> --input - --plan`.
10
10
  Activates when `/context:compile` iterates across the confirmed align plan.
@@ -35,17 +35,17 @@ deprecate / skip` actions; emit JSON; the CLI performs every write.
35
35
  - Pick `kind` from the form of the cited raw block: code / config / command sample → `example`; verifiable rule with a check method → `spec`; stable invariant, design rule, or core mechanism → `principle`; ≥2 subjects × ≥2 dimensions → `comparison`; explicit risk or caveat → `warning`; Q+A pair → `faq`; real incident with timeline → `incident`; versioned change record → `changelog`. Reach `description` only when none of those forms fit — narrative that defines an entity, explains a mechanism, or summarises a stance. First matching form wins.
36
36
  - `kind × node.type` must satisfy the CLI Section mount matrix; mismatches get rejected at write time. When the strongest kind is blocked by mount matrix, fall to the next legal kind whose form actually fits — do not collapse to `description` just because it mounts everywhere, and do not invent thin precision (e.g. one-line `spec`) just to avoid `description` either. See [Description anti-abuse gates](#description-anti-abuse-gates) for the classification checks at the description boundary.
37
37
  - Every write action cites raw via `source_refs[]`, choosing values from `raw_snippets[].source_ref`. Use a single-element array for one citation. Treat each source ref as an opaque citation token; never fabricate, parse, dereference, or cite navigation-only blocks as evidence for a content Section.
38
- - `content` ≤256 chars; long prose goes in `detail`. If a cited raw sentence is already short, single-line, and readable, use it with `content_mode: "extract"` instead of asking AI to summarize it. Do not compress 200 readable characters into a 180-character paraphrase just to make it look rewritten.
39
- - `detail` is not an evidence echo field. Do not copy raw evidence into `detail`, do not prefix detail with labels such as `原文:`, and do not use detail only to show the raw quote. Raw evidence is traceable through `source_refs[]`.
40
- - For `example` Sections, if the cited raw snippet contains command / config / code fences, keep `content` as a short summary and preserve the relevant fenced block in `detail`; do not collapse copyable examples into prose-only summaries unless semantic review asks the user and the user accepts that compression.
41
- - Preserve documentation/reference URL blocks. If a cited raw block is primarily links (官网 / docs / reference / related links), create a small `description` Section such as "相关链接" and put every URL in `detail`; do not drop link-only evidence just because it is not prose.
42
- - 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`.
38
+ - Use one `body` field for Section prose. It may be long and may contain fenced code. Do not emit internal Section fields or retired extractive-contract fields; the CLI derives its internal short claim/detail split before validation.
39
+ - Set `rewrite: false` only when the raw wording is already clear and should be preserved; omit it for normal concise rewriting.
40
+ - For `example` Sections, if the cited raw snippet contains command / config / code fences, include the short summary and the relevant fenced block together in `body`; do not collapse copyable examples into prose-only summaries unless semantic review asks the user and the user accepts that compression.
41
+ - Preserve documentation/reference URL blocks. If a cited raw block is primarily links (官网 / docs / reference / related links), create a small `description` Section such as "相关链接" and keep every URL in `body`; do not drop link-only evidence just because it is not prose.
42
+ - For `add`, `update`, and `supersede.new`, omit optional fields when empty; never emit `detail: null`.
43
43
  - `refers_to_nodes[]` only carries slugs present in the context's glossary, existing Sections, or the current align plan; never invent one.
44
44
  - `supersede` is for semantic replacement; `update` is for typo / wording fixes; `deprecate` needs a `reason`; `skip` is the honest default when raw adds nothing.
45
45
  - If a note or raw snippet was reviewed and should intentionally not write active knowledge, emit `skip` with `source_refs[]` from that exact snippet. This lets semantic review record `reviewed_no_write`; a bare skip is only for deterministic no-op cases such as unchanged input or navigation-only context.
46
46
  - Any Node may legitimately compile to no Sections when the provided snippets contain only navigation (`Parent` / `Children` / `Related` / `Relations`) or placeholder text that explicitly says no detailed content is available. Emit `skip`; do not turn align summaries, parent/child lists, sibling links, or placeholders into `description` Sections. The align graph and Node metadata preserve structure; active Sections need citation-eligible content.
47
47
  - FAQ collections attach to the most specific finalized Node (Entity → Action → Domain fallback); never create a standalone FAQ container.
48
- - Output language: `content`, `detail`, Node-facing summaries, and user-facing draft explanations follow `NodeContext.generation_policy.language` when present; otherwise match the raw material. Preserve product names, code identifiers, CLI flags, slugs, `source_ref` tokens, and exact quoted evidence as printed. Kind / confidence / identifier fields stay English.
48
+ - Output language: draft `body`, Node-facing summaries, and user-facing draft explanations follow `NodeContext.generation_policy.language` when present; otherwise match the raw material. Preserve product names, code identifiers, CLI flags, slugs, `block_id` / `source_ref` tokens, and exact quoted evidence as printed. Kind / confidence / identifier fields stay English.
49
49
  - Stable output: keep action order aligned with evidence order, keep object fields in the documented schema order, omit empty optional fields, and do not add current timestamps, random ids, scratch paths, or host paths. Fixed rules and schema come from this skill; only the current NodeContext should vary between repeated Node draft calls.
50
50
 
51
51
  <reference>
@@ -60,21 +60,21 @@ deprecate / skip` actions; emit JSON; the CLI performs every write.
60
60
  "sources": ["..."], "aliases": ["..."], "summary": "...",
61
61
  "planned_sections": ["spec", "..."],
62
62
  "action_gate": {
63
- "actor_blocks": ["b0002"],
63
+ "actor_blocks": ["2f4b8c1e9a03"],
64
64
  "trigger_blocks": [],
65
- "goal_blocks": ["b0003"],
66
- "step_blocks": ["b0004"],
67
- "outcome_blocks": ["b0005"],
68
- "repeatability_or_plan_blocks": ["b0006"],
65
+ "goal_blocks": ["c0d4e5f61728"],
66
+ "step_blocks": ["8b9a0c1d2e3f"],
67
+ "outcome_blocks": ["4e2d1c0b9a88"],
68
+ "repeatability_or_plan_blocks": ["9d1e2f3a4b5c"],
69
69
  "inference_sources": {
70
- "actor": { "source_type": "explicit-block", "evidence_blocks": ["b0002"], "rationale": "..." },
71
- "outcome_or_goal": { "source_type": "explicit-block", "evidence_blocks": ["b0003"], "rationale": "..." },
72
- "repeatability_or_plan": { "source_type": "explicit-block", "evidence_blocks": ["b0006"], "rationale": "..." },
70
+ "actor": { "source_type": "explicit-block", "evidence_blocks": ["2f4b8c1e9a03"], "rationale": "..." },
71
+ "outcome_or_goal": { "source_type": "explicit-block", "evidence_blocks": ["c0d4e5f61728"], "rationale": "..." },
72
+ "repeatability_or_plan": { "source_type": "explicit-block", "evidence_blocks": ["9d1e2f3a4b5c"], "rationale": "..." },
73
73
  "answerability": { "source_type": "ref-node", "ref_nodes": ["..."], "rationale": "..." }
74
74
  }
75
75
  },
76
76
  "domain_gate": {
77
- "scope_blocks": ["b0001"],
77
+ "scope_blocks": ["7a6f4c9d2e10"],
78
78
  "child_refs": ["..."],
79
79
  "grouping_reason": "..."
80
80
  }
@@ -83,22 +83,22 @@ deprecate / skip` actions; emit JSON; the CLI performs every write.
83
83
  "language": "Chinese",
84
84
  "source": "workspace.language",
85
85
  "applies_to": ["node.title", "node.summary", "section.content", "section.detail", "user_facing_report"],
86
- "instruction": "Generate knowledge titles, summaries, Section content/detail, and user-facing reports in Chinese; preserve product names, code identifiers, CLI flags, source_ref tokens, slugs, and quoted evidence exactly when needed."
86
+ "instruction": "Generate knowledge titles, summaries, Section content/detail, and user-facing reports in Chinese; preserve product names, code identifiers, CLI flags, block_id/source_ref tokens, slugs, and quoted evidence exactly when needed."
87
87
  },
88
88
  "existing": { // present if the Node already exists
89
89
  "sections": [
90
90
  { "id": "section-1", "kind": "description", "content": "...",
91
91
  "detail": "...", "status": "active|deprecated",
92
- "confidence": "...", "source_ref": "src-1#anchor L10-14@ab12cd34ef56",
92
+ "confidence": "...", "source_ref": "src-1#anchor L10-14@7a6f4c9d2e10",
93
93
  "refers_to_nodes": [...] }
94
94
  ]
95
95
  },
96
96
  // Default NodeContext does not expose raw file paths. Copy raw_snippets[].source_ref
97
- // into draft source_refs[]; identify blocks via source_id + block_locator_id (or block_hash).
97
+ // into draft source_refs[]; copy CLI-provided block_id only for ownership challenges.
98
98
  "mentions": [ { "line": 12, "quote": "...", "source_id": "local:billing", "block_locator_id": "h2-api" } ],
99
99
  "raw_snippets": [ { "line": 10,
100
100
  "line_range": [10, 18],
101
- "source_ref": "src-1#api L10-18@ab12cd34ef56",
101
+ "source_ref": "src-1#api L10-18@7a6f4c9d2e10",
102
102
  "quote": "...context block...",
103
103
  "mention_quote": "...",
104
104
  "source_type": "local|feishu|note",
@@ -152,43 +152,31 @@ unless citation-eligible raw snippets state the same claim.
152
152
  "target_node": "<matches node.slug>",
153
153
  "actions": [
154
154
  { "op": "add", "kind": "spec",
155
- "content": "...", "detail": "...",
155
+ "body": "...",
156
+ "rewrite": false,
156
157
  "refers_to_nodes": ["..."],
157
- "source_refs": ["src-1#api L10-14@ab12cd34ef56"],
158
- "content_mode": "extract",
159
- "basis_spans": [
160
- { "source_ref": "src-1#api L10-14@ab12cd34ef56" }
161
- ]
158
+ "source_refs": ["src-1#api L10-14@7a6f4c9d2e10"]
162
159
  },
163
160
  { "op": "update", "target_section_id": "section-3",
164
- "content": "...", "detail": null, // null clears detail
161
+ "body": "...",
165
162
  "refers_to_nodes": null,
166
- "source_refs": ["src-1#api L18-21@cd34ef56ab78"],
167
- "content_mode": "minimal_paraphrase",
168
- "paraphrase_reason": "fragment_fix",
169
- "basis_spans": [
170
- { "source_ref": "src-1#api L18-21@cd34ef56ab78" }
171
- ] },
163
+ "source_refs": ["src-1#api L18-21@c0d4e5f61728"] },
172
164
  { "op": "supersede", "target_section_id": "section-5",
173
165
  "reason": "raw published a new retention value",
174
- "new": { "kind": "spec", "content": "...", "detail": "...",
166
+ "new": { "kind": "spec", "body": "...",
175
167
  "refers_to_nodes": ["..."],
176
- "source_refs": ["src-1#limits L30-34@ef56ab78cd90"],
177
- "content_mode": "extract",
178
- "basis_spans": [
179
- { "source_ref": "src-1#limits L30-34@ef56ab78cd90" }
180
- ] } },
168
+ "source_refs": ["src-1#limits L30-34@9d1e2f3a4b5c"] } },
181
169
  { "op": "deprecate", "target_section_id": "section-2", "reason": "..." },
182
170
  { "op": "skip", "reason": "no new evidence in raw snippets" },
183
171
  { "op": "skip", "reason": "reviewed; intentionally not written",
184
- "source_refs": ["src-1#note L4-8@ab12cd34ef56"] },
172
+ "source_refs": ["src-1#note L4-8@7a6f4c9d2e10"] },
185
173
  { "op": "structure_challenge",
186
174
  "challenge_id": "ch_0001",
187
175
  "kind": "missing_action_node",
188
176
  "node_slug": "<matches node.slug>",
189
177
  "action_tag": "rollout-runbook",
190
178
  "summary": "The cited evidence is a repeatable procedure.",
191
- "source_ref": "src-1#ops L40-55@cd34ef56ab78",
179
+ "source_ref": "src-1#ops L40-55@c0d4e5f61728",
192
180
  "reason": "Align must review structure before compile writes process prose." },
193
181
  { "op": "structure_challenge",
194
182
  "challenge_id": "ch_0002",
@@ -199,7 +187,7 @@ unless citation-eligible raw snippets state the same claim.
199
187
  { "op": "pending_ownership_challenge",
200
188
  "challenge_id": "och_0001",
201
189
  "node_slug": "<matches node.slug>",
202
- "block_id": "b0032",
190
+ "block_id": "2f4b8c1e9a03",
203
191
  "requested_role": "shared",
204
192
  "reason": "A visible context_only or secondary shared block contains facts that need citation." }
205
193
  ]
@@ -209,17 +197,10 @@ unless citation-eligible raw snippets state the same claim.
209
197
  `source_refs[]` values are copied from `raw_snippets[].source_ref`; a single
210
198
  citation is still written as a single-element array. Submitting singular
211
199
  `source_ref` or quoted-evidence fields is rejected with canonical repair hints.
212
- Every Section write (`add`, `update` with content/detail/source refs, and
213
- `supersede.new`) must include `content_mode` plus `basis_spans[]`. Use
214
- `content_mode: "extract"` when the cited raw sentence already fits the
215
- single-line content contract and you keep the original sentence order. If you reorder
216
- sentences, merge sentences with new punctuation, or consolidate bullets, use
217
- `content_mode: "minimal_paraphrase"` with the matching `paraphrase_reason`. Use `content_mode: "minimal_paraphrase"` only
218
- when direct extract would be malformed, too broad, duplicated, or needs
219
- multi-span consolidation; include `paraphrase_reason`.
220
- Do not mark sentence 1 + sentence 3 from the same evidence block as
221
- `extract`; non-contiguous copies are `minimal_paraphrase` even when every word
222
- came from raw evidence.
200
+ Every Section write (`add`, `update` with body/source refs, and
201
+ `supersede.new`) uses `body`. Keep one coherent fact group per action; when
202
+ one Section summarizes contiguous multi-block evidence, list every relevant
203
+ source ref in order under `source_refs[]`.
223
204
  `structure_challenge` and `pending_ownership_challenge` do not write Sections;
224
205
  the CLI stores them as workflow payloads and close exposes them as debt until
225
206
  align resolution handles them. Supported structure challenge kinds include
@@ -357,27 +338,21 @@ For each existing Section:
357
338
 
358
339
  For each change from Steps 2-3:
359
340
 
360
- 1. Split the cited block into `content` and `detail` so the Section is independently addressable in retrieval. `content` (≤256 chars) carries the Section's identity — for `example` / `spec` / `incident` that is the load-bearing identifiers the cited block hinges on (command name, key flags, field names, distinguishing values, mode names, error codes); for `principle` / `description` / `decision` / `comparison` / `warning` / `faq` / `changelog` it is the claim itself in raw's own terms. If the raw sentence already fits this shape, keep it as an extract instead of summarizing it. `detail` carries active knowledge that cannot fit in `content`, especially copyable code/config/URL/table material. Prefer splitting prose into separate supported Sections over storing a raw prose quote in `detail`. Do not put the raw evidence itself into `detail` as a "source copy"; the rendered Section already carries source_ref, and the CLI can resolve the raw evidence from that token.
361
- 2. Keep `content` and `detail` faithful to the cited raw terms: do not introduce acronyms, abbreviations, translations, or aliases that do not appear in the cited raw snippet unless raw itself defines the equivalence or the user confirms it later during semantic review.
362
- 3. If the cited block contains documentation/reference URLs, preserve them in `content` or `detail`. Link-only blocks are still useful knowledge; use `kind: description` with a concise "相关链接" identity when no more specific kind applies.
341
+ 1. Write `body` as the Section text the reader should see. It can include long prose, URLs, tables, command/config/code fences, or short raw wording. Keep one coherent, cited fact group per action; the CLI derives the internal `content`/`detail` split.
342
+ 2. Keep `body` faithful to the cited raw terms: do not introduce acronyms, abbreviations, translations, or aliases that do not appear in the cited raw snippet unless raw itself defines the equivalence or the user confirms it later during semantic review. Use `rewrite: false` when preserving raw expression is the least surprising representation.
343
+ 3. If the cited block contains documentation/reference URLs, preserve them in `body`. Link-only blocks are still useful knowledge; use `kind: description` with a concise "相关链接" identity when no more specific kind applies.
363
344
  4. Omit `confidence` for ordinary confirmed claims. Assign `confidence` per the [Confidence rubric](#confidence-rubric) only when the evidence is not confirmed.
364
345
  5. Fill `refers_to_nodes[]` per [Glossary and refers_to_nodes](#glossary-and-refers_to_nodes).
365
346
  6. Cite evidence with `source_refs[]`, picking values from `raw_snippets[].source_ref`. When one Section summarizes contiguous multi-block evidence, list every relevant source ref in order under `source_refs[]`; the CLI verifies that the refs can collapse to one canonical citation token. If the evidence is non-contiguous or contains separable claims, split the draft into separately cited actions instead of stretching one action across unrelated blocks. For `skip`, include `source_refs[]` only when the skip represents reviewed no-write material; omit evidence for purely deterministic no-ops such as unchanged input. Never submit singular `source_ref` or quoted-evidence fields; the CLI rejects them.
366
- 7. Add the extractive contract to every Section write: `content_mode`,
367
- `basis_spans[]`, and `paraphrase_reason` when `content_mode` is
368
- `minimal_paraphrase`. Each `basis_spans[]` entry contains only
369
- `source_ref`; the CLI resolves cited text and computes the audit basis
370
- internally. When one short basis span is already a valid `content`, choose
371
- `content_mode: "extract"`.
372
- 8. If evidence implies a missing Action, missing `depends_on`, wrong parent, or
347
+ 7. If evidence implies a missing Action, missing `depends_on`, wrong parent, or
373
348
  needed ownership upgrade from `context_only`, emit the corresponding
374
349
  challenge action instead of forcing the content into a Section.
375
350
  `pending_ownership_challenge.requested_role` is `owned` or `shared`.
376
351
 
377
- Rendered knowledge uses the short claim as the visible blockquote and renders
378
- `detail` as a collapsed Details block under that claim. A reader should be able
379
- to understand the Section from `content` first; `detail` is supporting active
380
- knowledge, not a hidden evidence copy.
352
+ Rendered knowledge uses a CLI-derived short claim as the visible blockquote and
353
+ renders longer supporting material from `body` as collapsed Details when needed.
354
+ A reader should be able to understand the Section from the short claim first;
355
+ long supporting material is active knowledge, not a hidden evidence copy.
381
356
 
382
357
  ### Step 5 — Emit the JSON
383
358
 
@@ -388,11 +363,10 @@ Emit one compile draft JSON document for the caller to pass to `context compile
388
363
  - [ ] `target_node` equals `node.slug` — if not, **Step 5**.
389
364
  - [ ] Every `add` / `supersede.new` has a legal kind × type combination — if not, **Step 2**.
390
365
  - [ ] Every action's `source_refs[]` entries appear in `raw_snippets[].source_ref` for this NodeContext, and no action carries singular `source_ref` or quoted-evidence fields — if not, **Step 4**; pick the right source ref, split non-contiguous claims, or use `skip` only when raw has no write-worthy fact.
391
- - [ ] Every Section write has `content_mode` and `basis_spans[]`; every
392
- `minimal_paraphrase` has `paraphrase_reason` — if not, **Step 4**.
393
- - [ ] Short, readable, single-line evidence was not rewritten just for style. If it already fits `content`, switch to `content_mode: "extract"` if not, **Step 4**.
394
- - [ ] `content` does not add new hard terms, acronyms, abbreviations, translations, URLs, code literals, versions, or aliases absent from the cited raw snippet if it does, either use the raw wording, move the extra explanation into a user-confirmed decision later, or **Step 4**.
395
- - [ ] No `add` / `supersede.new` action contains `detail: null` — omit `detail` instead.
366
+ - [ ] Every Section write uses `body` and cites `source_refs[]`; no action uses `content`, `detail`, singular `source_ref`, extractive-contract fields, or quoted-evidence fields — if not, **Step 4**.
367
+ - [ ] Short, readable, single-line evidence was not rewritten just for style. If it is already clear, keep the raw wording in `body` and set `rewrite: false` — if not, **Step 4**.
368
+ - [ ] `body` does not add new hard terms, acronyms, abbreviations, translations, URLs, code literals, versions, or aliases absent from the cited raw snippet — if it does, either use the raw wording, move the extra explanation into a user-confirmed decision later, or **Step 4**.
369
+ - [ ] No action contains `detail` or `content` — use `body` instead.
396
370
  - [ ] No `description` action that would fail the anti-abuse gates — if any, **Step 2**.
397
371
  - [ ] Every citation-eligible raw URL block is either preserved in a Section or intentionally skipped with evidence and reason; if not, **Step 4**.
398
372
  - [ ] Dense raw material was not collapsed into one broad Section. If `raw_snippets[]` spans many locator areas and only one write action exists, return to **Step 2** unless the remaining snippets are duplicates, navigation-only, or already covered by existing Sections.