@c4a/context 0.6.1 → 0.6.3

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.
@@ -27,7 +27,8 @@ Codegraph NodeRef/ViewRef and knowledge paths use the stable module name without
27
27
  the date:
28
28
 
29
29
  ```text
30
- knowledge/<collection>/<containment>/<slug>.md
30
+ knowledge/<collection>/<slug>.md
31
+ knowledge/<collection>/<containment>/<slug>.md # only for an intentional hierarchy
31
32
  knowledge/codegraph/<module>/symbol/<slug>.md
32
33
  repo:<date>/<module>#symbol:...
33
34
  file:<date>/<module>/<document>#span:...
@@ -48,6 +49,12 @@ knowledge/codegraph/module-a/...
48
49
  knowledge/codegraph/module-b/...
49
50
  ```
50
51
 
52
+ For prose Views, provide a stable filename `slug` and omit `path`; the CLI
53
+ derives the path. Omit `containment` when the page is an independent collection
54
+ entry, producing `knowledge/<collection>/<slug>.md`. Set `containment` only
55
+ when the approved structure intentionally places the page under a parent path;
56
+ it is not a required source/module wrapper.
57
+
51
58
  The registry stores this as one date entry containing several `modules` entries,
52
59
  and materializes each module at `sources/repo/<date>/<module>`.
53
60
  Repo module names are project-wide codegraph identities and therefore cannot be
@@ -133,7 +140,7 @@ is a repo, file, or lark source:
133
140
  ```ts
134
141
  import { source } from "@c4a/context";
135
142
 
136
- const legacyDocs = source("product-docs");
143
+ const productDocs = source("product-docs");
137
144
  ```
138
145
 
139
146
  ### `source(namespace, module)`
@@ -165,16 +172,18 @@ siblings under `sources/file|lark/<date>/` and share the date-level
165
172
  directory level.
166
173
 
167
174
  For a confirmed multi-document request, declare one capture phase per module.
168
- While any module is uncaptured, `context status --format json` reports either:
169
-
170
- - `needs-capture-phase` with `routing.configuration` when a module is not yet
171
- declared in `src/index.ts`; or
172
- - `needs-capture` with every declared command in `routing.command_plan`.
173
-
174
- Each command-plan item says whether it is `immediate` or
175
- `after-human-confirmation`. The `routing.human_gate` object identifies the
176
- decision type and whether its result lives only in the current conversation or
177
- is persisted by a later workspace command.
175
+ While any module is uncaptured, `context status --format json` selects either
176
+ the `route.capture.configuration-required` Route with
177
+ `workflow.current.configuration`, or the `route.capture.pending-target` Route
178
+ with the next declared command in `workflow.current.commands`.
179
+
180
+ Each command item declares its effect and availability. The current route's
181
+ `gate` identifies the decision and authority boundary. Write commands are bound
182
+ to the workflow revision; after one succeeds, rerun status instead of reusing
183
+ the old command. An external command also declares
184
+ `execution.target: agent-host`; execute it as a top-level Agent-host action so
185
+ network and credential-store access are not lost inside a restricted child
186
+ sandbox.
178
187
 
179
188
  ### `allSources("repo")`
180
189
 
@@ -200,9 +209,16 @@ extraction phases, review gates, close/build, and packages explicitly. The CLI
200
209
  then routes work through `context status`, `context run <phase-id>`, `context
201
210
  review html/apply`, `context close`, `context verify`, and `context build`.
202
211
 
212
+ For Agent and automation output, use `context verify --format json --compact`.
213
+ It returns deterministic groups, counts, affected-scope totals, and a few
214
+ representative samples instead of repeating every issue. Read the complete,
215
+ auditable issue set only when needed with `context verify --view diagnostics
216
+ --page-size 25 --format json`; follow its executable pagination command without
217
+ inventing overlapping file ranges.
218
+
203
219
  ### Status declaration coverage
204
220
 
205
- `context status --format json` includes a `declarationGraph` and
221
+ `context status --format json --view full` includes a `declarationGraph` and
206
222
  `configurationGaps` for document workflows. Each row reports capture, align,
207
223
  compile, and Review coverage for a canonical source plus collection. Gaps are
208
224
  non-blocking before structure confirmation. Once a structure is confirmed,
@@ -218,18 +234,20 @@ declarations are complete, status returns the exact align investigation command
218
234
  for the next target. A built package does not freeze the workspace or require a
