@c4a/context-cli 0.6.11 → 0.6.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +5 -0
  2. package/README.zh-CN.md +5 -0
  3. package/cli.js +6112 -3389
  4. package/docs/document-optimization.md +62 -0
  5. package/docs/document-optimization.zh-CN.md +54 -0
  6. package/package.json +3 -2
  7. package/plugins/VERSION +1 -1
  8. package/plugins/claude/.claude-plugin/plugin.json +1 -1
  9. package/plugins/claude/commands/context.md +50 -5
  10. package/plugins/codex/.codex-plugin/plugin.json +2 -2
  11. package/plugins/codex/skills/context/SKILL.md +50 -5
  12. package/plugins/cursor/.cursor-plugin/plugin.json +1 -1
  13. package/plugins/cursor/commands/c4a-context.md +50 -5
  14. package/plugins/skills/c4a-context/SKILL.md +50 -5
  15. package/providers/context/actions/optimize-documents.yaml +6 -0
  16. package/providers/context/actions/preview-extraction-batch.yaml +5 -0
  17. package/providers/context/actions/revise-document.yaml +5 -0
  18. package/providers/context/codes.yaml +6 -0
  19. package/providers/context/graphs/workspace.yaml +118 -3
  20. package/providers/context/manifest.json +242 -26
  21. package/providers/context/provider.yaml +1 -1
  22. package/providers/context/resources/dialogue/code-extraction.md +39 -9
  23. package/providers/context/resources/dialogue/package-output.md +5 -8
  24. package/providers/context/resources/manuals/guides/package-outputs.md +14 -20
  25. package/providers/context/resources/manuals/reference/code-extractors.md +75 -18
  26. package/providers/context/resources/manuals/reference/package-templates.md +26 -33
  27. package/providers/context/resources/manuals/reference/project-api.md +156 -14
  28. package/providers/context/resources/manuals/reference/template-variables.md +4 -3
  29. package/providers/context/resources/procedures/close-and-build.md +5 -0
  30. package/providers/context/resources/procedures/code-extraction.md +86 -13
  31. package/providers/context/resources/procedures/document-optimization.md +43 -0
  32. package/providers/context/resources/procedures/document-revision.md +31 -0
  33. package/providers/context/resources/procedures/package-output.md +10 -34
  34. package/providers/context/resources/semantic/code-index/classification.md +267 -0
  35. package/providers/context/resources/semantic/code-index/templates/adapter.md +109 -0
  36. package/providers/context/resources/semantic/code-index/templates/api-service.md +116 -0
  37. package/providers/context/resources/semantic/code-index/templates/background-runtime.md +109 -0
  38. package/providers/context/resources/semantic/code-index/templates/cli-tool.md +129 -0
  39. package/providers/context/resources/semantic/code-index/templates/contract-source.md +73 -0
  40. package/providers/context/resources/semantic/code-index/templates/cross-module-chain.md +78 -0
  41. package/providers/context/resources/semantic/code-index/templates/derived-source.md +116 -0
  42. package/providers/context/resources/semantic/code-index/templates/domain-service.md +109 -0
  43. package/providers/context/resources/semantic/code-index/templates/event-flow.md +62 -0
  44. package/providers/context/resources/semantic/code-index/templates/monorepo-container.md +124 -0
  45. package/providers/context/resources/semantic/code-index/templates/persistence-boundary.md +56 -0
  46. package/providers/context/resources/semantic/code-index/templates/plugin-extension.md +52 -0
  47. package/providers/context/resources/semantic/code-index/templates/protocol-boundary.md +88 -0
  48. package/providers/context/resources/semantic/code-index/templates/sdk-library.md +132 -0
  49. package/providers/context/resources/semantic/code-index/templates/web-application.md +145 -0
  50. package/providers/context/resources/views/document-optimization-current.yaml +6 -0
  51. package/providers/context/resources/views/extraction-preview.yaml +6 -0
  52. package/providers/context/schemas/document-optimization-decisions.schema.json +34 -0
@@ -6,10 +6,16 @@ mediaType: text/markdown
6
6
 
7
7
  # Code-extraction dialogue
8
8
 
9
- Describe the proposed code scope before SDK fields. State:
9
+ Begin with the Route-selected batch inspection. Classify all modules from that
10
+ evidence before opening any archetype template, inspect source files only for
11
+ unresolved facts, then read every matching Route-recommended type or facet
12
+ template. For all modules in the current batch, state:
10
13
 
11
14
  - the confirmed repository module;
12
- - which files are included;
15
+ - the primary and additional module types, composable facets, evidence paths,
16
+ stable responsibility, entries, external protocols and important dependencies;
17
+ - the output owner/profile and planned page kinds;
18
+ - which files or generated/derived areas are excluded;
13
19
  - whether extraction follows configured/public entries or scans all matched
14
20
  files;
15
21
  - whether internal symbols are included; and
