@davidorex/pi-context 0.31.0 → 0.33.0

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 (77) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/README.md +16 -14
  3. package/dist/block-api.d.ts +20 -33
  4. package/dist/block-api.d.ts.map +1 -1
  5. package/dist/block-api.js +154 -3
  6. package/dist/block-api.js.map +1 -1
  7. package/dist/content-hash.d.ts +9 -0
  8. package/dist/content-hash.d.ts.map +1 -1
  9. package/dist/content-hash.js +11 -0
  10. package/dist/content-hash.js.map +1 -1
  11. package/dist/context-sdk.d.ts +157 -39
  12. package/dist/context-sdk.d.ts.map +1 -1
  13. package/dist/context-sdk.js +896 -251
  14. package/dist/context-sdk.js.map +1 -1
  15. package/dist/context.d.ts +158 -5
  16. package/dist/context.d.ts.map +1 -1
  17. package/dist/context.js +75 -5
  18. package/dist/context.js.map +1 -1
  19. package/dist/index.d.ts +151 -19
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +590 -97
  22. package/dist/index.js.map +1 -1
  23. package/dist/lens-view.d.ts +0 -5
  24. package/dist/lens-view.d.ts.map +1 -1
  25. package/dist/lens-view.js +43 -1
  26. package/dist/lens-view.js.map +1 -1
  27. package/dist/migration-registry-loader.d.ts +20 -12
  28. package/dist/migration-registry-loader.d.ts.map +1 -1
  29. package/dist/migration-registry-loader.js +46 -17
  30. package/dist/migration-registry-loader.js.map +1 -1
  31. package/dist/migrations-store.d.ts +45 -18
  32. package/dist/migrations-store.d.ts.map +1 -1
  33. package/dist/migrations-store.js +56 -22
  34. package/dist/migrations-store.js.map +1 -1
  35. package/dist/ops-registry.d.ts +18 -0
  36. package/dist/ops-registry.d.ts.map +1 -1
  37. package/dist/ops-registry.js +474 -130
  38. package/dist/ops-registry.js.map +1 -1
  39. package/dist/promote-item.d.ts.map +1 -1
  40. package/dist/promote-item.js +41 -12
  41. package/dist/promote-item.js.map +1 -1
  42. package/dist/roadmap-plan.d.ts +121 -99
  43. package/dist/roadmap-plan.d.ts.map +1 -1
  44. package/dist/roadmap-plan.js +281 -345
  45. package/dist/roadmap-plan.js.map +1 -1
  46. package/dist/status-vocab.d.ts +12 -2
  47. package/dist/status-vocab.d.ts.map +1 -1
  48. package/dist/status-vocab.js +14 -1
  49. package/dist/status-vocab.js.map +1 -1
  50. package/package.json +2 -2
  51. package/samples/blocks/milestone.json +3 -0
  52. package/samples/blocks/session-notes.json +1 -0
  53. package/samples/conception.json +315 -15
  54. package/samples/migrations.json +8 -0
  55. package/samples/schemas/context-contracts.schema.json +4 -0
  56. package/samples/schemas/conventions.schema.json +4 -0
  57. package/samples/schemas/decisions.schema.json +4 -0
  58. package/samples/schemas/features.schema.json +4 -0
  59. package/samples/schemas/framework-gaps.schema.json +9 -0
  60. package/samples/schemas/issues.schema.json +28 -0
  61. package/samples/schemas/layer-plans.schema.json +4 -0
  62. package/samples/schemas/milestone.schema.json +79 -0
  63. package/samples/schemas/phase.schema.json +4 -0
  64. package/samples/schemas/rationale.schema.json +4 -0
  65. package/samples/schemas/requirements.schema.json +4 -0
  66. package/samples/schemas/research.schema.json +45 -2
  67. package/samples/schemas/session-notes.schema.json +89 -0
  68. package/samples/schemas/spec-reviews.schema.json +4 -0
  69. package/samples/schemas/story.schema.json +8 -0
  70. package/samples/schemas/tasks.schema.json +4 -0
  71. package/samples/schemas/verification.schema.json +4 -0
  72. package/samples/schemas/work-orders.schema.json +4 -0
  73. package/schemas/config.schema.json +90 -4
  74. package/schemas/migrations.schema.json +25 -0
  75. package/skill-narrative.md +8 -6
  76. package/skills/pi-context/SKILL.md +70 -63
  77. package/skills/pi-context/references/bundled-resources.md +5 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,79 @@ All notable changes to this package are documented here. Format follows [Keep a
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.33.0] - 2026-07-08
8
+
9
+ - Substrate-internal paths are never pinned or judged by the staleness machinery: the write choke skips pinning/baselining any path resolving inside the substrate dir, and the staleness evaluator never judges a hand-authored pin or baseline on one — block files are living state that changes on every substrate write, so such a pin would drift immediately and flag anchor-drift forever.
10
+ - Declared-baseline currency is machine-evaluable (typed staleness + content pins): research `stale_conditions` items additively admit typed variants alongside bare strings — `{kind:'item-status', item, bucket}` (fires when the watched item's status buckets there; the reference field is deliberately not named `id`, which is the Phase-H nested-id-bearing-array trigger), `{kind:'file-changed', path, baseline_hash}` and `{kind:'revision-moved', ref, baseline_sha}` — bare strings stay human-only. The identity write choke stamps declared baselines before the content hash is computed: path-bearing citation/evidence entries whose item subschema declares `content_pin` get a raw-bytes sha-256 of the referenced file (new `computeFileBytesHash`; the JSON-canonical `computeFileContentHash` parses files as JSON and is the wrong fingerprint for arbitrary cited files), a `file-changed` condition without a baseline gets the file's current hash, and a `revision-moved` condition without a baseline gets the ref's current commit — existing pins/baselines are never overwritten, unreadable files/refs are left unstamped (human-only), and stamping is schema-gated so undeclaring substrates are untouched. `context-validate` flags a complete `stale_conditions`-bearing item whose typed condition fired or whose pin drifted as a `staleness-candidate` (warning) and any other pinned-and-drifted item as `anchor-drift` (warning) — validate never mutates. `context-reconcile`'s sweep grows the transition half through the same `evaluateStalenessCandidates` verdict: `--dryRun` previews the exact `stalenessTransitions` set; a live run applies the complete-to-stale transitions through the validated write path (`stalenessApplied`); anchor-drift items never transition. Both schema changes are additive (oneOf widening + optional pin fields) — existing data validates unchanged, no migration.
11
+ - Birth-relations entries afford the role-typed orientation form: each `relations` entry on `append-block-item` / append-mode `upsert-block-item` now carries exactly one of `direction: as_parent|as_child` (raw — unchanged semantics) or `role: primary|counter` (the semantic role the NEW item holds; `other` holds the complement), mapped to the role-typed append input and delegated to the same porcelain, so orientAppendInput's guards apply verbatim. Previously the entry shape was direction-only, and the porcelain's rejection of a bare append for role-bearing orientation-ambiguous relation_types (14 of the registry's 17 role-bearing types — the same-kind ordering relations plus the wildcard gated-by/derived-from/includes/depends families) carried a re-issue-with-primary/counter instruction the shape could not express, making the filing atom unusable exactly where an error-severity invariant demands such a birth edge. The direction/role mutual exclusion is enforced at coercion, before any write. `upsert-block-item --dryRun` additionally runs the same role-mapping + orientation-ambiguity guard over the entries (registry-only; endpoint resolution stays out since the item is unwritten), so a preview refuses what the live run would orientation-refuse — previously a preview reported would-file for entries the live run rejects.
12
+ - `complete-task` is the closure transition atom: it files the `verification_verifies_item` edge itself (verification=parent, task=child; idempotent — an exact pre-existing edge is a dedup no-op, reported as `edgeAppended` on the result) and flips the task status in one op run, replacing the prior contract that required a standalone `append-relation` first and threw "does not verify task" when the edge was absent. That two-op sequence deadlocks under an error-severity closure invariant pair (a passed verification must verify a completed task / a completed task must have a verification edge): each order's intermediate resting state is itself the violation, so the write-time gate refuses both — only the joint end-state written by one op is legal. The op's error text no longer instructs a sequence the gate refuses.
13
+ - `append-block-item` and append-mode `upsert-block-item` accept an optional `relations` array filing the new item's BIRTH edges in the same op run, after auto-id allocation, through the same validated porcelain as `append-relation` (registered-type + endpoint-kind gate, atomic write, duplicate no-op): each entry names the `relation_type`, the endpoint the new item occupies (`direction: as_parent | as_child`), the `other` endpoint's selector, and an optional `ordinal`. A new item can thereby satisfy an error-severity birth-edge invariant (e.g. a decision must cite a forcing artifact) that would refuse the bare filing. A replace-mode upsert supplied with `relations` refuses the write (birth edges are new-item-only; the refusal is byte-restored).
14
+ - The write pipeline is all-or-nothing at the op level: an op that throws mid-run (a birth edge failing after its item landed, a composite ceremony failing between writes) byte-restores every top-level substrate `*.json` from the pre-write snapshot before rethrowing — previously the restore fired only on the gate's own refusal, so a mid-composite throw could persist a partial write in a state the gate never judged. Same snapshot gating as the refusal path (substrates declaring no invariants are unaffected).
15
+ - `upsert-block-item` joined the write-pipeline op set (converge-on-write + delta-scoped gate + throw-restore) — it mutates items exactly like `update-block-item` and was previously unwrapped.
16
+ - Delta-scoped write-time invariant gate: the rollup-input-mutating ops re-evaluate the config invariants after their write through the same path `context-validate` uses (identical verdicts by construction), acting ONLY on violations newly introduced by that write — error severity refuses the write with every top-level substrate `*.json` byte-restored from the pre-write snapshot and the op throwing the violation messages; warning severity is surfaced on the op result (`write-warning:` lines on string results, a `writeWarnings` array inside `{json}` object payloads). Pre-existing violations never block or warn, so legacy substrates stay fully writable; substrates declaring no invariants bypass the gate entirely; `--dryRun` previews bypass the whole write pipeline. Convergence runs before the gate evaluation, so a divergence the write's own convergence repairs is never flagged.
17
+ - Converge-on-write: the sanctioned mutating ops that can change a rollup input (item writes, relation writes, complete-task, rename-canonical-id, promote-item) run the derived-status convergence after their write lands, so an op-surface write leaves rollup-kind stored statuses equal to their derivation with no reconcile run needed. Convergence triggers on non-throw (these ops throw on failure and return success strings), skips --dryRun previews, is config-driven opt-in (no derived-status invariant declared → inert, byte-identical behavior), and is best-effort by design: it never establishes identity and never fails the caller's landed write — a convergence failure leaves the divergence for the invariant to detect and `context-reconcile` to repair.
18
+ - New `context-reconcile` op (auth-gated; CLI-reflected): converges stored substrate state with its derivation — the repair half of the `derived-status` invariant class. For every kind a `derived-status` invariant declares, it computes each item's stored-vs-derived status delta with the same completeness helper the state derivation and `context-validate` use (preview, detector, and repair cannot disagree). `--dryRun` returns the exact delta set a live run would apply, writing nothing; a live run applies exactly that set through the standard validated write path (identity-stamped, envelope-stamped, attested to the invoking writer) and reports the applied count. Scope: derived-status deltas only — the op never writes an authored-status kind and never touches prose (those classes are flagged for review, not auto-repaired); a converged substrate is a clean no-op both ways, and a live run on a pre-identity substrate establishes identity at entry.
19
+ - New `derived-status` invariant class (config-declared, additive `oneOf` branch — no schema version advance needed): for a block kind declared in `state_derivation.rollups`, `context-validate` compares each item's STORED status against its DERIVED membership-rollup status and reports divergence in BOTH directions (stored behind or ahead of the derivation), with `{stored}`/`{derived}` message tokens. The comparison uses the same shared completeness helper the state derivation's gate satisfaction uses, so the detector and the derivation cannot disagree. Defaults to warning severity (divergence is expected steady state until write-time convergence and the reconcile repair path exist). A declaration naming a non-rollup block is inert; old engines skip the unknown class. The packaged catalog registers `milestone-status-converges` over the milestone kind.
20
+ - Gate satisfaction in the state derivation consults a target kind's truth model: a kind declared in `state_derivation.rollups` (e.g. milestone) completes by its DERIVED membership rollup — recursively for nested rollup kinds, with a cycle guard deriving not-complete — instead of its stored status field, and the milestones facet reports the SAME verdict the gates consult, so a single `context-current-state` read can no longer simultaneously report a milestone reached and hold tasks blocked on it. Non-rollup kinds keep the shared status-bucket completeness unchanged, and a substrate without `state_derivation` is unaffected.
21
+
22
+ ## [0.32.0] - 2026-07-05
23
+
24
+ - Ceremony-entry identity establishment: the substrate-lifecycle ceremonies that reach identity-stamping writes — `update` (live runs), `install`, and `resolve-blocked` — establish substrate identity at entry when `config.json` carries no `substrate_id`: one is minted (the same mint init uses), persisted through the sanctioned config write, and registered in the project registry before the ceremony's first stamping write, and the ceremony result reports it under `substrateIdEstablished`. A pre-identity substrate thereby heals on the sanctioned ceremony instead of refusing its populated-block version bump (the former mislabeled refusal), dry and live update runs agree on the outcome, and the two previously-skipped migrate-path tests are re-greened. An established identity is never re-minted (the on-disk id stays immutable), `--dryRun` establishes nothing (a preview performs no stamping write), and the block writer's own identity guard stays load-bearing for any write reaching it without identity.
25
+ - The rendered blocked report's trailing fix-items-then-resolve-blocked guidance renders only when at least one blocked entry actually persists a pending record (`validation-failed` / `no-migration-chain`); a report whose entries are all `write-failed` ends with the per-entry precondition guidance instead of a contradictory instruction to correct items that were never flagged invalid.
26
+ - Blocked-resync refusals are classified by cause: only an AJV validation failure reports reason `validation-failed`; any other throw at the resync write boundary (e.g. a substrate with no established `substrate_id` hitting the mandatory identity stamp, at either the same-version or version-bump arm) reports the new reason `write-failed` with the thrown message carried in the failures entry. A `write-failed` refusal inscribes no failure markers into the block file and persists no pending-blocked record — those consequences now fire only for genuine item-validation failures — and the rendered blocked report tells the operator the items were not flagged invalid instead of directing item fixes. `resolve-blocked`'s commit is now all-or-nothing: a throw partway through the commit restores every touched file byte-exact (migrations.json, the installed schema, the block file, config.json, the pending record) and reports the failure, where previously it could strand a partially-committed state (schema advanced, markers stripped, block unwritten, pending entry stale).
27
+ - `update`'s result makes per-component partial application legible in one place: an optional `partialApplication` field is populated exactly when the run both refused something (`blocked`, `refused`, or `conflicts` non-empty) and applied something (`resynced`, `migrated`, `merged`, `migrationsRegistered`, or any `registryAdditions` array non-empty) — carrying `applied`/`notApplied` mirrors of those channels plus a one-line summary naming what was applied alongside what was refused and why — so a run that blocks a schema while the additive registry propagation (or another schema's resync) lands no longer reads as a no-op. Computed for live and `--dryRun` runs (the preview reports the predicted partiality and declares itself a preview); a fully-clean or fully-refused run carries no field.
28
+ - The foreign-substrate config read feeding the relation porcelain's id index prefers the migration-aware loader over its prior raw parse, so a lagging-but-chained foreign config is read in its migrated shape — no reader of `config.json` sees a different shape than `loadConfig` where a chain resolves. Best-effort in two tiers: when the migration-aware load fails (unresolvable version, invalid), the raw parse is the fallback so the prefix invariant stays fed (a mis-filed foreign id keeps degrading to dangling rather than resolving); absent or unparsable still returns null.
29
+ - The composed `context-validate` verdict now covers block schema validity: a substrate-wide sweep validates every block that has both an installed schema and a block file against that schema — migration-aware when the envelope carries `schema_version` (a lagging version walks the registered chain; an unresolvable one surfaces), raw otherwise — and every failure lands as an ERROR naming the block, the failing item id, and the field/keyword (`block_schema_invalid`). Invalidity introduced without a write to the block (a schema resync, a hand edit) is no longer invisible behind a clean verdict. Pointer-less projects skip the sweep gracefully.
30
+ - `update`'s same-version resync arm re-validates populated blocks against the incoming catalog body BEFORE overwriting, and refuses on failure — the schema is reported `blocked` with per-item failures (reason `validation-failed`), the pending-blocked record and in-file failure markers follow the same flow as a version-bump refusal, and `--dryRun` predicts the same outcome. A same-version catalog change that narrows validity (a dropped property, an added required, a narrowed enum) can no longer silently invalidate existing items; compatible same-version changes still resync verbatim.
31
+ - The catalog story schema declares an optional `user_kind` on story items (the "As a `<user_kind>`" subject of the story statement), matching the field live stories carry.
32
+ - The bundled config schema is gated expand-contract at build time: `scripts/check-config-schema.ts` (pre-commit + CI, staged and `--base` modes diffing against the prior git revision) fails a non-additive `config.schema.json` change — a removed or renamed property key anywhere in the properties tree, or a new `required` entry on a pre-existing object — unless the same change set advances the schema `version` AND declares a packaged `config` migration reaching that version in `samples/migrations.json`. Additive changes (new optional fields, description/enum additions) pass untouched; a newly-added optional object's own initial requireds are additive by construction. New config fields land optional; removals/renames wait for a contract release paired with a migration.
33
+ - Envelope `schema_version` is live end-to-end: every block schema in the packaged catalog (`samples/schemas/`, 17 files; session-notes already declared it) admits an optional top-level `schema_version`, and `writeTypedFile` stamps every versioned-document envelope to the owning schema's current `version` on write — self-gated on the schema both declaring the property and carrying a `version`, so block writes, whole-block writes, `config.json` (converges to the bundled config schema version on its next sanctioned write, ending the permanently-persisted stale config version), and `migrations.json` all converge, while substrates whose installed schemas predate the property write unchanged until `/context update` lands it. With envelopes stamped, the previously-dormant read-time migration hook and pre-write version gate are active: an envelope claiming an older version is walked forward through the registered migration chain (read and write), and a version with no resolvable chain fails loud — the read throws and a write is refused with the block file left byte-unchanged.
34
+ - The packaged catalog (`samples/conception.json`) declares `role_direction` on the 17 relation_types that have a per-role consumer, so fresh `accept-all`/`install` substrates carry the orientation source of truth the deriver / rollup / roadmap / promote / write / read surfaces read. `as_parent` (primary at `edge.parent`): `task_depends_on_task`, `feature_depends_on_item`, `story_depends_on_story`, `requirement_depends_on_requirement`, `milestone_precedes_milestone`, `decision_supersedes_decision`, `research_supersedes_research`, `feature_contains_story`, `story_includes_item`. `as_child` (primary at `edge.child`): `task_gated_by_item`, `feature_gated_by_item`, `story_gated_by_item`, `decision_gated_by_item`, `phase_positioned_in_milestone`, `task_positioned_in_phase`, `item_derived_from_item`, `decision_derived_from_item`. The values are reverse-engineered from the convention already stored/consumed, so derived output is unchanged and the latent gate/rollup siblings are pre-empted; the other 27 relations (no role consumer) omit the field.
35
+ - The closure-table walk wrappers `walkLensDescendants` (`context-walk-descendants`) and `walkAncestorsByLens` (`walk-ancestors`) now SIGNAL a wrong-orientation query instead of silently returning `[]`. For a DISJOINT-kind relation (its `source_kinds` and `target_kinds` share no kind and neither is the `"*"` wildcard), a descendants walk is only meaningful from a SOURCE-kind id and an ancestors walk only from a TARGET-kind id; when the queried id resolves to a block that sits exclusively on the wrong end for the requested direction, the walk THROWS naming the correct op (a wrong-end `context-walk-descendants` points to `walk-ancestors`, and vice-versa). Same-kind / wildcard-endpoint relations, an unregistered relation, and an id that resolves to no block stay structurally un-disambiguatable and return `[]` as before; `find-references both` is symmetric and carries no signal.
36
+ - The relation-append porcelain (`append-relation` / `append-relations` ops + the `appendRelationByRef` / `appendRelationsByRef` SDK fns) accepts a ROLE-TYPED authoring form alongside the raw `{parent, child}` form: `--primary`/`--counter` (or `{primary, counter}` in an `append-relations` edge object) name the relation's semantic-role endpoints and are mapped to `parent`/`child` via the relation's declared `role_direction`. The two orientation pairs are mutually exclusive. For a relation that is BOTH role-bearing and orientation-ambiguous (its `source_kinds` and `target_kinds` overlap, including the `"*"` wildcard — e.g. a same-kind `task↔task` ordering relation), a bare `--parent`/`--child` append is now REJECTED with a message directing the author to `--primary`/`--counter`; the porcelain never guesses or auto-swaps. A role-less relation, or a role-bearing relation whose endpoint kinds are disjoint (self-orienting via the existing source/target-kind gate), is unaffected — its bare append still succeeds. Supplying `--primary`/`--counter` for a relation that declares no `role_direction` throws (there is no role to map).
37
+ - `promoteItem` orients the `item_derived_from_item` lineage edge it files into the destination substrate from that relation's declared `role_direction`: the SOURCE (the item derived from) is placed at the PRIMARY endpoint and the new-derived item at the COUNTER endpoint. `item_derived_from_item` is `as_child` (source at `edge.child`), reproducing the prior parent=new-derived / child=source layout; the `as_child` fallback preserves that layout when the destination config registers no `role_direction`. A destination declaring the relation `as_parent` mirrors the edge (parent=source, child=new-derived).
38
+ - The derived roadmap (`context-roadmap-load` / `context-roadmap-render` / `context-roadmap-validate`) reads the orientation of its three domain relations from their declared `role_direction` via the `primaryEndpoint`/`counterEndpoint` helpers rather than hardcoded parent/child picks: the precedes DAG treats the predecessor as the PRIMARY endpoint of `milestone_precedes_milestone` (fallback `as_parent`), and the phase/task membership tiers treat the container as the PRIMARY endpoint of `phase_positioned_in_milestone` / `task_positioned_in_phase` (fallback `as_child`). The former `MILESTONE_PRECEDES` / `PHASE_IN_MILESTONE` / `TASK_IN_PHASE` module constants are removed. With the stock (or absent) role_direction the derived order, membership, and validation output are unchanged; declaring a non-default `role_direction` reorients the roadmap accordingly.
39
+ - `currentState`'s config-declared membership rollups (`state_derivation.rollups`, e.g. the milestone rollup) read their container/member orientation from the membership relation's declared `role_direction` via the `primaryEndpoint`/`counterEndpoint` helpers: the CONTAINER (the rollup item) is the PRIMARY endpoint, the MEMBERS are the COUNTER endpoint. `phase_positioned_in_milestone` is `as_child` (container=milestone at `edge.child`, member=phase at `edge.parent`), reproducing the prior filter-child / map-parent selection exactly; a membership relation the config does not register with a `role_direction` defaults to `as_child` (the prior container=child convention). A `contains`-shaped (`as_parent`) membership relation now rolls up correctly (member read at the child endpoint) instead of finding zero members.
40
+ - `currentState` (the derivation behind `context-current-state` / `/context status`) partitions its `state_derivation.blocked_by` relations into gate-direction vs dependency-direction from each relation's declared `role_direction` rather than the former single `task_gated_by_item` string literal: a blocked_by relation declared `as_child` reads as a GATE (the waiting item at `edge.parent`, its gate target at `edge.child`), any other (`as_parent` or a relation the config does not register with a `role_direction`) reads as a DEPENDENCY (the item's prerequisites are the parents of edges whose child is the item). For the stock `blocked_by` set `{task_depends_on_task (as_parent), task_gated_by_item (as_child)}` the classification and the derived `blocked` / `nextActions` / `blockedBy` output are unchanged; the difference is that a same-shape gate sibling (`feature_/story_/decision_gated_by_item`) added to `blocked_by` now reads the correct gate direction by construction instead of the swapped dependency direction the literal-keyed deriver produced.
41
+ - Relation orientation — which endpoint holds a relation's PRIMARY semantic role (prerequisite/predecessor/gate for `ordering`, container for `membership`, source for `data_flow`) — is now declared once as config metadata rather than hardcoded per consumer. `config.relation_types[].role_direction` (`as_parent` | `as_child`, optional, reusing the existing invariant-direction vocabulary) names where the primary role sits: `as_parent`=`edge.parent`, `as_child`=`edge.child`. Two pure helpers `primaryEndpoint(edge, role_direction)` / `counterEndpoint(edge, role_direction)` (exported from `@davidorex/pi-context` and `@davidorex/pi-context/context-sdk`) read the endpoint under that declaration. The field is presence-gated — populated only for relations with a per-role consumer (deriver / rollup / roadmap / promote / write-orientation / read-signal); role-less relations omit it. The config schema advances to version 1.8.0 (the addition is optional; the packaged `samples/migrations.json` config chain carries a `1.0.0→1.8.0` identity migration, so a catalog-born config migrates cleanly and a config already declaring the field validates unchanged).
42
+ - The roadmap is a DERIVED view over the `milestone_precedes_milestone` relation, which the packaged catalog (`samples/conception.json`) now registers (category `ordering`, source/target `milestone`, modeled on `decision_supersedes_decision`): `context-roadmap-load` / `context-roadmap-render` / `context-roadmap-validate` take no parameters and derive the roadmap entirely from substrate state — milestone-block items topo-ordered by the authored precedes edges (order + cycles), each milestone carrying its derived status/phaseCount (currentState's config-declared milestone rollup), member phases via `phase_positioned_in_milestone`, per-phase tasks via `task_positioned_in_phase`, and per-phase + per-milestone status rollups. Adjacency in the loaded view and the rendered **Preceded by:** lines comes strictly from the authored edges, never inferred from order consecutive pairs. The filed design specified a precedes-CHAIN; the implementation generalizes chain → DAG (the approved delta): multiple starts and joins topo-order correctly, a linear chain being the degenerate case, and zero milestones is a valid empty view. The roadmap BLOCK is retired with the derivation: no `roadmap.json`, no ROADMAP- ids, no roadmap block kind — the `context-roadmap-list` op, the `/context roadmap-list` subcommand, the `loadRoadmap(cwd, roadmapId)` / `listRoadmaps` / `validateRoadmaps` / `PhaseSpec` / `RoadmapSpec` / `PhaseView` / `RoadmapView` exports, and the legacy `registry/schemas/roadmap.schema.json` fixture are removed (`/context roadmap-view` and `/context roadmap-validate` no longer take an id; the new exports are `loadRoadmap(cwd)`, `validateRoadmap`, `MilestoneRoadmapView`, `MilestoneView`, `PhaseRollupView`, `TaskRow`). Validation codes are rewired to the derived model: errors `roadmap_precedes_endpoint_missing` (a precedes-edge endpoint that is not a milestone-block item), `roadmap_milestone_cycle`, `roadmap_milestone_missing` (a `phase_positioned_in_milestone` edge whose child is not a known milestone); warning `roadmap_status_unknown_value`; and a new INFO tier — `roadmap_milestone_isolated` (a milestone with zero precedes edges while others are ordered) — that never affects the validation status (invalid iff any error, warnings iff any warning, else clean) and is excluded from the `context-validate` lens-validator merge, which contributes error-code issues only, block-framed `milestone`.
43
+ - The SKILL's `/context init` and `/context accept-all` descriptions state the ceremony's actual writes: init bootstraps the pointer + dirs, a vocabulary-empty SKELETON `config.json` (minted + registered `substrate_id`), and the seeded catalog `config` migration declarations; accept-all never overwrites a POPULATED config but DOES overwrite the init skeleton (preserving its on-disk `substrate_id`), and `config.json`'s `root` is written first at init and again at accept-all.
44
+ - `resyncSchema`'s internal collision-key separator is spelled as the `\u0000` escape sequence instead of a literal NUL byte — the produced runtime string is identical; `src/index.ts` (and the built `dist/index.js`) are plain text again for byte-sensitive tools.
45
+ - New `map_each` declarative-transform primitive (TransformOp, alongside rename/set/delete/coerce): addresses an ARRAY at a dotted `$`-path (absent path / non-array value no-op) and maps its elements in one of two modes — table mode replaces each string element through a lookup table, with an unmatched string becoming `{relation_type: <element>, item_endpoint: <fallback>}` under a `parent`/`child` fallback (default `parent`) and non-string elements passing through; set-on-each mode assigns a declared `field`=`value` on every object element (non-object elements skipped). The schema variant enforces table XOR field+value. Registered in `migrations.schema.json`, the `TransformOp` TS union, and the loader's op applicator; surfaced in the `write-schema-migration` op description.
46
+ - Config loading (`loadConfig` / `loadConfigForDir`) is migration-aware: when `config.json`'s `schema_version` differs from the bundled config schema's `version`, the substrate's registered `config` migration chain walks the data forward in memory before validation (the on-disk file is never rewritten); a mismatch with no resolvable chain throws (fail-fast — no raw-validate fallback). On version match the migration registry is never consulted.
47
+ - The packaged catalog (`samples/migrations.json`) ships a `config 1.0.0→1.7.0` identity migration declaration, and EVERY sanctioned ceremony entry point — `/context init` (`writeSkeletonConfig`), `/context accept-all` (`adoptConception`), `/context install` (`installContext`), `/context update` (`updateContext`), `/context check-status` (`checkStatus`), the `/context switch` existing-target and switch-back forms (`switchToExisting` / `switchToPrevious`, seeding the TARGET substrate right after the pointer flip), `/context resolve-conflict` (`resolveConflict`), and `/context resolve-blocked` (`resolveBlocked`) — seeds the catalog's `config` declarations into the substrate's `migrations.json` via the exported `seedCatalogConfigMigrationDecls(substrateDir, ctx?)` (idempotent: a present `(schemaName, fromVersion)` pair is never replaced; returns the appended edges) BEFORE its first config read, so catalog-born substrates and re-entered legacy substrates carry a resolvable config chain before any config read. The initial change seeded only init / accept-all / install; an adversarially-verified finding showed a lagging legacy substrate (1.0.0 config, no `migrations.json`) still threw on `update` / `check-status` / a pointer flip onto it — the class rule now applied is that every ceremony entry point seeds. `check-status` and a `--dryRun` update thereby perform this one idempotent seed write (the designed heal semantic, consistent with idempotent re-init healing) while remaining otherwise read-only. The seed helper is additionally a no-op on a NONEXISTENT substrate dir (guarded at its first statement, one guard covering every present and future call site): the seed heals substrates, it never materializes them — a bootstrap pointer naming a dir that was never created degrades with zero writes (no dir creation, no `migrations.json` residue) rather than the seed mkdir-ing the dir into existence; ceremonies that need the dir create it themselves before seeding — concretely, the WRITE-flavored ceremonies whose job is materializing config (`adoptConception` for accept-all, `writeSkeletonConfig` for init / switch -c) mkdir the substrate dir immediately before their seed call, so a first-touch accept-all on a pointer whose dir was never created still lands the seeded config chain before the config write, while the read-flavored ceremonies (check-status / update / switch-back onto a degenerate pointer) rely on the helper's no-op guard and write nothing. An EXISTING dir without a `config.json` remains seeded by design (mid-ceremony states such as init→accept-all need the seed before, and independent of, config presence).
48
+ - The `context-check-status` and `context-update` reflected op `description` strings state the seed-at-entry behavior: each names the one idempotent catalog-config-migration seed write performed before the first config read, with the drift report / `--dryRun` preview otherwise unchanged in their read-only framing.
49
+ - `seedCatalogConfigMigrationDecls` no-ops (returns `[]`, zero writes) when the substrate dir does not exist — the seed heals substrates, it never materializes them, so a read-flavored ceremony (`check-status`, `update`, a switch-back) invoked against a bootstrap pointer naming a nonexistent dir degrades exactly as before seeding existed (no dir creation, no `migrations.json` residue). The write-flavored ceremonies that legitimately materialize config (`accept-all`'s `adoptConception`, `init`'s `writeSkeletonConfig`) mkdir their substrate dir immediately before seeding, so a first-touch accept-all still lands the config chain before the config write.
50
+ - Every `migrations.json` write now invalidates the migration-registry cache at the write funnel (`writeMigrationsFileForDir`) rather than per mutation helper, so any write path through the store — including the new ceremony seeding — is cache-coherent in-process (fixes a staleness window where a registry warmed empty before a raw whole-file write kept serving the pre-write declarations).
51
+ - The packaged catalog (`samples/conception.json`) now registers the config vocabulary that shipped derivations already referenced but the catalog had not defined, so fresh `accept-all`/`install` substrates carry it and are internally consistent: relation_types `task_gated_by_item` (the blocking relation `state_derivation.blocked_by` already names), `task_advances_story` / `feature_advances_story` (the relations the `story-advancers` / `story-advancers-features` lenses project), `decision_derived_from_item` / `decision_escalates_underdetermined` (the relations the `decision-shows-derivation` invariant requires), and `session_touches_item`; the lenses `gaps-by-priority`, `features-by-status`, `story-advancers`, `story-advancers-features`; the invariant `decision-shows-derivation`; and the `session-notes` block kind (prefix `SESSION-`, array_key `sessions`) with its schema (`samples/schemas/session-notes.schema.json`), an empty starter block (`samples/blocks/session-notes.json`), and `session-notes` added to `installed_schemas` / `installed_blocks` so `install` materializes `session-notes.json`. A fresh catalog-built substrate now validates with no unregistered-relation reference and accepts `task_gated_by_item` / `task_advances_story` / `session_touches_item` edges.
52
+ - The packaged catalog (`samples/conception.json`) `state_derivation.next_ranked` push order is `tasks`, then `issues`, then `framework-gaps` — so `nextActions` (`context-current-state` / `/context status`) surfaces ready unblocked tasks ahead of open issues and open framework-gaps in the derived next-actions head (the deriver walks `next_ranked` in array order, then truncates to `head_size`). Each entry's content (kind, label, bucket, rank_field, rank_order, reason_template) is unchanged from before; only the entries' order in the array differs.
53
+ - The packaged catalog (`samples/conception.json`) now treats issues as a gap-sibling open-work kind: it ships relation_types `task_addresses_issue` (a task addressing an issue) and `issue_relates_to_issue` (an issue related to another issue); a `task-completed-issue-resolved` status-consistency invariant (warning) flagging a completed task whose `task_addresses_issue` target is not resolved; a `state_derivation.next_ranked` entry for `issues` (open issues ranked by `priority` critical→high→medium→low, surfaced in `nextActions` of `context-current-state` / `/context status` after tasks and before framework-gaps); and `issues-by-status` (open/resolved/deferred) + `issues-by-priority` (critical/high/medium/low) lenses. The issues schema (`samples/schemas/issues.schema.json`, version unchanged) additively gains an optional `resolved_at` (ISO-8601 resolution timestamp) field and an `x-lifecycle` block declaring the `status` states (open/resolved/deferred) and authority-gated transitions (open→resolved any, open→deferred user).
54
+ - Each `next_ranked` entry in the `state_derivation` registry now carries an optional `reason_template` (string) supplying the `reason` string `currentState` (`context-current-state` / `/context status`) emits for the items that entry surfaces in `nextActions`. The template substitutes `{rank_value}` (the item's `rank_field` value, or `unset` when absent) and `{id}` (the item id) literally where they appear. The packaged catalog ships the stock templates — `open gap (priority {rank_value})` on the priority-ranked `framework-gaps` entry and `unblocked planned task` on the topo `tasks` entry — so a custom `state_derivation` declaring non-`framework-gaps`/`tasks` kinds emits its own configured reason strings, and the `focus` fallback prefix is drawn from `focus_fallback.kind` (stock `phase`, yielding `phase: <id>`). The config schema is at version 1.7.0.
55
+ - A substrate whose config declares NO `state_derivation` makes `currentState` (`context-current-state` / `/context status`) report `focus: "state-derivation not configured"` with empty `inFlight` / `nextActions` / `blocked` / `milestones` — a signal distinct from a configured-but-empty substrate (which derives `focus: "no active focus."` with empty arrays). The derivation's in-flight kinds/bucket, focus fallback, next-actions ranking + order, blocking relation set, milestone rollup, and head-size cap are all read from the declared registry.
56
+ - `amend-config --registry state_derivation` addresses the `state_derivation` singleton per-key (a map-kind registry: its six top-level keys are the map entries), and `update` brings the catalog's whole `state_derivation` object into a substrate that lacks one while leaving an existing one untouched (merged whole, never body-merged).
57
+ - The packaged catalog (`samples/conception.json`) ships the stock `state_derivation` registry — `in_flight` over `tasks` at `in_progress`, `focus_fallback` on `phase` at `in_progress`, a `next_ranked` of `tasks` (topo) then priority-ranked `issues` then priority-ranked `framework-gaps` (P0..P3), `blocked_by` the `task_depends_on_task` + `task_gated_by_item` relations, a `milestone` rollup over `phase_positioned_in_milestone` (reached/planned), and `head_size` 15 — so fresh `accept-all`/`install` substrates carry the derivation declaration.
58
+ - `currentState` (the derivation behind `context-current-state` / `/context status`) derives its focus, in-flight set, next-actions ranking, blocked set, and milestone rollup from a new config-declared `state_derivation` registry rather than from values baked into the deriver. The registry is a singleton config object with six keys: `in_flight` (block kinds + status bucket counted as in-flight), `focus_fallback` (kind + bucket for the focus fallback when nothing is in-flight), `next_ranked` (the ordered cross-kind push order for next-actions; each entry selects a kind at a bucket and either ranks within itself via a named field + ordered value list or topo-orders over the blocking-relation graph), `blocked_by` (the relation_types whose edges contribute blockers), `rollups` (membership rollups such as milestones, with their complete/incomplete status strings), and `head_size` (the next-actions truncation cap). The packaged catalog (`samples/conception.json`) ships the stock registry — tasks/phase/issues/framework-gaps/milestone kinds, the `task_depends_on_task` + `task_gated_by_item` blocking relations, the `next_ranked` push order of `tasks` (topo) then priority-ranked `issues` then priority-ranked `framework-gaps` (P0..P3), and head size 15 — so fresh `accept-all`/`install` substrates carry it and the derived output is unchanged. A substrate whose config has no `state_derivation` reports `focus: "state-derivation not configured"` with empty arrays, distinguishing an un-configured substrate from a configured-but-empty one. `state_derivation` is addressable per-key through `amend-config --registry state_derivation` (a map-kind registry); `update` brings the whole object into a substrate that lacks it while leaving an existing one untouched. The config schema is at version 1.7.0.
59
+ - The packaged catalog ships an empty `milestone` starter block (`samples/blocks/milestone.json`, `{ "milestones": [] }`, matching the block kind's `data_path` `milestone.json`), so `install` / `context-install` materializes a `milestone.json` block in the substrate alongside the milestone schema.
60
+ - The packaged catalog (`samples/conception.json`) now ships a `milestone` block kind (prefix `MILE-`, array_key `milestones`, schema `samples/schemas/milestone.schema.json`) and its schema, so fresh `accept-all`/`install` substrates carry it. A milestone is a phase-rollup checkpoint with fields `id` (`MILE-NNN`), required `name`, required `status` (`planned` | `reached`), and an optional `release` grouping string. `status` is DERIVED, not authored: `currentState` (the derivation behind `context-current-state` / `/context status`) reports a milestone as `reached` when at least one phase is positioned in it via a `phase_positioned_in_milestone` edge (phase is the parent, milestone the child) and the parent phase of every such edge buckets to complete, and `planned` otherwise (covering no-phases and any-incomplete). The catalog also adds two membership relation_types — `phase_positioned_in_milestone` (phase → milestone, driving the rollup) and `story_includes_item` (story → any kind, the single relation expressing a story's scope) — and replaces the former `story_contains_task` with `story_includes_item`. A `status-consistency` invariant `reached-milestone-phases-complete` (severity error) backstops the derived state: a milestone whose own status buckets to complete must have the parent phase of every `phase_positioned_in_milestone` edge complete, surfaced by `context-validate`. `reached` maps to the complete status bucket in the default status vocabulary.
61
+ - `currentState` (the derivation behind `context-current-state` / `/context status`) now folds `task_gated_by_item` gates into task-readiness alongside the existing `task_depends_on_task` dependencies. A planned task carrying a `task_gated_by_item` edge to a target that has not reached the complete bucket is reported in `blocked` (the gate target id present in `blockedBy`, unioned with any unsatisfied dependency parents) and excluded from `nextActions`; a gate target of any kind reaching its complete status (gap→closed, decision→enacted, feature→complete, task→completed) releases the gate. Gate satisfaction reuses the same `bucket(target) === "complete"` check via the config-resolved status vocabulary that the status-consistency invariant engine uses — kind-general, no per-kind special-casing and no parallel completeness notion. A dangling gate target (id resolving to no item) is treated as satisfied/non-blocking, mirroring the dangling-dependency guard. Scope is the literal relation_type `task_gated_by_item`: `decision_gated_by_item` and other non-task `*_gated_by_item` edges do not alter `currentState`. A gate target in a terminal-abandoned status (`wontfix` / `superseded` / `cancelled`, which bucket to `unknown` rather than `complete`) keeps the gated task blocked; promoting such states to gate-releasing and generalizing the gate-aware derivation to all gate relation kinds is the config-driven refinement boundary, deferred. With no `task_gated_by_item` edges present the derivation output is unchanged.
62
+ - The packaged catalog (`samples/conception.json`) now ships three relation_types: `decision_raises_gap` (a decision raising a framework-gap), `decision_gated_by_item` (a decision enactment-gated by an item), and `gap_relates_to_gap` (a framework-gap related to another framework-gap), so fresh `accept-all`/`install` substrates carry them.
63
+ - The friendly-selector edge-write porcelain (`appendRelationByRef` / `appendRelationsByRef`) now validates each resolved edge against the relation_type registry at write time: an edge whose `relation_type` is not registered in `config.relation_types`, or whose resolved source/target endpoint block is not in that relation_type's declared `source_kinds` / `target_kinds`, throws and is never persisted (a batch is all-or-nothing — a single invalid edge rejects the whole `appendRelationsByRef` call before any write; `dryRun` rejects identically). A relation_type declaring neither `source_kinds` nor `target_kinds` is unchecked for endpoint kinds (presence-gated). This is the same registration + endpoint-kind check `context-validate` performs post-hoc, now factored into a shared `validateEdgeAgainstRegistry` helper invoked at both surfaces so write-time and validate-time verdicts are identical.
64
+
65
+ ### Documentation
66
+ - Edge orientation is documented across the surfaces the metadata change touches: the `append-relation` / `append-relations` op `description` + `promptSnippet` state the raw-vs-role-typed authoring forms and the ambiguous-bare-append reject; `context-walk-descendants` / `walk-ancestors` state the disjoint-kind wrong-orientation throw (naming the counterpart op); `replace-relation` states that it writes raw endpoints verbatim, bypassing the orientation gate (the re-orient affordance, `context-validate` after). The package README's relations section gains an "Edge orientation" paragraph (the `role_direction` source of truth + `primaryEndpoint`/`counterEndpoint` + authoring/read behavior), and `skill-narrative.md` gains the matching orientation prose; the root README's tool enumeration carried no orientation claim to correct. Regenerate `skills/pi-context/SKILL.md` (`npm run skills`) to pick up the changed op strings.
67
+ - Regenerated `skills/pi-context/SKILL.md` from the edge-orientation `skill-narrative.md` + op-string edits: the tool entries now carry the role-typed `append-relation`/`append-relations` authoring + ambiguous-bare-append reject, the `context-walk-descendants`/`walk-ancestors` disjoint-kind wrong-orientation throw, and the `replace-relation` raw-endpoint gate-bypass note.
68
+ - The `next_ranked` doc strings — the `config.schema.json` `next_ranked` `description`, the `next_ranked` field JSDoc in `context.ts`, and the `CurrentState.nextActions` field doc + `nextActions` deriver inline comment in `context-sdk.ts` — state the stock cross-kind push order as tasks (topo-ordered) then issues (priority-ranked) then framework-gaps (priority-ranked), matching the packaged catalog's `state_derivation.next_ranked` array order.
69
+ - The `context-current-state` op `description` + `promptSnippet` state that focus, in-flight, ranked next-actions, blocked, and milestone rollups all derive from the config-declared `state_derivation` registry (in-flight kinds + bucket, focus fallback, the ordered next-actions push order with per-entry field-ranking or topo ordering, the blocking relation set, the membership rollups with their status strings, and the head-size cap), and that a substrate without the registry reports focus 'state-derivation not configured'.
70
+ - Regenerated `skills/pi-context/SKILL.md` for the `context-current-state` op's config-declared `state_derivation` derivation surface — the tool entry now states that focus, in-flight, ranked next-actions, blocked, and milestone rollups all derive from the declared `state_derivation` registry and that a substrate without it reports focus 'state-derivation not configured'.
71
+ - Regenerated `skills/pi-context/SKILL.md` for the `context-current-state` op's gate-aware readiness surface — the tool entry now states that task readiness honors both `task_depends_on_task` dependencies and `task_gated_by_item` gates and that a gate target reaching its complete status releases the gate.
72
+ - Regenerated `skills/pi-context/SKILL.md` + `references/bundled-resources.md` for the milestone block kind (now listed in the installable blocks/schemas inventory) and the corrected `context-roadmap-load`/`render`/`validate` op strings — a phase's milestone is a MILE- block id whose satisfaction reads the milestone's derived `reached` (a pure phase-rollup over the parent phases of its `phase_positioned_in_milestone` edges; phase is the parent, milestone the child), with the validate codes collapsed to `roadmap_milestone_missing`.
73
+
74
+ ### Fixed
75
+ - `context-validate-relations` no longer reports `edge_parent_not_in_bins` for a content edge whose structured item parent rides a relation_type that also serves as an edge-materialization lens axis (a lens with `derived_from_field: null`, `bins: []`, e.g. `story-advancers` / `story-advancers-features`). `validateRelations` had applied the lens parent-in-bins contract to every edge matching a lens's relation_type, including the real content edges (task/feature → story), so structurally-correct advancer edges falsely invalidated the substrate. The bins check now applies only when the parent is a `lens_bin` endpoint — a genuine `lens_bin` parent not among the lens bins still errors; an item or legacy-string parent is validated on endpoint kind / existence only.
76
+ - `context-validate` again groups its edge-registry diagnostics by class — every relation_type-registration issue across all edges before every source/target-kind issue across all edges — matching the order surfaced before the `validateEdgeAgainstRegistry` refactor. That refactor's per-edge loop had interleaved the two classes (one edge's registration and kind issues, then the next edge's), changing the printed `issues[]` order; the merged loop now collects then partitions by class so the emission order is class-grouped again. Order-only — the set, count, wording, and severity of the issues are unchanged.
77
+ - Corrected the `phase_positioned_in_milestone` edge direction throughout the milestone phase-rollup: the phase is the edge PARENT and the milestone the CHILD (matching the relation_type registration `source_kinds: phase` / `target_kinds: milestone`, the closure parent=source/child=target convention, and the invariant's `direction: as_child` meaning the milestone is the child). The `currentState` `reached` deriver had selected edges where the milestone was the parent and read the child as the member phase; it now selects edges where the milestone is the child and reads the parent as the member phase, so a milestone derives `reached` only when at least one phase is positioned in it and the parent phase of every such edge buckets to complete. The schema, invariant message, op `description`, and roadmap fixtures that described the phase as the "child" are corrected to the parent-phase framing.
78
+ - Corrected the milestone block kind's `data_path` to `milestone.json` (matching the `data_path === canonical_id + ".json"` convention; `canonical_id` is `milestone`) and renamed the catalog starter block to `samples/blocks/milestone.json` accordingly. It had been authored as `milestones.json`, diverging from the convention.
79
+
7
80
  ## [0.31.0] - 2026-06-13
8
81
 
9
82
  ### Changed
package/README.md CHANGED
@@ -15,18 +15,18 @@ pi install npm:@davidorex/pi-context
15
15
  ```
16
16
  /context init <substrate-dir> # create the empty substrate skeleton
17
17
  /context install # reconcile <substrate-dir>/ against installed_* lists in config.json
18
- /context check-status # read-only: report which installed schemas are behind the catalog + the version gap (writes nothing)
18
+ /context check-status # read-only: report which installed schemas are behind the catalog + the version gap (writes nothing beyond the idempotent config-migration seed)
19
19
  /context update [--dryRun] # bring the installed schema model current with the catalog, preserving local edits (3-way merge); --dryRun previews
20
20
  /context resolve-conflict --schemaName <name> [--schema <reconciled>] # commit a reconciled merge conflict: write the resolved body + advance the merge base to the catalog
21
21
  ```
22
22
 
23
23
  `init` (and `switch -c`) is intentionally minimal: it writes the bootstrap pointer, the substrate/schemas dirs, and a minimal schema-valid **skeleton config** (`schema_version` + empty `block_kinds` + `root` + a minted, registered `substrate_id`) — no schemas, no starter blocks (ship-no-defaults). The skeleton is never-clobbered: an idempotent re-init leaves an existing config untouched. From the skeleton there are two onward paths: adopt the packaged conception with `/context accept-all` (overwrites a skeleton config, never a populated one; writes `config.json` from `samples/conception.json` and preserves the skeleton's `substrate_id`), then `/context install`; or build a custom vocabulary directly via `amend-config` / `write-schema` / `append-block-item` (no catalog adoption). The opt-in install ceremony copies the `installed_schemas` / `installed_blocks` declared in `config.json` from the package samples catalog (`samples/blocks/` and `samples/schemas/`); it is idempotent. Populated block data is never overwritten (reported as `preserved`), while empty or absent blocks get the catalog starter. Install records an **install baseline** (`config.installed_from`) — the catalog source + a per-schema content fingerprint of the installed schemas — for installed-vs-catalog drift detection; the baseline covers schemas only. The adopted conception also carries advisory (severity-`warning`) convention-articulation invariants: every decision, feature, and task should carry an `item_governed_by_convention` edge to a convention it follows, or an `item_acknowledges_missing_convention` edge to a missing-convention gap — `context-validate` reports an artifact articulating neither as a warning (not an error), so the advice surfaces without blocking writes.
24
24
 
25
- `/context update` is the drift-aware, customization-preserving path for bringing the installed schema model current with the catalog (it supersedes the former `/context install --update`). Per installed schema it consults the drift classification: an `in-sync` schema is a no-op; a `catalog-ahead` schema re-syncs through the migration-aware path; a `locally-modified` / `both-diverged` schema is reconciled by a deterministic 3-way merge of base (the as-installed schema body in the object store, keyed by the recorded baseline `content_hash`) × ours (the installed schema) × theirs (the catalog schema) — disjoint edits auto-merge so both the user's and the catalog's changes survive (`required` / `enum` / array-valued `type` nodes merge as sets), and a schema with irreconcilable per-path conflicts is left unmodified — the conflict set is returned in the op output (under `conflicts`) alongside a readable report, and the calling agent reconciles it then commits via `/context resolve-conflict` (no subordinate resolver is spawned). `update` also additively propagates catalog-new config-registry entries (`relation_types` / `invariants` / `block_kinds` / `lenses`) absent from the config, preserving every user-authored entry and any locally-diverged body of an existing entry (additive-only; the added ids are reported under `registryAdditions`). A version-bump `catalog-ahead` resync registers the shipped catalog migration chain's declarations into `migrations.json`, reported under `migrationsRegistered` (each `{ schema, from, to }`). `--dryRun` predicts the precise per-schema outcome (resync / migrate / block / merge / conflict) by running the forward-migration and re-validation in memory, alongside the config-registry entries that would be added and the migration declarations that would be registered, writing nothing. Preview drift first with `/context check-status`, which reports which installed schemas are behind the catalog and by what version gap.
25
+ `/context update` is the drift-aware, customization-preserving path for bringing the installed schema model current with the catalog (it supersedes the former `/context install --update`). Per installed schema it consults the drift classification: an `in-sync` schema is a no-op; a `catalog-ahead` schema re-syncs through the migration-aware path; a `locally-modified` / `both-diverged` schema is reconciled by a deterministic 3-way merge of base (the as-installed schema body in the object store, keyed by the recorded baseline `content_hash`) × ours (the installed schema) × theirs (the catalog schema) — disjoint edits auto-merge so both the user's and the catalog's changes survive (`required` / `enum` / array-valued `type` nodes merge as sets), and a schema with irreconcilable per-path conflicts is left unmodified — the conflict set is returned in the op output (under `conflicts`) alongside a readable report, and the calling agent reconciles it then commits via `/context resolve-conflict` (no subordinate resolver is spawned). `update` also additively propagates catalog-new config-registry entries (`relation_types` / `invariants` / `block_kinds` / `lenses`) absent from the config, preserving every user-authored entry and any locally-diverged body of an existing entry (additive-only; the added ids are reported under `registryAdditions`). A version-bump `catalog-ahead` resync registers the shipped catalog migration chain's declarations into `migrations.json`, reported under `migrationsRegistered` (each `{ schema, from, to }`). `--dryRun` predicts the precise per-schema outcome (resync / migrate / block / merge / conflict) by running the forward-migration and re-validation in memory, alongside the config-registry entries that would be added and the migration declarations that would be registered, writing nothing beyond the idempotent config-migration ceremony seed. Because update applies per-component (a blocked schema rolls back only itself; the registry propagation writes regardless), a run that refuses any schema while applying registry additions or other-schema resyncs reports the partiality under `partialApplication` — `applied`/`notApplied` mirrors of the result channels plus a one-line summary naming what was applied alongside what was refused and why — so a blocked run never reads as a no-op (`--dryRun` reports the predicted partiality in the same shape). The ceremonies that reach identity-stamping writes (update, install, resolve-blocked) establish substrate identity at entry: a config with no `substrate_id` gets one minted, persisted, and registered before the first stamping write — a pre-identity substrate heals on the sanctioned ceremony instead of refusing — reported under `substrateIdEstablished` (live runs only; an established identity is never re-minted). Preview drift first with `/context check-status`, which reports which installed schemas are behind the catalog and by what version gap.
26
26
 
27
27
  ## How It Works
28
28
 
29
- Project data lives under the substrate root (the dir chosen at init and recorded in `config.json`'s `root` field by accept-all; no default is shipped) as typed JSON block files. Each block has a corresponding JSON Schema that defines its shape. All writes — whether from tools, workflows, or agents — are validated against the schema before data hits disk. Invalid data is never persisted.
29
+ Project data lives under the substrate root (the dir chosen at init and recorded in `config.json`'s `root` field by accept-all; no default is shipped) as typed JSON block files. Each block has a corresponding JSON Schema that defines its shape. All writes — whether from tools, workflows, or agents — are validated against the schema before data hits disk. Invalid data is never persisted. Mutating ops additionally run a write pipeline: rollup-kind stored statuses converge with their derivation after the write, and the config invariants are re-evaluated delta-scoped — a violation newly introduced by the write refuses it at error severity (substrate byte-restored) or is surfaced on the result at warning severity; pre-existing violations never block. The pipeline is also all-or-nothing at the op level: an op that throws mid-run (e.g. a birth edge failing after its item landed) byte-restores the substrate before rethrowing, so a composite write never persists partially. Because an error-severity invariant can forbid every intermediate resting state of a multi-write transition, the ops that own such transitions perform them as one gate-judged atom: `complete-task` files the verification edge and flips the task status in a single run, and `append-block-item` / `upsert-block-item` accept a `relations` array that files a new item's birth edges in the same run.
30
30
 
31
31
  After `/context init <substrate-dir>` the substrate skeleton is the dirs plus a minimal skeleton `config.json` (schema-valid, empty of vocabulary, carrying a minted/registered `substrate_id`) — no schemas, no blocks:
32
32
 
@@ -75,20 +75,22 @@ Each substrate's `config.json` carries a `substrate_id` (pattern `sub-` + 16 hex
75
75
 
76
76
  All inter-item relationships are closure-table edges in `<substrate-dir>/relations.json` — `{parent, child, relation_type, ordinal?}` rows. Endpoints are dual-form: a legacy string (a canonical id, a lens bin name, or an `<alias>:<refname>` cross-substrate sentinel), or a structured `{kind:"item", oid, refname?, substrate_id?, content_hash?}` (where `substrate_id` marks a foreign endpoint), or a structured `{kind:"lens_bin", bin}` virtual parent. Embedded nested id-bearing arrays and FK-as-field are forbidden (`validateContext` flags `nested_id_bearing_array`); containment is a membership edge carrying `ordinal`. `promote-item` is the cross-substrate derivation tool (an item promoted into another registered substrate as a new content-addressed item).
77
77
 
78
+ **Edge orientation.** Storage is uniform (`edge.parent` = source endpoint, `edge.child` = target endpoint); which endpoint holds a relation's PRIMARY semantic role (prerequisite/predecessor/gate for `ordering`, container for `membership`, source for `data_flow`) is declared ONCE as `config.relation_types[].role_direction` (`as_parent` = primary at `edge.parent`, `as_child` = primary at `edge.child`; optional — set only for relations with a per-role consumer). The blocked/ready deriver, the milestone rollup, the derived roadmap, and `promote-item`'s lineage edge all read orientation from this field via the `primaryEndpoint`/`counterEndpoint` helpers rather than hardcoding parent/child. Authoring: `append-relation` / `append-relations` accept EITHER raw `--parent`/`--child` OR role-typed `--primary`/`--counter` (mapped to parent/child via `role_direction`); a bare `--parent`/`--child` append of a relation that is BOTH role-bearing and orientation-ambiguous (its source/target kinds overlap) is rejected in favor of `--primary`/`--counter`. Reading: a `context-walk-descendants` / `walk-ancestors` query on a disjoint-kind relation from the wrong endpoint THROWS naming the correct op instead of returning an ambiguous `[]`. `replace-relation` writes raw endpoints verbatim (bypassing the orientation gate) and is the re-orient affordance — run `context-validate` after.
79
+
78
80
  ### Schema versioning + migrations
79
81
 
80
- `<substrate-dir>/migrations.json` is the per-substrate migration registry. A schema `version` bump requires a companion migration declared via `write-schema-migration` — without one, reading or writing an item with an older `schema_version` throws a version mismatch. Migration kinds are `identity` (shape-compatible, no transform) or `declarative-transform` (a spec of rename/set/delete/coerce on dotted paths). The loaded registry walks items forward at the next read/write without a process restart.
82
+ `<substrate-dir>/migrations.json` is the per-substrate migration registry. A schema `version` bump requires a companion migration declared via `write-schema-migration` — without one, reading or writing an item with an older `schema_version` throws a version mismatch. Migration kinds are `identity` (shape-compatible, no transform) or `declarative-transform` (a spec of rename/set/delete/coerce/map_each on dotted paths; `map_each` addresses an array — table mode maps each string element through a lookup, with unmatched elements becoming `{relation_type, item_endpoint}` under a parent/child fallback, and set-on-each mode sets a field on every object element). The loaded registry walks items forward at the next read/write without a process restart. Config loading is migration-aware — a config whose `schema_version` lags the bundled schema is walked forward through the `config` migration chain in memory at load (the on-disk file is never rewritten); every substrate-lifecycle ceremony — `/context init`, `/context accept-all`, `/context install`, `/context update`, `/context check-status`, `/context switch` (the existing-target and switch-back forms; the target substrate is seeded right after the pointer flip), `/context resolve-conflict`, and `/context resolve-blocked` — seeds the catalog's `config` identity declaration into `migrations.json` (idempotent) before its first config read, and a version mismatch with no resolvable chain throws. The ceremonies that reach identity-stamping writes (update, install, resolve-blocked) also establish substrate identity at entry: a config carrying no `substrate_id` gets one minted, persisted, and registered before the first stamping write — a pre-identity substrate heals on the sanctioned ceremony instead of refusing — reported in the ceremony result under `substrateIdEstablished` (live runs only; an established identity is never re-minted). On the write side, versioned-document envelopes converge: every block schema declares an optional top-level `schema_version`, and the write path stamps it (config.json's and migrations.json's included) to the owning schema's current `version` on every sanctioned write — an incoming envelope claiming an older version is first walked forward through the registered chain (or refused with the file left byte-unchanged when no chain reaches the current version), then persisted at the current version; reads of a stamped block validate the whole envelope migration-aware. A substrate whose installed schemas predate the `schema_version` property keeps writing unchanged until `/context update` lands it. The bundled config schema itself evolves expand-contract: new fields land optional, and a non-additive change (a removed/renamed key, or a new required field on a pre-existing object) is refused by a build-time gate (`scripts/check-config-schema.ts`, pre-commit + CI) unless the same change advances the schema `version` and declares a packaged `config` migration reaching it.
81
83
 
82
84
  **Tools registered:** the tool surface grows with the package — read the generated `skills/pi-context/SKILL.md` for the current set, or call the `list-tools` tool at runtime (in-pi) / `grep pi.registerTool packages/pi-context/src/index.ts` (source). Families:
83
85
 
84
- - **Block CRUD** — `read-block`, `write-block`, `read-block-dir`, `append-block-item`, `update-block-item`, `upsert-block-item` (validated find-or-append), `remove-block-item`, and the nested-array variants (`append/update/remove-block-nested-item`).
86
+ - **Block CRUD** — `read-block`, `write-block`, `read-block-dir`, `append-block-item`, `update-block-item`, `upsert-block-item` (validated find-or-append), `remove-block-item`, and the nested-array variants (`append/update/remove-block-nested-item`). `append-block-item` and append-mode `upsert-block-item` take an optional `relations` array filing the new item's birth edges in the same op run — item + edges judged as one atom by the write-time gate. Each entry names the relation_type, the other endpoint's selector, and exactly one orientation: `direction: as_parent|as_child` (raw — the endpoint the new item occupies) or `role: primary|counter` (role-typed — the semantic role the new item holds, mapped via the relation's declared `role_direction`; required for role-bearing orientation-ambiguous relation_types, where the raw form is rejected). `upsert-block-item --dryRun` runs the same orientation guard over the entries, so a preview refuses what the live run would refuse.
85
87
  - **Item-level read/query** — `read-block-item`, `read-block-page`, `filter-block-items`, `resolve-item-by-id`, `resolve-items-by-id`, `join-blocks`, `find-references`, `walk-ancestors`, `context-walk-descendants`, `context-edges-for-lens`, `context-lens-view`, `gather-execution-context`.
86
88
  - **Substrate writes** — `append-relation`, `append-relations` (bulk edge append), `remove-relation`, `replace-relation` (single-write atomic re-orient), `amend-config`, `write-schema`, `write-schema-migration`, `rename-canonical-id`.
87
89
  - **Content-addressing lifecycle** — `promote-item` (cross-substrate derivation: promote an item into another registered substrate as a new content-addressed item + `item_derived_from_item` lineage edge; `dryRun` previews the destination write without persisting).
88
90
  - **Discovery/introspection** — `read-config`, `read-schema`, `read-samples-catalog`, `read-catalog-schema`, `list-tools`, `context-current-state`, `context-bootstrap-state`.
89
- - **Lifecycle/state** — `context-status`, `context-validate`, `context-validate-relations`, `complete-task` (gates on a passing `verification_verifies_item` edge — verification=parent, task=child).
91
+ - **Lifecycle/state** — `context-status`, `context-validate`, `context-validate-relations`, `complete-task` (the closure atom: gates on a passing verification, files the `verification_verifies_item` edge itself — verification=parent, task=child; idempotent — then flips the task to completed in the same run; no prior `append-relation` step).
90
92
  - **Substrate management** — `context-init`, `context-accept-all`, `context-install`, `context-switch`, `context-list`, `context-archive`.
91
- - **Roadmap** — `context-roadmap-load`, `context-roadmap-render`, `context-roadmap-validate`, `context-roadmap-list`.
93
+ - **Roadmap** — `context-roadmap-load`, `context-roadmap-render`, `context-roadmap-validate`: the derived roadmap over the `milestone_precedes_milestone` DAG — milestone-block items topo-ordered by the authored precedes edges, with per-milestone phase/task rollups; adjacency comes strictly from the edges, never inferred from order.
92
94
 
93
95
  The relation byRef ops (`append-relation` / `remove-relation` / `replace-relation` / `append-relations`) and `upsert-block-item` accept a `dryRun` flag: it resolves the operation and validates the prospective whole file under the SAME write-path validation, returning the would-decision (`{ ..., dryRun: true }`) while writing nothing. The same shared library path backs both the op (`--dryRun`) and the orchestrator scripts — one implementation, not a script-only preview.
94
96
 
@@ -101,21 +103,21 @@ The relation byRef ops (`append-relation` / `remove-relation` / `replace-relatio
101
103
  **Commands registered:**
102
104
  - `/context init <substrate-dir>` — bootstrap pointer + substrate/schemas dirs + a never-clobber skeleton `config.json` (schema-valid, empty of vocabulary, minted `substrate_id`); onward via accept-all OR amend-config / edit
103
105
  - `/context accept-all` — adopt `samples/conception.json` as `config.json` (idempotent; never overwrites an existing config)
104
- - `/context install` (CLI: `pi-context context-install [--update]`) — reconcile the substrate against `installed_schemas` / `installed_blocks` in `config.json` by copying assets from the samples catalog (skip-if-exists by default). Populated block data is never overwritten (reported as `preserved`), and empty or absent blocks get the catalog starter. Install also base-stamps each as-installed schema body into the object store and records an **install baseline** in `config.installed_from` — the catalog source (`name@version` + conception `schema_version`) plus a per-schema fingerprint (content hash + declared version) of the installed schemas — used for installed-vs-catalog drift detection. The baseline covers schemas only (blocks are user data); a re-install on an unchanged substrate is idempotent (byte-identical `config.json`, `at` preserved). (Bringing the installed schema model current is now `/context update`, below.)
105
- - `/context check-status` (CLI: `pi-context context-check-status`) — read-only: reports drift between the installed schemas and the catalog, reporting each as `in-sync` / `catalog-ahead` / `locally-modified` / `both-diverged` / `no-baseline` / `missing-catalog` / `missing-installed`, and for each schema behind the catalog (`catalog-ahead` / `both-diverged`) it surfaces `behind` and a `version_delta` — the baseline → catalog version pair (a declared version bump) or a content-only basis when the catalog body moved with the version string unchanged; writes nothing
106
+ - `/context install` (CLI: `pi-context context-install [--update]`) — reconcile the substrate against `installed_schemas` / `installed_blocks` in `config.json` by copying assets from the samples catalog (skip-if-exists by default). Populated block data is never overwritten (reported as `preserved`), and empty or absent blocks get the catalog starter. Install also base-stamps each as-installed schema body into the object store and records an **install baseline** in `config.installed_from` — the catalog source (`name@version` + conception `schema_version`) plus a per-schema fingerprint (content hash + declared version) of the installed schemas — used for installed-vs-catalog drift detection. The baseline covers schemas only (blocks are user data); a re-install on an unchanged substrate is idempotent (byte-identical `config.json`, `at` preserved). On a substrate whose config carries no `substrate_id`, install establishes the identity at entry (mint + persist + register) and reports it under `substrateIdEstablished`. (Bringing the installed schema model current is now `/context update`, below.)
107
+ - `/context check-status` (CLI: `pi-context context-check-status`) — read-only: reports drift between the installed schemas and the catalog, reporting each as `in-sync` / `catalog-ahead` / `locally-modified` / `both-diverged` / `no-baseline` / `missing-catalog` / `missing-installed`, and for each schema behind the catalog (`catalog-ahead` / `both-diverged`) it surfaces `behind` and a `version_delta` — the baseline → catalog version pair (a declared version bump) or a content-only basis when the catalog body moved with the version string unchanged; writes nothing beyond the idempotent ceremony seed of the catalog's `config` migration declarations into `migrations.json` (every substrate-lifecycle ceremony seeds before its first config read, so a version-lagging legacy substrate is diagnosable)
106
108
  - `read-catalog-schema` (CLI: `pi-context read-catalog-schema --kind <canonical_id>`) — read-only: fetches and prints the verbatim bundled catalog `*.schema.json` body for a named block kind (the raw JSON Schema — `properties` / `definitions` / `$id`, not the `read-samples-catalog` projection), so the body is diffable locally against the installed `<substrate>/schemas/<name>.schema.json` without hunting through `node_modules`. Package-intrinsic (reads the extension's bundled samples catalog, independent of any project substrate); mutates nothing. An unknown kind is an error
107
109
  - `validate-block-items` (CLI: `pi-context validate-block-items --block <name>`) — read-only: validates a block's items against the catalog schema version (forward-migrating in memory when the block lags the catalog version) and returns `{ block, from?, to?, valid, failures[] }`, each failure naming the item id, field, and constraint; writes nothing. An unknown block or a missing installed block file is an error
108
- - `/context update [--dryRun]` (CLI: `pi-context update [--dryRun]`) — bring the installed schema model current with the catalog, routing each schema by its drift state: `in-sync` no-op; `catalog-ahead` resync (migration-aware); `locally-modified` / `both-diverged` reconciled by a deterministic 3-way merge of base (the as-installed body in the object store, keyed by the baseline `content_hash`) × ours (installed schema) × theirs (catalog schema) — disjoint edits auto-merge (`required` / `enum` / array-`type` nodes merge as sets), and a schema with irreconcilable per-path conflicts is left unmodified — the conflict set is returned in the op output (under `conflicts`) alongside a readable report, and the calling agent reconciles it then commits via `/context resolve-conflict` (below; no subordinate resolver is spawned). Update also additively propagates catalog-new config-registry entries (`relation_types` / `invariants` / `block_kinds` / `lenses`) absent from the config, preserving user-authored entries and any locally-diverged body of an existing entry (reported under `registryAdditions`). A version-bump `catalog-ahead` resync registers the shipped catalog migration chain's declarations into `migrations.json`; these are reported under `migrationsRegistered` (each `{ schema, from, to }`). A `catalog-ahead` schema whose resync is refused (`blocked`) carries its diagnostic under `blockedDetail` (one entry per blocked schema): the refusal reason — `no-migration-chain` (no shipped chain reaches the catalog version) vs `validation-failed` (the forward-migrated items fail the catalog schema) — the installed→catalog version pair, and for a validation failure the per-item failures naming the failing item id, field, and constraint. A live block also persists a pending-blocked record (`pending-blocked.json`, pinning the target catalog schema + the chain reaching it) consumable by `/context resolve-blocked` (below): fix the named items (or widen the local schema) then run it to commit the resolution so a subsequent `update` converges instead of re-blocking. A `validation-failed` block additionally gets git-style failure markers written INTO the block file at the offending items (full-line `<<<<<<< BLOCKED …` / `>>>>>>> target: …` sentinels), pinning the pre-marker bytes; the schema and `migrations.json` stay byte-unchanged, and `/context resolve-blocked` strips the markers before re-validating. `--dryRun` predicts the precise per-schema outcome (resync / migrate / block / merge / conflict) by running the forward-migration and re-validation in memory, alongside the per-blocked-schema diagnostic detail, the config-registry entries that would be added, and the migration declarations that would be registered, and writes nothing (no markers). Each auto-merged / resynced schema refreshes its baseline so a follow-up `/context check-status` reports it `in-sync`; a schema left as a `conflict` is NOT brought current by update — it stays unmodified until `/context resolve-conflict` commits the reconciliation
110
+ - `/context update [--dryRun]` (CLI: `pi-context update [--dryRun]`) — bring the installed schema model current with the catalog, routing each schema by its drift state: `in-sync` no-op; `catalog-ahead` resync (migration-aware); `locally-modified` / `both-diverged` reconciled by a deterministic 3-way merge of base (the as-installed body in the object store, keyed by the baseline `content_hash`) × ours (installed schema) × theirs (catalog schema) — disjoint edits auto-merge (`required` / `enum` / array-`type` nodes merge as sets), and a schema with irreconcilable per-path conflicts is left unmodified — the conflict set is returned in the op output (under `conflicts`) alongside a readable report, and the calling agent reconciles it then commits via `/context resolve-conflict` (below; no subordinate resolver is spawned). Update also additively propagates catalog-new config-registry entries (`relation_types` / `invariants` / `block_kinds` / `lenses`) absent from the config, preserving user-authored entries and any locally-diverged body of an existing entry (reported under `registryAdditions`). A version-bump `catalog-ahead` resync registers the shipped catalog migration chain's declarations into `migrations.json`; these are reported under `migrationsRegistered` (each `{ schema, from, to }`). A `catalog-ahead` schema whose resync is refused (`blocked`) carries its diagnostic under `blockedDetail` (one entry per blocked schema): the refusal reason — `no-migration-chain` (no shipped chain reaches the catalog version) vs `validation-failed` (the forward-migrated items fail the catalog schema) vs `write-failed` (a non-validation throw at the write boundary, e.g. the block writer's duplicate-item-id guard; the failures entry carries the thrown message, the items were NOT flagged invalid, and no markers or pending-blocked record are produced) — the installed→catalog version pair, and for a validation failure the per-item failures naming the failing item id, field, and constraint. A live `validation-failed` block also persists a pending-blocked record (`pending-blocked.json`, pinning the target catalog schema + the chain reaching it) consumable by `/context resolve-blocked` (below): fix the named items (or widen the local schema) then run it to commit the resolution so a subsequent `update` converges instead of re-blocking. A `validation-failed` block additionally gets git-style failure markers written INTO the block file at the offending items (full-line `<<<<<<< BLOCKED …` / `>>>>>>> target: …` sentinels), pinning the pre-marker bytes; the schema and `migrations.json` stay byte-unchanged, and `/context resolve-blocked` strips the markers before re-validating. `--dryRun` predicts the precise per-schema outcome (resync / migrate / block / merge / conflict) by running the forward-migration and re-validation in memory, alongside the per-blocked-schema diagnostic detail, the config-registry entries that would be added, and the migration declarations that would be registered, and writes nothing beyond the idempotent config-migration ceremony seed (no markers). Each auto-merged / resynced schema refreshes its baseline so a follow-up `/context check-status` reports it `in-sync`; a schema left as a `conflict` is NOT brought current by update — it stays unmodified until `/context resolve-conflict` commits the reconciliation. A run that refuses any schema while applying registry additions or other-schema resyncs/migrations/merges additionally reports the partiality under `partialApplication` (`applied`/`notApplied` mirrors of the result channels + a one-line summary naming what was applied alongside what was refused and why), so a blocked run never reads as a no-op; `--dryRun` reports the predicted partiality in the same shape. On a substrate whose config carries no `substrate_id`, a LIVE update establishes the identity at entry — mints (the same `mintSubstrateId` init uses), persists it through the sanctioned config write, and registers it in the project registry — before its first identity-stamping write, so a pre-identity substrate heals on the ceremony instead of refusing; the run reports it under `substrateIdEstablished`, an established identity is never re-minted, and `--dryRun` (no stamping writes) establishes nothing
109
111
  - `/context resolve-conflict --schemaName <name> [--schema <reconciled>]` (CLI: `pi-context resolve-conflict --schemaName <name> [--schema <reconciled>]`) — commit the reconciliation of a merge conflict `update` surfaced. Run after reconciling a `both-diverged` conflict: it writes the reconciled schema body (meta-validated, atomic) AND advances the merge base for that schema to the catalog body, so the next `update` sees the schema as `locally-modified` and its deterministic merge takes the reconciled body (base === theirs → ours) — auto-merging with zero conflicts and preserving the resolution. Without advancing the base a bare `write-schema` leaves the baseline on the original pre-conflict body and `update` re-derives the same conflict on every run. If `--schema` is omitted the current on-disk schema is treated as already reconciled and only the base is advanced
110
- - `/context resolve-blocked --schemaName <name>` (CLI: `pi-context resolve-blocked --schemaName <name>`) — commit the resolution of a schema `update` blocked. Run after fixing the block's failing items (or widening the local schema): when the block file carries git-style failure markers (written by `update`), it strips the full-line marker sentinels first, then re-validates the corrected block against the pinned target schema from the pending-blocked record (forward-migrating in memory through the pinned chain when the block lags the target version); on pass it registers the chain declarations, writes the target schema, advances the block's `schema_version` envelope and the merge base to the target (so a subsequent `update` converges in-sync instead of re-blocking), and clears the pending entry; on fail it returns the remaining per-item failures and writes nothing (the pending record and the marker file stay intact for a retry)
112
+ - `/context resolve-blocked --schemaName <name>` (CLI: `pi-context resolve-blocked --schemaName <name>`) — commit the resolution of a schema `update` blocked. Run after fixing the block's failing items (or widening the local schema): when the block file carries git-style failure markers (written by `update`), it strips the full-line marker sentinels first, then re-validates the corrected block against the pinned target schema from the pending-blocked record (forward-migrating in memory through the pinned chain when the block lags the target version); on pass it registers the chain declarations, writes the target schema, advances the block's `schema_version` envelope and the merge base to the target (so a subsequent `update` converges in-sync instead of re-blocking), and clears the pending entry; on fail it returns the remaining per-item failures and writes nothing (the pending record and the marker file stay intact for a retry). The commit itself is all-or-nothing: a throw partway through it restores every touched file byte-exact — `migrations.json`, the installed schema, the block file, `config.json`, and the pending record — and reports the failure, never a partial commit. On a substrate whose config carries no `substrate_id`, resolve-blocked establishes the identity at entry (mint + persist + register) before the commit's stamping write and reports it under `substrateIdEstablished`
113
+ - `/context reconcile [--dryRun]` (CLI: `pi-context context-reconcile [--dryRun]`, auth-gated) — converge stored substrate state with its derivation, the repair half of the `derived-status` invariant class. For every block kind a `derived-status` invariant declares (paired with its `state_derivation.rollups` entry), computes each item's stored-vs-derived status delta using the SAME completeness helper the state derivation's gate satisfaction and `context-validate` use — preview, detector, and repair cannot disagree. The sweep also includes declared-baseline staleness: every `stale_conditions`-bearing item whose status buckets complete and whose typed condition fired (item-status / file-changed / revision-moved) or whose citation content pin drifted transitions to `stale`, through the same `evaluateStalenessCandidates` verdict `context-validate` flags with (flag-only anchor-drift items never transition). `--dryRun` returns the exact delta + transition sets a live run would apply (deltas: id, block, from/to, declaring invariant; `stalenessTransitions`: id, block, from, to stale, firing reasons), writing nothing; a live run applies exactly those sets through the standard validated write path (identity-stamped, envelope-stamped, writer-attested) and reports the applied counts. Scope: derived-status deltas + declared-staleness transitions ONLY — never an authored-status kind (feature/gap/issue/task buckets are human judgment), never prose; those classes are flagged for review by `context-validate`, not auto-repaired. A converged substrate is a clean no-op both ways; a live run on a pre-identity substrate establishes identity at entry
111
114
  - `/context view <lensId>` — render a configured lens (groupByLens projection) into the conversation as markdown
112
115
  - `/context lens-curate <lensId>` — surface bin-assignment suggestions for uncategorized items as a follow-up turn; the LLM persists chosen edges via `append-block-item` against `relations.json`
113
116
  - `/context status` — derived project state (source metrics, test counts, block summaries, git state)
114
117
  - `/context add-work` — extract structured items from conversation into typed blocks
115
118
  - `/context validate` — cross-block referential integrity checks
116
- - `/context roadmap-list` — list every roadmap in `<config.root>/roadmap.json` (id, title, status, phase count)
117
- - `/context roadmap-view <ROADMAP-id>` render a roadmap as pure-textual markdown (phase order, per-phase adjacency from authored `phase_depends_on` edges, status rollup, milestone resolution; no mermaid)
118
- - `/context roadmap-validate [ROADMAP-id]` — validate every roadmap (or one) and surface structured issues
119
+ - `/context roadmap-view` — render the derived roadmap as pure-textual markdown (milestone order over authored `milestone_precedes_milestone` edges, per-milestone phase/task rollups, adjacency strictly from edges; no mermaid)
120
+ - `/context roadmap-validate`validate the derived roadmap and surface structured issues (error/warning/info codes; info never affects status)
119
121
  - `/context switch <existing-dir> | -c <new-dir> | -` — flip the bootstrap pointer (to an existing substrate, bootstrap-new-and-flip, or back to `previous_contextDir`)
120
122
  - `/context list` — enumerate top-level dirs containing `config.json` (switchable substrates); marks the active one
121
123
  - `/context archive <dir>` — move a non-active substrate dir to `archive/<dir>/`
@@ -1,3 +1,21 @@
1
+ /**
2
+ * Centralized read/write API for .project/*.json project block files.
3
+ * Validates data against schemas before writing; uses atomic writes (tmp + rename).
4
+ * Read-modify-write operations (append, update) use file-level locking via proper-lockfile
5
+ * to prevent data loss from concurrent workflow steps targeting the same block.
6
+ *
7
+ * DispatchContext (FGAP-004): every write function accepts an optional final
8
+ * argument `ctx?: DispatchContext`. When provided AND the target block's
9
+ * schema declares any of {created_by, created_at, modified_by, modified_at},
10
+ * items are stamped via `stampItem` from `./dispatch-context` before AJV
11
+ * validation. When `ctx` is undefined, behavior is byte-identical to the
12
+ * pre-step-3 surface — the parameter is purely additive. The has-author-fields
13
+ * decision is mtime-cached per (cwd, blockName) to avoid re-reading the
14
+ * schema on every write; mirrors the `loadContext` cache pattern from
15
+ * `context.ts`.
16
+ *
17
+ * Future extraction seam for pi-project extension.
18
+ */
1
19
  import type { DispatchContext } from "./dispatch-context.js";
2
20
  /**
3
21
  * The MANDATORY content/metadata floor (content-addressed substrate identity,
@@ -110,39 +128,8 @@ export declare function contentProjection(schema: Record<string, unknown>, array
110
128
  * edge dedup key in `endpointIdentity`, not the oid itself.)
111
129
  */
112
130
  export declare function mintOid(substrateId: string, nonce?: string): string;
113
- /**
114
- * Compute the content/identity fields for an item about to be written, per the
115
- * content-addressed substrate identity model (Cycle 3 / Phase C). Returns the
116
- * item with `oid` / `content_hash` / `content_parent` set; the input is never
117
- * mutated (a shallow copy is returned). Also persists the content projection to
118
- * the object store as a side effect on every stamping write.
119
- *
120
- * NO-OP GATE (locked decision 1): when the item's array subschema does not
121
- * declare all three identity fields, the original `item` is returned unchanged
122
- * (no oid mint, no hash, no object write, no substrate_id read). This scopes
123
- * the behavior change to exactly the schemas Cycle 3 edits — bespoke test
124
- * schemas without the fields are untouched — mirroring `maybeStampItem`'s
125
- * author-field gate. The gate is NOT ctx-gated: content hash / oid are
126
- * integrity, not attestation.
127
- *
128
- * Ordering vs author-stamp: call AFTER `maybeStampItem`/`maybeStampTypedItem`.
129
- * Author fields are in the metadata partition (excluded from the projection),
130
- * so the content hash is invariant to whether author-stamping ran first — but
131
- * `content_hash` itself is a metadata field, so it must be assigned AFTER the
132
- * projection is computed from the (already author-stamped) item.
133
- *
134
- * `mode`:
135
- * - `"create"`: mint a fresh `oid` (via `substrateIdForDir(substrateDir)`),
136
- * compute `content_hash`, set NO `content_parent` (a v1 item has no prior).
137
- * - `"update"`: preserve `prior.oid` — and THROW if the incoming item carries
138
- * a different `oid` (locked decision 3: oid is immutable). Recompute
139
- * `content_hash`. When the content changed (new hash !== prior.content_hash)
140
- * set `content_parent = prior.content_hash`; when content is unchanged
141
- * (no-op write) leave `content_parent` at the prior value (not advanced).
142
- *
143
- * `prior` is the on-disk item being replaced (required for `"update"`); for
144
- * `"create"` it is ignored.
145
- */
131
+ /** Current commit of `ref` in the repo at `projectRoot`, or null (no repo / unresolvable). */
132
+ export declare function resolveGitRefOrNull(projectRoot: string, ref: string): string | null;
146
133
  export declare function prepareItemIdentityForWrite(substrateDir: string, blockName: string, item: Record<string, unknown>, schemaPath: string | null, arrayKey: string, mode: "create" | "update", prior?: Record<string, unknown>): Record<string, unknown>;
147
134
  /**
148
135
  * Read and parse a .project/{blockName}.json file.
@@ -1 +1 @@
1
- {"version":3,"file":"block-api.d.ts","sourceRoot":"","sources":["../src/block-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block-api.d.ts","sourceRoot":"","sources":["../src/block-api.ts"],"names":[],"mappings":"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"}