219
235
  new workspace for later sources.
220
236
 
221
- Use `context status --format json --view summary` when only the current state,
222
- target, counts, diagnostics, and recommended command are needed. The full view
223
- retains source, phase, package, and lifecycle inventories.
237
+ `context status --format json` defaults to the compact workflow route, target,
238
+ progress, counts, and aggregated diagnostics. Use `--view full` only when
239
+ source, phase, package, and lifecycle inventories are needed for debugging.
224
240
 
225
241
  ### Current-conversation managed execution
226
242
 
227
243
  `context status --managed --format json` exposes
228
244
  `executionMode: { mode: "managed", scope: "current-conversation" }` and resolves
229
245
  eligible human gates into immediate commands. The flag is deliberately absent
230
- from `defineProject`: callers must pass it on each status/run/review command in
231
- the authorized conversation. A later process or conversation gets ordinary
232
- human-gated behavior by default.
246
+ from `defineProject`: callers start each workflow evaluation loop with managed
247
+ status, then execute the returned revision-bound command unchanged. Returned
248
+ commands carry a compact current-conversation marker instead of repeating every
249
+ authority. A later process or conversation gets ordinary human-gated behavior
250
+ by default.
233
251
 
234
252
  Managed Review is atomic and scope-validated:
235
253
 
@@ -238,10 +256,25 @@ context review approve-all <collection> --managed --format json
238
256
  context review approve-all --all --managed --format json
239
257
  ```
240
258
 
241
- Managed structure staging uses `context run <align-phase> --stage --managed
242
- --input <structure.yaml> --format json`. Source boundaries and unread source
243
- bodies, external operations, payload validation, deterministic close, and
244
- verification errors are never bypassed.
259
+ The default JSON result reports counts and change totals without listing every
260
+ candidate id or materialized path. Add `--verbose` only when debugging requires
261
+ the complete candidate and page details.
262
+
263
+ Managed structure confirmation and Review use only the revision-bound commands
264
+ returned by `workflow.current`. Source boundaries and unread source bodies,
265
+ external operations, payload validation, deterministic close, and verification
266
+ errors are never bypassed.
267
+
268
+ For consecutive mechanical routes, the Agent may run:
269
+
270
+ ```bash
271
+ context run --managed --until blocked-or-complete --format json
272
+ ```
273
+
274
+ This is a bounded host loop over the same revisioned routes. It stops before
275
+ read-only interpretation, project configuration, unresolved authority,
276
+ diagnostics, or a non-unique command plan; it does not add another workflow
277
+ entry or make semantic decisions.
245
278
 
246
279
  ### `captureFile`
247
280
 
@@ -295,6 +328,21 @@ Markdown snapshot:
295
328
  captureLark({ source: handbook });
296
329
  ```
297
330
 
331
+ Embedded resources are materialized with deterministic defaults. Video remains
332
+ reference-only unless a project opts into bundling, and byte limits prevent an
333
+ unexpected document from expanding the workspace without bound:
334
+
335
+ ```ts
336
+ captureLark({
337
+ source: handbook,
338
+ resources: {
339
+ videos: "bundle",
340
+ maxBytesPerResource: 20 * 1024 * 1024,
341
+ maxTotalBytes: 200 * 1024 * 1024,
342
+ },
343
+ });
344
+ ```
345
+
298
346
  Phase id:
299
347
 