@@ -22,23 +28,47 @@ whether a project-owned adapter supplies the missing mapping. Do not ask the
22
28
  user to choose between parser package names unless two genuinely incompatible
23
29
  technical choices remain.
24
30
 
31
+ In fully managed mode, write the same fields into one batch report instead of
32
+ asking or narrating them module by module. A typed `material-required` gap and
33
+ the measured scale limit remain observable in both modes; advisory risks do not
34
+ create another confirmation Gate.
35
+
25
36
  If a selected package lacks a standard entry, offer two Context-owned choices:
26
37
  configure source-relative API roots, or use scan mode for all declarations in
27
38
  the confirmed file scope. Do not ask the user to change source code or package
28
39
  metadata to satisfy Context.
29
40
 
30
- For a non-TypeScript source or an aggregated repository protocol, explain that
31
- the project will use `extractCustom()`. If an optional structural extractor is
32
- available, use it for syntax facts and keep project-specific classification in
33
- the project callback; do not imply that installing it adds a new CLI phase.
41
+ `extractTs()` creates one candidate page per selected symbol and assigns a
42
+ source to one index unit. Use it only when that granular shape is the intended
43
+ public reference. For an aggregate module map, registry, protocol index, or
44
+ cross-module flow—or multiple units over one source—use `extractCustom()` and
45
+ declare candidate ownership. If an optional structural extractor is available,
46
+ use it for syntax facts and keep project-specific classification in the project
47
+ callback; do not imply that installing it adds a new CLI phase.
34
48
 
35
- Run the route-selected dry-run first. Report discovered, AST-analyzed, skipped,
36
- symbol, relation, and candidate counts separately, plus resolved entries,
37
- exported/internal counts, symbol-kind counts, and the proposed knowledge tree.
49
+ Do not predict page counts from the template examples. Run the route-selected
50
+ batch preview once after the plan is configured. Report discovered, AST-analyzed,
51
+ skipped, symbol, relation, and candidate counts separately, plus resolved
52
+ entries, exported/internal counts, symbol-kind counts, output ownership and the
53
+ proposed knowledge tree.
38
54
  Treat those fields as structural scope evidence, not a semantic ranking. Stop
39
55
  when the preview crosses the confirmed module boundary or the module
40
56
  identity/path shape is wrong.
41
57
 
58
+ Apply the per-index-unit policy exactly: up to 100 pages proceeds; 101–300 pages
59
+ warns and proceeds; more than 300 pages stops even in fully managed mode. Group
60
+ all oversized or capability-gap units into one explanation and one plan-revision
61
+ Gate instead of asking about modules one by one. If the revision changes a
62
+ module's classification, read the newly selected template before editing the
63
+ plan; otherwise reuse the current classification and avoid another
64
+ classification dialogue.
65
+
66
+ When blocked, propose only legal revisions: narrow `include`, exclude generated
67
+ or mirrored areas, enable `exportedOnly`, change to an aggregate
68
+ `extractCustom()` shape, or register real child sources. Do not split one
69
+ `extractTs()` source into overlapping index units. Report a batch-total page
70
+ advisory as a cost signal, not a new Gate.
71
+
42
72
  For a multi-module round, finish every pending extraction target before opening
43
73
  one Review. For an unchanged repeat run, explain that no added, changed, or
44
74
  removed symbols need a decision. Mention `extractTs`, `include`, `entries`,
@@ -25,14 +25,11 @@ package namespace. Ask whether Skills need a short optional prefix, then
25
25
  maintain their complete final names in the template. Do not expose downstream
26
26
  layout terminology or ask for platform-specific identity fields.
27
27
 
28
- Also ask how referenced resources should be delivered. Offer Git raw links,
29
- bundled files, or explicit omission. Git raw may derive a commit-pinned GitHub
30
- URL when the workspace is in Git, or use an author-provided HTTPS `urlPrefix`
31
- for resources published from another repository. A literal branch in that
32
- prefix is an explicit project choice, not a Context default. If neither local
33
- Git nor an explicit prefix is available, offer only bundle or omit.
34
- State that publishing the referenced resources and making private raw hosts
35
- reachable are the package author's responsibility; Context does not probe them.
28
+ Referenced resources are bundled by default. Explain the 1 MiB per-image and
29
+ 40 MiB total-image package limits only when relevant. Offer Git raw links or
30
+ explicit omission only when the author asks for another delivery policy. Git
31
+ raw uses an immutable derived URL or an author-provided HTTPS `urlPrefix`;
32
+ publishing and access remain the author's responsibility.
36
33
 
37
34
  Do not offer a hidden `both` shortcut. If the user wants multiple outputs,
38
35
  declare and inspect one first, then obtain confirmation for the next. Mention
@@ -95,26 +95,20 @@ package needs project-specific terminology, entry points, known limits, or
95
95
  task workflows. Authors may explicitly accept the generic default when it is
96
96
  intentionally sufficient.
97
97
 
98
- When approved pages reference materialized document resources, Context keeps
99
- their production copies in content-addressed `knowledge/assets/` paths. New KB
100
- setup should offer Git raw delivery first. It rewrites package links to either
101
- an automatically derived raw prefix or an explicit author-provided prefix.
102
- Context does not check whether resource files are committed, pushed, or
103
- remotely readable; that is the package author's responsibility. With no
104
- explicit prefix, supported remotes use an immutable commit URL. An explicit
105
- prefix can contain `{commit}` when the Context workspace is in Git, or name a
106
- mutable branch when that lifecycle is intentional; a literal prefix also works
107
- when resources are published from a separate repository.
108
-
109
- Workspaces without usable Git or an explicit raw prefix can choose bundled
110
- delivery, which copies only selected resources to `others/assets/`, or explicit
111
- omission, which does not copy resources and reports that links remain
112
- unresolved. Bundled output may
113
- optionally install `sharp` in the workspace and configure
114
- `assets.optimize`; Context itself has no image dependency. Optimization changes
115
- only `dist/`, content-addresses smaller WebP output, and leaves `sources/` and
116
- `knowledge/assets/` unchanged. Source audit XML and capture reports are never
117
- distributed as reader assets. See [Lark Resource Materialization](./lark-resources.md).
98
+ When approved pages reference materialized resources, Context keeps their
99
+ production copies in content-addressed `knowledge/assets/` paths and bundles
100
+ selected resources into `others/assets/` by default. Supported images are
101
+ adaptively compressed only when needed: every packaged image must be at most 1
102
+ MiB and all packaged images together must be at most 40 MiB. The CLI owns the
103
+ processor. Optimization changes only `dist/`, content-addresses smaller WebP
104
+ output, and leaves `sources/` and `knowledge/assets/` unchanged.
105
+
106
+ Configure Git raw delivery only when external immutable links are an explicit
107
+ project requirement. Context can derive supported Git URLs or use an explicit
108
+ HTTPS `urlPrefix`, but it does not publish or probe those resources. Explicit
109
+ omission remains available and reports unresolved links. Source audit XML and
110
+ capture reports are never distributed as reader assets. See
111
+ [Lark Resource Materialization](./lark-resources.md).
118
112
 
119
113
  The same inventory exposes `structure.relationship_coverage`. It records
120
114
  whether selected codegraph pages have current source-backed AST relationship
@@ -12,8 +12,9 @@ chooses how those facts become source-backed code knowledge.
12
12
 
13
13
  ## Inspect Before Declaring
14
14
 
15
- Run every read-only inspection command returned by the extraction-scope Gate.
16
- The result identifies each confirmed module and its recognized `manifests`.
15
+ Run the single batch inspection command returned by the extraction-scope Gate.
16
+ The result identifies every confirmed module, its recognized `manifests`,
17
+ README locations, entry candidates, protocol locators, and lifecycle markers.
17
18
  Treat these as deterministic technology signals, not as product semantics:
18
19
 
19
20
  | Signal | Technology candidate |
@@ -49,6 +50,19 @@ Current reusable capabilities are:
49
50
  | React Router route declarations | `extractReactRouterRoutes()` from `@c4a/extract-ts` | call from `extractCustom()`; complements TypeScript symbols |
50
51
  | Rust, Python, Java/JVM, or an unsupported framework/protocol | no assumed built-in parser | project-owned `extractCustom()` adapter |
51
52
 
53
+ The custom extraction preview verifies this selection mechanically. Context
54
+ detects applicable community capabilities from source manifests and stable path
55
+ signals, then checks that candidate evidence covers every required entry,
56
+ route, implementation boundary, workspace, or protocol probe. One aggregated
57
+ module page is valid when it closes that structural coverage. A callback that
58
+ only hashes a few filenames or renders configured prose does not satisfy the
59
+ probe, even when its Markdown count is small.
60
+
61
+ The probe does not assign business meaning and does not require one page per
62
+ fact. The project adapter still owns grouping, titles, explanations, and
63
+ cross-module semantics. If the source uses an unsupported language or protocol,
64
+ report a capability gap instead of claiming that a known probe was consumed.
65
+
52
66
  An optional package does not create a new CLI phase. Add it as an explicit
53
67
  workspace dependency, then map its structural facts to candidates in the
54
68
  project callback. Do not add a parser package when its documented coverage does
@@ -56,23 +70,18 @@ not match the inspected source.
56
70
 
57
71
  ## Read The Contract Before Extending
58
72
 
59
- Before editing `src/index.ts`, read the relevant installed public manual or
60
- package README. Do not infer APIs from bundled JavaScript.
61
-
62
- - Context lifecycle and `extractCustom()`:
63
- `node_modules/@c4a/context/docs/reference/project-api.md`
64
- - Generic plugin protocol:
65
- `node_modules/@c4a/extract/README.md`
66
- - TypeScript:
67
- `node_modules/@c4a/extract-ts/README.md`
68
- - Go:
69
- `node_modules/@c4a/extract-go/README.md`
70
- - Rush:
71
- `node_modules/@c4a/extract-rush/README.md`
73
+ Before editing `src/index.ts`, read the Route-selected Context lifecycle and
74
+ extractor resources completely. They are the installed contract for
75
+ Context-owned phases such as `extractTs()`; do not require a separate
76
+ workspace copy of an implementation package and do not infer APIs from bundled
77
+ JavaScript.
72
78
 