300
348
  ```text
@@ -306,9 +354,34 @@ Register each source with
306
354
  flag: `--url`, `--doc-token`, or `--wiki-token`. Multiple documents may share
307
355
  one date batch; when `--module` is omitted, the CLI derives an opaque,
308
356
  credential-safe module id. Capture reads the
309
- remote document through the CLI runner, writes normalized snapshot files under
310
- `sources/lark/<date>/` as sibling document files tracked by one date-level `manifest.json`, and does not write access credentials into the
311
- workspace.
357
+ remote document through the CLI runner as structured Docx XML. Context keeps a
358
+ redacted XML audit asset, projects supported blocks deterministically into
359
+ readable Markdown, and materializes required inline resources such as images,
360
+ attachments, Sheets, Bases, whiteboards, diagrams, and synced blocks. Navigation
361
+ resources and default video capture remain explicit references. The projection
362
+ does not infer or summarize document meaning. Its fidelity and resource reports close discovered blocks
363
+ against converted and intentionally skipped blocks and reports evidence
364
+ completeness separately from Markdown projection quality. Unknown non-empty XML
365
+ blocks receive a generic, auditable, non-interactive projection and do not block
366
+ downstream work. A remote whiteboard or diagram explicitly confirmed as deleted
367
+ is preserved as an unavailable-resource notice with
368
+ `document.resource.source-missing` and a warning. An embedded resource whose
369
+ export is explicitly rejected as `authorization/permission_denied` is retained
370
+ the same way with `document.resource.permission-denied`. Missing scopes,
371
+ unresolved external-resource identity, retryable failures, and unclassified
372
+ authorization errors remain evidence errors and prevent downstream Review.
373
+ Snapshot files live under `sources/lark/<date>/` as sibling document files
374
+ tracked by one compact date-level `manifest.json`. Each module keeps one raw
375
+ `source.xml`, one consolidated `capture-report.json`, and its actual downloaded
376
+ or structured resources under `assets/<module>/materialized/`; it does not emit
377
+ one descriptor file per embedded resource. Access credentials and transient
378
+ signed media URLs are not written into the workspace.
379
+
380
+ Approved resource bytes are projected to content-addressed
381
+ `knowledge/assets/<kind>/` paths. KB build copies selected resources to
382
+ `others/assets/<kind>/` inside the package and rewrites page links. See
383
+ [Lark Resource Materialization](../guides/lark-resources.md) for the complete
384
+ resource table and storage lifecycle.
312
385
 
313
386
  Use a typed document reference in project declarations:
314
387
 
@@ -347,6 +420,7 @@ context run align:file:<source-name>:architecture --view read-plan --format json
347
420
  context run align:file:<source-name>:architecture --view source-index --compact --format json
348
421
  context run align:file:<source-name>:architecture --view span-detail --span <source-ref> --format json
349
422
  context run align:file:<source-name>:architecture --view span-text --span <source-ref> --format json
423
+ context run align:file:<source-name>:architecture --view existing-knowledge --query <title-or-stable-ref> --format json
350
424
  context run align:file:<source-name>:architecture --view schema --format json
351
425
  context run align:file:<source-name>:architecture --view semantic-rules --format json
352
426
  context run align:file:<source-name>:architecture --validate --input <structure.yaml> --format json
@@ -355,14 +429,64 @@ context run align:file:<source-name>:architecture --view structure-summary --inp
355
429
  context run align:file:<source-name>:architecture --stage --input <structure.yaml> --format json
356
430
  ```
357
431
 
358
- `--validate`, `--stage`, `--confirm`, and `--repair` are mutually exclusive
359
- operations. An `--input` without an operation is rejected unless the selected
360
- view explicitly consumes that input. Successful validation returns a stage
361
- command with the same file path. JSON run output keeps `next_action` first;
432
+ When `workflow.current.batch` is present, several independent document slots
433
+ can be prepared in one Agent pass and validated or staged through one command:
434
+
435
+ ```yaml
436
+ schema: context.prose.structure-batch.v1
437
+ items:
438
+ - phase_id: align:file:<source-a>:architecture
439
+ input: .tmp/agent-payloads/<source-a>-structure.yaml
440
+ - phase_id: align:file:<source-b>:architecture
441
+ input: .tmp/agent-payloads/<source-b>-structure.yaml
442
+ ```
443
+
444
+ ```bash
445
+ context run --batch-input .tmp/agent-payloads/prose-structure-batch.yaml --validate --format json
446
+ context run --batch-input .tmp/agent-payloads/prose-structure-batch.yaml --stage --managed --format json
447
+ ```
448
+
449
+ Batch preflight validates every payload before writing. Stage writes ready
450
+ slots serially; it does not merge documents or decide their semantic shape.
451
+
452
+ Align results expose a recommended `payload_target.path` under
453
+ `.tmp/agent-payloads/`. Agents should use it for transient structure inputs and
454
+ may remove the file after a successful stage. The CLI continues to accept an
455
+ explicit alternative path; this is an authoring convention, not validation.
456
+
457
+ For the ordinary path, `read-plan` is a complete authoring packet: it includes
458
+ the payload contract, a budgeted canonical source-ref map, exact source-body
459
+ resources, and a direct `--stage` command. Read the bodies, author the payload,
460
+ and run that stage command. Request `source-index` only when the packet reports
461
+ omitted refs, and request `existing-knowledge` only when reusing or checking an
462
+ approved identity. The separate schema and validate views are optional
463
+ diagnostic tools, not required lifecycle steps.
464
+
465
+ `--validate`, `--stage`, and `--confirm` are mutually exclusive operations. An
466
+ `--input` without an operation is rejected unless the selected view explicitly
467
+ consumes that input. Deterministic boundary repairs run internally before the
468
+ result is returned. `self_healed` includes input/output Section counts, the
469
+ number of original Sections split, and structural reason codes. Stage performs validation before writing and returns the
470
+ same diagnostics on failure; in managed mode, a valid stage also confirms the
471
+ structure. Successful standalone validation returns a stage command with the
472
+ same file path. JSON run output keeps `next_action` first;
362
473
  schema and full reports stay behind explicit Views, while `--verbose` restores