73
- If an optional package is not installed, use this capability matrix to decide
74
- whether it is relevant, add only that dependency, and then read its shipped
75
- README before implementing the callback.
79
+ Only a capability imported directly by a project-owned `extractCustom()`
80
+ adapter requires its package README. Use this matrix to decide whether that
81
+ optional capability is relevant, add only that dependency, then read the
82
+ README from the resolved installed package before implementing the callback.
83
+ Never assume that a transitive or dev-only package is present at a hard-coded
84
+ `node_modules` path.
76
85
 
77
86
  A project-owned adapter may use an existing parser, compiler API, or command
78
87
  whose output is deterministic. It must return source-backed candidates through
@@ -89,6 +98,54 @@ Before the first extraction preview, state briefly:
89
98
  - whether coverage is complete or which facts remain project-owned; and
90
99
  - why another available extractor is not needed.
91
100
 
101
+ After preview, use `inspection.structuralProbes` and each index unit's
102
+ `structuralCoverage` as the exact audit result. An uncovered probe is a
103
+ configuration problem, not a Review decision.
104
+
92
105
  If no current capability can parse the source reliably, stop at configuration
93
106
  and report the missing generic capability. Do not silently emit an empty
94
107
  codegraph or reuse an unrelated parser.
108
+
109
+ ## Plan Before Parsing
110
+
111
+ Classify the user-visible module before selecting language tooling or reading an
112
+ archetype template: API/service, background runtime, SDK/library, interactive
113
+ application, adapter, CLI/tool, monorepo container, derived source,
114
+ authoritative contract source, or unknown.
115
+ A hybrid module may declare several `moduleTypes` and several behavior `facets`;
116
+ keep one primary `moduleType` for concise reports. Record inspected paths in
117
+ `moduleTypeEvidence`, then read all matching Route-recommended files below
118
+ `resources/semantic/code-index/templates/` and combine them into one plan.
119
+ After that, choose exactly one closed output profile: `module-map`,
120
+ `application-map`, `protocol-index`, `service-boundary`, `runtime-map`,
121
+ `public-api-reference`, `command-map`, `adapter-contract`, `module-registry`,
122
+ `cross-module-flow`, or `provenance-only`. The profile selects structural probes
123
+ and advisory checks; an invented value is rejected.
124
+
125
+ Each archetype resource is a working template for an Agent with limited prior
126
+ context. It provides a minimum evidence pass, the reader questions the index
127
+ must answer, suggested knowledge units, Markdown chapter blueprints,
128
+ aggregation and relationship rules, composition examples, and stop conditions.
129
+ The blueprints are illustrative: omit unsupported sections and merge overlap
130
+ across selected templates instead of producing empty headings or duplicate
131
+ pages. They shape content before the batch preview; they do not prescribe or
132
+ override projected page counts.
133
+
134
+ Extractor shape defines what can be emitted. `extractTs()` creates one page per
135
+ selected symbol and permits one owning index unit per source. Use it for an
136
+ intentional granular public reference. Use `extractCustom()` for module-level
137
+ aggregation, registries, protocol indexes, cross-module flows, or multiple
138
+ candidate owners over one source; each candidate declares its `module` and
139
+ evidence-scoped `sections`. Each section's typed coverage and exact evidence is
140
+ checked against the output profile during preview. Resolve repositories from
141
+ the extractor context's `sources[].absolutePath`, never from a
142
+ machine-specific checkout path. Cross-module flow output must also emit
143
+ source-backed structured edges. Generated clients/models, mirrored sources, legacy
144
+ implementations, and internal helpers should normally be excluded or recorded
145
+ as provenance rather than expanded one symbol per page.
146
+
147
+ If a repository uses service manifests or protocol registrations that the
148
+ community inspector cannot interpret, keep that interpretation in a generic
149
+ project-owned `inspect` adapter attached to `extractCustom()`. Return findings
150
+ and capability gaps through the public Context contract; do not add internal
151
+ framework names or directory rules to the CLI.
@@ -37,10 +37,7 @@ kbPackage({
37
37
  foldDirectoryIndexes: true,
38
38
  maxInlineEntries: 50,
39
39
  },
40
- assets: {
41
- delivery: "git-raw",
42
- urlPrefix: "https://code.example.com/team/knowledge/raw/{commit}",
43
- },
40
+ assets: { delivery: "bundle" },
44
41
  });
45
42
  ```
46
43
 
@@ -62,10 +59,16 @@ llmsPackage({
62
59
  | `template` | yes | Project-relative template directory or `{ path, vars }`. |
63
60
  | `select` | no | Approved knowledge selector. Omit to include all approved knowledge. Supports internal `collections`, OKF `okfRoots`, and `include` / `exclude` path patterns relative to `knowledge/`. |
64
61
  | `navigation` | no | KB directory-index policy. Defaults to `{ foldDirectoryIndexes: true, maxInlineEntries: 50 }`. |
65
- | `assets` | no | Resource delivery: Git raw links, bundled files, or explicit omission. New KB setup should offer Git raw first. Omit for legacy byte-for-byte bundling. |
62
+ | `assets` | no | Resource delivery: bundled files by default, explicit Git raw links, or explicit omission. |
66
63
  | `distribution` | no | Legacy input accepted from older workspaces. It no longer changes package paths and should not be added to new declarations. |
67
64
 
68
- Use Git raw delivery when resources are published from a Git repository.
65
+ Bundled delivery is the default. Selected resources are written below
66
+ `others/assets/`. Supported images are automatically compressed when required
67
+ to keep each image at or below 1 MiB and all package images at or below 40 MiB.
68
+ The source snapshots and approved `knowledge/assets/` files are never changed.
69
+
70
+ Use Git raw delivery only when it is explicitly configured for resources
71
+ published from a Git repository.
69
72
  Without `urlPrefix`, the Context workspace must be inside Git; GitHub remotes
70
73
  are derived automatically and pinned to the current commit. Other hosts accept
71
74
  an explicit HTTPS prefix. `{commit}` is replaced only when the workspace is
@@ -76,14 +79,14 @@ appends the project-relative `knowledge/assets/...` path.
76
79
  For a non-GitHub service that exposes raw files through the GitHub-compatible
77
80
  same-host layout
78
81
  `https://<host>/<namespace>/<repository>/raw/<ref>/<path>`, derive and configure
79
- the explicit prefix before choosing bundled delivery. For example, use
82
+ the explicit prefix before choosing Git raw delivery. For example, use
80
83
  `https://git.example.com/team/knowledge/raw/{commit}` for a workspace at the
81
84
  repository root. If the workspace is nested, append its repository-relative
82
85
  directory to the prefix because Context appends only the project-relative
83
86
  `knowledge/assets/...` path. This derivation is appropriate only when the
84
87
  service's raw convention and repository identity are confirmed; otherwise ask
85
- for the prefix or use bundled delivery. The fact that Context does not
86
- automatically recognize a host is not, by itself, a reason to bundle.
88
+ for the prefix or keep the default bundled delivery. Never invent a raw URL
89
+ only because Context does not automatically recognize a host.
87
90
 
88
91
  The resolved commit and raw URL participate in package freshness, so changing
89
92
  Git HEAD or the selected remote makes an existing package stale. Context does
@@ -114,26 +117,12 @@ assets: { delivery: "bundle" }
114
117
  assets: { delivery: "omit" } // keeps unresolved links and reports them
115
118
  ```
116
119
 
117
- Bundled resources are copied byte-for-byte unless image optimization is
118
- configured. When optimizable PNG/JPEG resources exceed 20 MiB, build and status
119
- return `package.assets.optimization-recommended`. To optimize bundled output:
120
-
121
- ```bash
122
- bun add -D sharp
123
- ```
124
-
125
- ```ts
126
- assets: {
127
- delivery: "bundle",
128
- optimize: { processor: "sharp", mode: "lossless-webp" },
129
- }
130
- ```
131
-
132
- `optimize.mode: "webp"` additionally accepts `quality` from 1 to 100. Both modes accept
120
+ Explicit `assets.optimize` overrides the automatic output policy.
121
+ `optimize.mode: "webp"` accepts `quality` from 1 to 100. Both modes accept
133
122
  an optional positive `maxDimension`; images are never enlarged. Context adopts
134
123
  a generated image only when it is smaller, uses a digest-derived `.webp` path,
135
- and rewrites package links. A configured but missing processor blocks before
136
- the previous `dist/` package is replaced.
124
+ and rewrites package links. If explicit settings cannot meet the package image
125
+ budgets, build stops before replacing the previous `dist/` package.
137
126
 
138
127
  `template` is required. Do not call `kbPackage({ name })` or
139
128
  `llmsPackage({ name })`.
@@ -287,13 +276,17 @@ Default navigation rules:
287
276
 
288
277
  - `wikis/index.md` is the required default bundle index. Other selected OKF
289
278
  roots always use their own `<okf-root>/index.md`.
290
- - With `foldDirectoryIndexes: true`, a non-root directory gets its own
291
- `index.md` only when its descendant knowledge-page count is greater than
292
- `maxInlineEntries`. The default threshold is `50`.
279
+ - With `foldDirectoryIndexes: true`, directory indexes are planned bottom-up.
280
+ A non-root directory gets its own `index.md` only when the page and child-index
281
+ entries it would expose to its parent are greater than `maxInlineEntries`.
282
+ The default threshold is `50`.
293
283
  - A folded directory is not discarded. Its pages are listed in the nearest
294
- generated ancestor index, grouped by their relative directory path.
295
- - The threshold counts selected knowledge pages in the path tree. It does not
296
- inspect Markdown line counts, headings, or content semantics.
284
+ generated ancestor index, grouped by their relative directory path, while
285
+ retained descendant indexes are linked directly from that ancestor. This
286
+ also removes large but navigation-thin intermediate directories.
287
+ - The threshold counts visible navigation entries after descendant indexes are
288
+ planned. It does not inspect Markdown line counts, headings, or content
289
+ semantics.
297
290
  - Set `foldDirectoryIndexes: false` to generate an `index.md` for every
298
291
  directory, matching the fully expanded navigation shape.
299
292
  - A generated directory index uses OKF frontmatter with `type: Knowledge