363
474
  the full phase result and repeated contracts. Long diagnostics return a compact
364
475
  first page plus an exact diagnostics continuation command.
365
476
 
477
+ Validation returns `state: ready | repair-required | invalid`. Only `ready`
478
+ sets `valid: true` and may proceed to stage. `error_free: true` with
479
+ `state: repair-required` means no error diagnostic remains, but a declared
480
+ confirmation blocker still requires repair; it is not a successful result.
481
+
482
+ `existing-knowledge` is the authoring-time lookup for approved identities. It
483
+ returns stable NodeRefs, ViewRefs, titles, tags, collections, and section counts
484
+ without exposing workspace storage paths. `--query` performs deterministic
485
+ case-insensitive exact/prefix/substring matching; `--collection`,
486
+ `--node-type`, `--page-size`, and the returned continuation command narrow or
487
+ page the same View. Use it after reading source evidence and before introducing
488
+ a new Node identity. Structure validation remains the final duplicate gate.
489
+
366
490
  Align and compile evidence results include `semantic_rules`. Its `required`
367
491
  array is the rule subset selected for the current judgment, with a selection
368
492
  reason and content digest for each rule. `handle`, `digest`, and
@@ -383,22 +507,35 @@ cross multiple heading paths, without classifying document topics.
383
507
 
384
508
  After capture, the capture phase itself exposes collection-neutral `read-plan`,
385
509
  `source-index`, `span-detail`, `span-text`, and other read-only evidence views.
386
- Status reports `captured-ready-to-classify` until every captured target has an
387
- evidence-backed, user-confirmed align declaration. Align then adds `schema` and
388
- `structure-summary` for structure work. Agents should not inspect `sources/` or
389
- `.tmp` directly.
390
-
391
- Compile `read-plan`, `blockers`, `node-context`, and `schema` Views are also
392
- workspace-read-only and may run concurrently. `--validate`, `--stage`,
393
- structure confirmation, Review apply, and close are serial mutations.
510
+ Status selects `route.document.classification-required` until every captured
511
+ target has an evidence-backed, user-confirmed align declaration. Align then
512
+ adds `schema` and `structure-summary` for structure work. Agents should not
513
+ scan `sources/` or `.tmp` to invent evidence. They may read only the exact
514
+ source-body files selected as required resources by the current Route; those
515
+ files carry stable content digests and must be read in full before a receipt is
516
+ reported. Read all required direct paths, then execute the Route's single
517
+ `resources.after_read.command`; the CLI writes and carries the merged receipt
518
+ set without requiring Agent-authored JSON. That acknowledgement response
519
+ already contains the re-evaluated `workflow.current`, so no additional status
520
+ command is needed.
521
+
522
+ Generated Context Views use the same content-addressed rule. Materialization
523
+ returns a receipt-set path and an exact post-read command. Read the complete
524
+ file, then execute that command; unchanged content remains current across
525
+ workflow revisions, while write and external commands still require the exact
526
+ current revision.
527
+
528
+ Compile `read-plan`, `blockers`, and `diagnostics` Views are workspace-read-only
529
+ and may run concurrently. Compile `--validate`, compile `--stage`, structure
530
+ confirmation, Review apply, and close are serial operations.
394
531
 
395
532
  Structure payloads use `schema_version: "context.structure.v1"` and canonical
396
533
  `file:` / `lark:` `#span` source refs. A one-file-to-one-page plan is represented
397
534
  as ordinary `nodes[]` and `views[]` in the structure. It does not bypass