@@ -612,8 +612,65 @@ Options:
612
612
  | `mode` | `"exports"` (default) traces public exports from automatic or configured entries; `"scan"` uses every file matched by `include` as an entry root |
613
613
  | `entries` | Optional source-relative entry files for `"exports"` mode. They override `package.json` entry detection and live only in the Context project configuration |
614
614
  | `exportedOnly` | Defaults to `true` in `"exports"` mode and `false` in `"scan"` mode |
615
+ | `indexUnits` | Stable module/index plans used for ownership, capability and per-unit scale checks. A single-source exports-only package gets a compatible public-contract default; scan, collection and custom extraction require an explicit plan before formal writes |
615
616
  | `transform` | Optional markdown transform function or functions |
616
617
 
618
+ An explicit index unit records production intent rather than parser settings:
619
+
620
+ ```ts
621
+ extractTs({
622
+ source: componentLib,
623
+ collection: "codegraph",
624
+ indexUnits: [{
625
+ id: "component-public-api",
626
+ inputSources: ["20260712/component-lib"],
627
+ outputOwner: "component-lib",
628
+ moduleType: "sdk-library",
629
+ moduleTypes: ["sdk-library"],
630
+ facets: ["public-api", "plugin-extension"],
631
+ moduleTypeEvidence: ["package.json exports and src/index.ts public entry"],
632
+ outputProfile: "public-api-reference",
633
+ responsibility: "Document stable exported component contracts.",
634
+ entries: ["src/index.ts"],
635
+ pageKinds: ["module-map", "public-contract"],
636
+ protocols: [],
637
+ dependencies: [],
638
+ exclusions: ["src/internal/**", "src/generated/**"],
639
+ lifecycle: "authoritative",
640
+ sourceOfTruth: "src/index.ts",
641
+ capability: "complete",
642
+ }],
643
+ });
644
+ ```
645
+
646
+ `inputSources` names registered evidence sources; `outputOwner` is the one
647
+ stable page owner used for accounting and navigation. `capability` is
648
+ `"complete"`, `"project-adapter"`, or `"material-required"`. The last value
649
+ stops the Route until the plan is narrowed or reliable source material is
650
+ provided.
651
+
652
+ `moduleType` is the primary compact classification. `moduleTypes` may add other
653
+ applicable archetypes for a hybrid module, while `facets` records composable
654
+ behaviors such as routing, protocol consumption, events, persistence, plugins,
655
+ release, or cross-module chains. `moduleTypeEvidence` records the inspected
656
+ paths that support the classification. Classify first, then read the matching
657
+ Route-provided code-index templates, and only then finish the extraction plan.
658
+ `lifecycle` is `"authoritative"`, `"generated"`, `"mirrored"`, `"legacy"`,
659
+ or `"vendored"`; derived sources normally use `"provenance-only"` rather
660
+ than duplicating reader-facing pages. These are generic project facts, not
661
+ framework names inferred by the CLI.
662
+
663
+ `moduleType`, `moduleTypes`, `facets`, `outputProfile`, `lifecycle`, and
664
+ `capability` are runtime-validated closed values. Supported output profiles are
665
+ `module-map`, `application-map`, `protocol-index`, `service-boundary`,
666
+ `runtime-map`, `public-api-reference`, `command-map`, `adapter-contract`,
667
+ `module-registry`, `cross-module-flow`, and `provenance-only`.
668
+
669
+ `extractTs()` projects one candidate page per selected symbol, and each source
670
+ can belong to only one of its index units. Use `extractCustom()` for aggregated
671
+ maps, registries, protocol indexes, cross-module flows, or multiple candidate
672
+ owners over one source; custom candidates declare their owning `module`.
673
+
617
674
  `source` is the only package/module boundary. `include` narrows files inside
618
675
  that source; it does not select a second module. Standard packages can omit
619
676
  `entries` and use `package.json` `exports`, `main`, or `bin` detection. For a