398
535
  structure confirmation or compile. Continuity applies to each Section, while one View/Page may
399
- contain multiple independently retrievable continuous Sections. The optional
400
- `suggested-splits` repair can expand a broad cross-heading Section into Markdown
401
- structural groups without creating child Views.
536
+ contain multiple independently retrievable continuous Sections. Deterministic
537
+ boundary splitting is applied internally during validate/stage; it is not a
538
+ separate Agent-authored payload or approval step.
402
539
 
403
540
  ### `compileProse`
404
541
 
@@ -423,35 +560,30 @@ compile:file:<source-name>:architecture
423
560
  compile:lark:<source-name>:architecture
424
561
  ```
425
562
 
426
- Compile requires confirmed `unapproved/structure.yaml`. It freezes the current
427
- structure for the compile round; if the user wants to change nodes, section
428
- ownership, or relationships, return to the align/structure gate.
563
+ Compile requires confirmed CLI-managed lifecycle structure. It freezes the
564
+ current structure for the compile round; if the user wants to change nodes,
565
+ section ownership, or relationships, return to the align/structure gate.
429
566
 
430
567
  Common commands:
431
568
 
432
569
  ```bash
433
570
  context run compile:file:<source-name>:architecture --view read-plan --format json
434
- context run compile:file:<source-name>:architecture --view node-context --source <view-ref> --format json
435
- context run compile:file:<source-name>:architecture --view schema --format json
436
- context run compile:file:<source-name>:architecture --validate --input <compile-actions.yaml> --format json
437
- context run compile:file:<source-name>:architecture --stage --input <compile-actions.yaml> --format json
438
- ```
439
-
440
- Compile remains one View per write for evidence isolation. After staging, follow
441
- `continue_compile_batch` to prepare the next View. Each canonical source plus
442
- collection is confirmed as an independent structure slot. When other captured
443
- align targets remain pending, status routes to those slots before opening one
444
- collection-level Review payload. `context close` is blocked while a planned
445
- View is unprepared, still draft, or rejected without a structure revision.
446
-
447
- Compile action payloads use `schema_version: "context.compile-actions.v1"`.
448
- By default, actions should omit body content and let the CLI mirror cited source
449
- spans into `verbatim` sections. Explicit reader-visible content is not accepted
450
- by the current compile action contract; split source evidence or return to the
451
- structure gate instead. The current approved section wire contract accepts `verbatim` and `empty`;
452
- it does not accept rewritten or mechanical projection modes.
453
- Relationships stay in `structure.yaml` typed edges in current output; do not
454
- inject relation markers into verbatim body.
571
+ context run compile:file:<source-name>:architecture --validate --format json
572
+ context run compile:file:<source-name>:architecture --stage --format json
573
+ context run compile:file:<source-name>:architecture --view diagnostics --format json
574
+ ```
575
+
576
+ Compile validates the complete confirmed source/collection slot before writing
577
+ any candidate, then materializes the slot atomically. Section bodies are
578
+ source-mirrored from the confirmed spans; the Agent does not create a separate
579
+ compile-actions payload. Each canonical source plus collection remains an
580
+ independent structure slot. When other captured align targets remain pending,
581
+ status routes to those slots before opening one collection-level Review
582
+ payload. `context close` is blocked while a planned View is unprepared, still
583
+ draft, or rejected without a structure revision.
584
+
585
+ Relationships stay in `structure.yaml` typed edges in current output; compile
586
+ does not infer relationships or inject relation markers into verbatim body.
455
587
 
456
588
  ### `extractTs`
457
589
 
@@ -514,12 +646,16 @@ package from a larger monorepo source.
514
646
  Use `context source inspect <date>/<module>` to list detected module/package
515
647
  boundaries before choosing the source. Use `context run <phase-id> --dry-run
516
648
  --format json` to check the resolved modules, file counts, symbol counts, and
517
- candidate estimate before writing `unapproved/entities.jsonl`. The dry-run
649
+ candidate estimate before writing the ignored lifecycle candidate ledger. The dry-run
518
650
  preview also includes `knowledgeTree` and `knowledgePathExamples`, which show
519
651
  where approved Markdown will land after review apply.
520
652
  Its module and total summaries distinguish `discoveredFiles`, `analyzedFiles`,
521
- `skippedFiles`, `symbols`, and `relations`; modules with skipped files include
522
- the reason, such as files not reachable from exports-mode entries.
653
+ `skippedFiles`, `symbols`, and `relations`. Module summaries also expose the
654
+ resolved `entryFiles`, exported/internal symbol counts, and a structural
655
+ `candidateKinds` count. These fields describe extractor output only; the CLI
656
+ does not infer which symbols are meaningful to a particular product or
657
+ audience. Modules with skipped files include the deterministic traversal
658
+ reason, such as files not reachable from exports-mode entries.
523
659
 
524
660
  Phase id shape:
525
661
 
@@ -531,8 +667,9 @@ Codegraph extraction has two execution policies:
531
667
 
532
668
  - `context run <phase-id>` is the Agent/user default. The first run sends every
533
669
  code symbol to Review. Later runs preserve unchanged approved symbols and send
534
- only `add`, `update`, and `remove` deltas to Review. If there is no delta, the
535
- result returns `next_action.human_gate=false` and the Agent continues.
670
+ only `add`, `update`, and `remove` deltas to Review. After every phase result,
671
+ the Agent re-evaluates `context status --format json`; only
672
+ `workflow.current` decides whether Review is now required.
536
673
  - `context run <phase-id> --auto-promote` is the explicit CI/CD path. It is valid
537
674
  only for `phase.extract.ts` codegraph phases, applies deterministic code deltas
538
675
  without Review, refreshes deterministic close when approved knowledge changed,
@@ -542,8 +679,9 @@ Codegraph extraction has two execution policies:
542
679
  separate pipeline step; existing package outputs are reported stale.
543
680
 
544
681
  This policy never auto-promotes architecture, business, decision, test, or
545
- other semantic knowledge. Agents must follow the returned
546
- `next_action.human_gate` instead of assuming every extraction requires Review.
682
+ other semantic knowledge. Agents must not infer a human gate from a phase-local
683
+ result. Human gates and their inspection/resolution Actions are exposed only by
684
+ `workflow.current`.
547
685
 
548
686
  Approved codegraph sections use the local evidence form
549
687
  `src-N#symbol:<file>:<symbol>:<kind>@<digest>`. The file segment makes reverse
@@ -551,18 +689,55 @@ lookup exact when multiple files contain the same symbol name, kind, and digest;
551
689
  the complete ref remains opaque to agents. New pages keep only top-level
552
690
  `candidate_fingerprint` and do not emit `code_origin`.
553
691
 
554
- Projects created by the beta.5 protocol can upgrade approved pages without a
555
- second human decision. Rerun every declared codegraph extraction phase to write
556
- the current file-aware symbol index, then run:
692
+ ### `extractCustom`
557
693
 
558
- ```bash
559
- context review migrate-codegraph-refs
560
- context verify
694
+ Use a project-owned extractor when code facts cannot be represented by the
695
+ TypeScript symbol extractor, for example a language-specific parser or an
696
+ aggregated repository protocol:
697
+
698
+ ```ts
699
+ extractCustom({
700
+ id: "extract:service:protocol",
701
+ sources: [service],
702
+ collection: "codegraph",
703
+ extract: async ({ projectRoot }) => ({
704
+ candidates: [{
705
+ nodeRef: "service/protocol",
706
+ kind: "protocol",
707
+ visibility: "exported",
708
+ module: "service",
709
+ markdown: renderProtocol(projectRoot),
710
+ evidence: [{
711
+ source: "20260811/service",
712
+ file: "src/protocol.ts",
713
+ symbol: "protocol",
714
+ kind: "variable",
715
+ digest: "0123456789ab",
716
+ }],
717
+ review: {
718
+ title: "Service protocol",
719
+ summary: "Aggregated protocol boundary.",
720
+ signals: ["source-backed"],
721
+ reason: "Review the project-owned extraction.",
722
+ },
723
+ }],
724
+ }),
725
+ });
561
726
  ```
562
727
 
563
- Migration resolves each legacy ref against the trusted index and its existing
564
- origin metadata, removes `code_origin`, preserves the approved body and review
565
- state, and rolls back all page writes if final verification fails.
728
+ `sources` is the complete registered repo scope for the phase. Every candidate
729
+ and edge carries structured `evidence`; the CLI validates that evidence against
730
+ the declared sources, creates canonical `source_ref` values, writes the symbol
731
+ index, candidate ledger and Review snapshots atomically, and records a phase
732
+ fingerprint. `context status` therefore treats this phase exactly like another
733
+ pending code extraction target, and Review can verify snapshot freshness
734
+ without a placeholder `extractTs` phase.
735
+
736
+ The extractor returns knowledge semantics (`nodeRef`, rendered Markdown,
737
+ Review summary and source-backed evidence). It must not write `knowledge/`,
738
+ `.tmp/context-runtime/lifecycle/candidates.jsonl`, extraction fingerprints or
739
+ Review snapshots directly. Context owns those files and preserves rejected and
740
+ unchanged-approved decisions across reruns.
566
741
 
567
742
  ### `reviewValidity`
568
743
 
@@ -603,7 +778,8 @@ structure slots and every declared `pendingStructureTargets` item in the round;
603
778
  codegraph waits for every pending extract phase in the confirmed module round.
604
779
  Candidate count/hash therefore describes the complete current batch rather than
605
780
  one page, source slot, or module. Deterministic close later merges all active
606
- slots into `knowledge/structure.yaml`.
781
+ slots into `knowledge/structure.yaml`, retains only their source, collection,
782
+ and consumed snapshot hash as `source_inputs`, then removes the lifecycle slots.
607
783
 
608
784
  `status.structureBatch` lists unclassified, configuration-required, pending,
609
785
  and active structure slots together with the execution policy for the round.
@@ -634,8 +810,9 @@ customPhase("custom:20260712/sample:review", async (ctx) => {
634
810
  });
635
811
  ```