@@ -631,7 +688,9 @@ extractTs({
631
688
 
632
689
  When the intended knowledge scope is every declaration in the selected files
633
690
  rather than a public export graph, use `mode: "scan"`. Scan mode does not accept
634
- `entries`; `include` supplies its file roots.
691
+ `entries`; `include` supplies its file roots. Because scan mode can expand
692
+ internal declarations into a symbol catalog, it requires an explicit
693
+ `indexUnits` plan before formal extraction.
635
694
 
636
695
  Entry failures use the stable machine code `NO_ENTRY_DETECTED`. This includes
637
696
  `entries: []`, exports mode with no detected/configured entry, and scan mode
@@ -663,6 +722,21 @@ does not infer which symbols are meaningful to a particular product or
663
722
  audience. Modules with skipped files include the deterministic traversal
664
723
  reason, such as files not reachable from exports-mode entries.
665
724
 
725
+ Before formal extraction, the workflow runs one batch preview for all pending
726
+ phases. Each `indexUnits[]` result reports projected Markdown pages, output
727
+ profile/owner, content-byte estimates, and risks. Per unit, 0–100 pages is
728
+ normal, 101–300 is a warning that may continue, and more than 300 is blocked.
729
+ The limit is non-delegatable, including in managed mode. A passing preview is
730
+ cached by digest under `.tmp/context-runtime/extract/previews/` and reused by
731
+ formal extraction when the source scope, phase declaration, project `src/`,
732
+ dependency lock, and preview protocol still match. A missing cache is
733
+ recoverable by rerunning the preview. The report includes cache hits,
734
+ extractor invocation count, current and projected page counts, changes,
735
+ exported/internal distribution, top directories, and advisory large-page
736
+ risks; only the 300-page per-unit limit is a hard scale gate.
737
+ A batch-total page advisory and quality risks such as a thin custom aggregate
738
+ remain report signals and do not create another Gate.
739
+
666
740
  Phase id shape:
667
741
 
668
742
  ```text
@@ -706,19 +780,53 @@ extractCustom({
706
780
  id: "extract:service:protocol",
707
781
  sources: [service],
708
782
  collection: "codegraph",
709
- extract: async ({ projectRoot }) => ({
783
+ indexUnits: [{
784
+ id: "service-protocol",
785
+ inputSources: ["20260811/service"],
786
+ outputOwner: "service",
787
+ moduleType: "api-service",
788
+ moduleTypes: ["api-service", "adapter"],
789
+ facets: ["protocol-provider", "protocol-consumer", "cross-module-chain"],
790
+ moduleTypeEvidence: ["src/protocol.ts registration and src/handler.ts dispatch"],
791
+ outputProfile: "protocol-index",
792
+ responsibility: "Document the stable service protocol boundary.",
793
+ entries: ["src/protocol.ts"],
794
+ pageKinds: ["protocol-index"],
795
+ protocols: ["declared service protocol"],
796
+ dependencies: [],
797
+ exclusions: ["generated/**"],
798
+ lifecycle: "authoritative",
799
+ capability: "project-adapter",
800
+ }],
801
+ extract: async ({ sources }) => {
802
+ const serviceRoot = sources.find((item) => item.name === "20260811/service")?.absolutePath;
803
+ if (serviceRoot === undefined) throw new Error("service source is not materialized");
804
+ const protocolEvidence = inspectProtocol(serviceRoot);
805
+ return {
710
806
  candidates: [{
711
807
  nodeRef: "service/protocol",
712
808
  kind: "protocol",
713
809
  visibility: "exported",
714
810
  module: "service",
715
- markdown: renderProtocol(projectRoot),
716
- evidence: [{
717
- source: "20260811/service",
718
- file: "src/protocol.ts",
719
- symbol: "protocol",
720
- kind: "variable",
721
- digest: "0123456789ab",
811
+ evidence: [protocolEvidence],
812
+ sections: [{
813
+ id: "contract",
814
+ kind: "contract",
815
+ title: "Provided contract",
816
+ markdown: renderContract(serviceRoot),
817
+ evidence: [protocolEvidence],
818
+ }, {
819
+ id: "operations",
820
+ kind: "operation",
821
+ title: "Operations",
822
+ markdown: renderOperations(serviceRoot),
823
+ evidence: inspectOperations(serviceRoot),
824
+ }, {
825
+ id: "handoff",
826
+ kind: "handoff",
827
+ title: "Implementation handoff",
828
+ markdown: renderHandoff(serviceRoot),
829
+ evidence: inspectHandoff(serviceRoot),
722
830
  }],
723
831
  review: {
724
832
  title: "Service protocol",
@@ -727,18 +835,50 @@ extractCustom({
727
835
  reason: "Review the project-owned extraction.",
728
836
  },
729
837
  }],
730
- }),
838
+ }},
731
839
  });
732
840
  ```
733
841
 
734
- `sources` is the complete registered repo scope for the phase. Every candidate
735
- and edge carries structured `evidence`; the CLI validates that evidence against
842
+ `sources` is the complete CLI-resolved repo scope for the phase. Resolve files
843
+ from `sources[].absolutePath`; do not embed a local or remote Agent checkout
844
+ path. Every candidate section and edge carries structured `evidence`; the CLI validates that evidence against
736
845
  the declared sources, creates canonical `source_ref` values, writes the symbol
737
846
  index, candidate ledger and Review snapshots atomically, and records a phase
738
- fingerprint. `context status` therefore treats this phase exactly like another
847
+ fingerprint. Evidence-scoped section `kind` values satisfy the selected output
848
+ profile's semantic coverage contract. A cross-module flow also requires at
849
+ least one source-backed structured edge. `context status` therefore treats this phase exactly like another
739
850
  pending code extraction target, and Review can verify snapshot freshness
740
851
  without a placeholder `extractTs` phase.
741
852
 
853
+ `indexUnits` is also the batch scale and ownership contract. Candidate
854
+ `module` must match one declared unit id or output owner. Older callbacks that
855
+ omit `indexUnits` remain compatible: Context groups candidates by `module` and
856
+ marks the plan as inferred. Once explicit units exist, an unmatched or
857
+ multiply-owned candidate blocks formal extraction instead of being guessed.
858
+ An inferred plan can be previewed for migration diagnostics, but formal writes
859
+ require the project to declare stable units and owners.
860
+
861
+ For a large adapter, `candidates` may be an `AsyncIterable` instead of an
862
+ array. Context consumes it incrementally and stops retaining full candidates
863
+ for an index unit after the 301st item proves that the unit is blocked. Array
864
+ callbacks remain supported and are reported as `legacy-preview`.
865
+
866
+ An optional generic `inspect` adapter can return source-backed module, entry,
867
+ protocol, dependency, lifecycle, and source-of-truth findings before candidate
868
+ collection. It may also return capability gaps tied to declared index-unit ids;
869
+ those gaps enter the one non-delegatable capability Gate. Internal framework
870
+ meaning stays in the project adapter and its referenced material.
871
+
872
+ The CLI also runs a lightweight structural probe before every custom preview.
873
+ It recognizes TypeScript symbols, React Router routes, Go symbols, Rush
874
+ workspace structure, and source-owned protocol schemas from generic manifests
875
+ and paths. The preview exposes all detected probes in
876
+ `inspection.structuralProbes` and records `structuralCoverage` on each index
877
+ unit. Candidate evidence must cover every probe applicable to the selected
878
+ output profile. Coverage is based on source-backed evidence paths, not Markdown
879
+ page count, so one aggregate page can pass while an entry-only static module
880
+ card cannot.
881
+
742
882
  The extractor returns knowledge semantics (`nodeRef`, rendered Markdown,
743
883
  Review summary and source-backed evidence). It must not write `knowledge/`,
744
884
  `.tmp/context-runtime/lifecycle/candidates.jsonl`, extraction fingerprints or
@@ -778,7 +918,9 @@ Available structural libraries include:
778
918
  The packages return syntax and repository facts only. They do not classify
779
919
  product meaning, choose candidate identities, or write lifecycle state. The
780
920
  knowledge project owns that mapping. Context CLI does not auto-install these
781
- packages and does not expose a built-in Go or Rush phase.
921
+ packages and does not expose a built-in Go or Rush phase. Detection does not
922
+ execute or replace an optional parser; it makes the matching parser contract
923
+ and its evidence coverage auditable before candidate writes.
782
924
 
783
925
  ### `reviewValidity`
784
926
 
@@ -237,9 +237,10 @@ The default KB template uses the variables above to generate a starter index:
237
237
  - links to generated directory indexes when a directory exceeds the configured
238
238
  inline-entry threshold.
239
239
 
240
- `context build` always provides selected OKF root indexes. By default, a
241
- non-root directory gets its own index only when it contains more than 50
242
- descendant knowledge pages. Configure this with
240
+ `context build` always provides selected OKF root indexes. By default,
241
+ directory indexes are planned bottom-up, and a non-root directory gets its own
242
+ index only when it would expose more than 50 page or retained child-index
243
+ entries to its parent. Configure this with
243
244
  `kbPackage({ navigation: { foldDirectoryIndexes, maxInlineEntries } })`.
244
245
 
245
246
  The output is only a starter. Edit the files under
@@ -18,6 +18,11 @@ Build runs only after close and verification are current. It writes declared
18
18
  packages under `dist/` and records an inventory receipt with added, updated,
19
19
  removed, and index changes.
20
20
 
21
+ When document optimization is enabled, its current revision batch must also be
22
+ resolved before build. Build compiles each approved page through its optional
23
+ `__revision.md` sidecar and records the policy and decision counts in the
24
+ package inventory. Revision sidecars are never emitted as separate knowledge.
25
+
21
26
  Run only the current route command, then evaluate again. A successful build
22
27
  means the currently declared scope is current; newly captured or newly declared
23
28
  targets can reopen earlier graph nodes.