636
812
 
637
- Custom phases are an escape hatch. Prefer built-in factories for source,
638
- extract, review, and package workflows. The supported runtime helpers are:
813
+ Custom phases are an orchestration escape hatch. Use `extractCustom()` instead
814
+ when project code needs to publish codegraph candidates. The supported runtime
815
+ helpers are:
639
816
 
640
817
  - `ctx.ensureSources(...)` for repo source readiness.
641
818
  - `ctx.extract.ts(...)` for declared TypeScript extraction.
@@ -91,6 +91,15 @@ Read node_modules/@c4a/context/docs/reference/template-variables.md.
91
91
  |---|---|---|
92
92
  | `packageName` | string | Package name from `kbPackage()` / `llmsPackage()`. |
93
93
  | `packageKind` | string | `kb` or `llms`. |
94
+ | `knowledgeNamespace` | string | Legacy configured namespace when an older workspace still declares one; otherwise empty. It does not change output paths. |
95
+ | `namespacedKnowledge` | boolean | Always `false`; retained so older templates remain renderable. |
96
+ | `skillsRoot` | string | Skills root, currently `skills`. |
97
+ | `wikisRoot` | string | Final wikis root: `wikis`. |
98
+ | `guidesRoot` | string | Final guides root: `guides`. |
99
+ | `rulesRoot` | string | Final rules root: `rules`. |
100
+ | `featsRoot` | string | Final feats root: `feats`. |
101
+ | `skillName` | string | Author-maintained name of the Skill currently being rendered. Empty outside a `skills/<name>/...` template. |
102
+ | `skillPath` | string | Final package-relative `SKILL.md` path for the Skill currently being rendered. Empty outside a Skill template. |
94
103
  | `knowledgeCount` | number | Selected approved Markdown file count. |
95
104
  | `knowledgeTimestamp` | string | Latest selected approved Markdown `timestamp`, or epoch when empty. |
96
105
  | `knowledge` | string | Concatenated selected approved Markdown bundle. Use carefully; it can be large. |
@@ -100,7 +109,7 @@ Read node_modules/@c4a/context/docs/reference/template-variables.md.
100
109
  | `knowledgeTreeNodes` | array | Nested path tree for selected pages. Useful for custom navigation. |
101
110
  | `knowledgeTree` | string | Markdown tree preview of selected pages. |
102
111
  | `knowledgeItemsMarkdown` | string | Markdown list of up to 50 selected pages. |
103
- | `knowledgeGroupsMarkdown` | string | Markdown list of first-level directories with links to their generated `index.md` files. |
112
+ | `knowledgeGroupsMarkdown` | string | Markdown navigation for the current index. Folded directories render direct page links; expanded directories render links to generated indexes. |
104
113
  | `buildInventory` | object | Deterministic package build inventory, including selected files, selected-by reasons, collection summaries, and package-visible edge records. |
105
114
  | `buildInventoryJson` | string | Pretty JSON form of `buildInventory`. |
106
115
  | `buildInventoryPath` | string | Package-relative inventory path, currently `context-build-inventory.json`. |
@@ -130,6 +139,7 @@ Each item contains:
130
139
  | `internal_collection` | Alias for `internalCollection`. |
131
140
  | `collection` | Internal approved collection; alias for `internalCollection`. |
132
141
  | `okf_root` | OKF output root, for example `wikis`, `guides`, `rules`, or `feats`. |
142
+ | `okf_root_path` | Final flat package-relative OKF root. |
133
143
  | `node_ref` | Stable NodeRef from approved frontmatter, for example `entity/button`. |
134
144
  | `view_ref` | Stable ViewRef from approved frontmatter, for example `architecture:entity/button`. |
135
145
  | `pathWithinCollection` | Path below the OKF root, for example `component-lib/symbol/button.md`. |
@@ -167,10 +177,13 @@ Each group contains:
167
177
  | `internalCollection` | Internal approved collection; alias for `collection`. |
168
178
  | `internal_collection` | Alias for `internalCollection`. |
169
179
  | `okf_root` | OKF output root for this group, for example `wikis`, `guides`, `rules`, or `feats`. |
180
+ | `okf_root_path` | Final flat package-relative OKF root. |
170
181
  | `title` | Display title; defaults to `name`, or the OKF root title for a root group. |
171
182
  | `count` | Number of selected pages in this group. |
183
+ | `hasIndex` | Whether the active package navigation policy generates `indexPath`. |
184
+ | `has_index` | Alias for `hasIndex`. |
172
185
  | `indexPath` | OKF-root-aware index path, for example `wikis/component-lib/index.md`, `guides/component-lib/index.md`, or `rules/index.md` for a root group. |
173
- | `indexHrefFromTemplate` | Link from the template file currently being rendered to `indexPath`. Use this in custom templates. |
186
+ | `indexHrefFromTemplate` | Link from the template file currently being rendered to `indexPath`. Check `hasIndex` before rendering it. |
174
187
  | `indexHrefFromCollectionIndex` | Link from the OKF root index to `indexPath`. |
175
188
  | `items` | `knowledgeItems` in the group. |
176
189
 
@@ -178,8 +191,11 @@ Example:
178
191
 
179
192
  ```md
180
193
  {{#each knowledgeGroups}}
181
- ## [{{title}}]({{indexHrefFromTemplate}}) ({{count}})
194
+ ## {{title}} ({{count}})
182
195
 
196
+ {{#if hasIndex}}
197
+ [Open directory index]({{indexHrefFromTemplate}})
198
+ {{/if}}
183
199
  {{#each items}}
184
200
  - [{{title}}]({{href}}) - {{type}}
185
201
  {{/each}}
@@ -211,15 +227,16 @@ care about.
211
227
  The default KB template uses the variables above to generate a starter index:
212
228
 
213
229
  - bundle count and timestamp in OKF frontmatter;
214
- - next-level directory links;
215
- - links to generated directory indexes such as `wikis/<group>/index.md` or
216
- another selected OKF root's `<okf-root>/<group>/index.md`.
217
-
218
- `context build` also generates `index.md` files for directories under selected
219
- OKF roots when a directory does not already contain one. The root
220
- `wikis/index.md` should stay shallow by default; put detailed navigation in the
221
- generated child indexes or in custom template sections.
222
-
223
- The output is only a starter. Edit
224
- `src/package-templates/kb/wikis/index.md` to add project-specific reading
225
- paths, API entry points, or task-focused navigation before `context build`.
230
+ - direct page links for directories folded by the active navigation policy;
231
+ - links to generated directory indexes when a directory exceeds the configured
232
+ inline-entry threshold.
233
+
234
+ `context build` always provides selected OKF root indexes. By default, a
235
+ non-root directory gets its own index only when it contains more than 50
236
+ descendant knowledge pages. Configure this with
237
+ `kbPackage({ navigation: { foldDirectoryIndexes, maxInlineEntries } })`.
238
+
239
+ The output is only a starter. Edit the files under
240
+ `src/package-templates/kb/` when the package needs different reading paths or
241
+ navigation before `context build`. An unchanged generated starter must instead
242
+ be explicitly accepted through the current package-template Review Route.