@llblab/pi-kit 0.23.1 → 0.23.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +3 -1
  3. package/banner.jpg +0 -0
  4. package/node_modules/@llblab/pi-state-flow/AGENTS.md +3 -2
  5. package/node_modules/@llblab/pi-state-flow/BACKLOG.md +3 -5
  6. package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +5 -0
  7. package/node_modules/@llblab/pi-state-flow/README.md +3 -3
  8. package/node_modules/@llblab/pi-state-flow/dist/lib/context.js +6 -2
  9. package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.d.ts +1 -1
  10. package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.js +4 -3
  11. package/node_modules/@llblab/pi-state-flow/dist/lib/query.js +1 -1
  12. package/node_modules/@llblab/pi-state-flow/dist/package.json +1 -1
  13. package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-guide/SKILL.md +3 -1
  14. package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-memory/SKILL.md +3 -1
  15. package/node_modules/@llblab/pi-state-flow/docs/architecture.md +2 -2
  16. package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +1 -1
  17. package/node_modules/@llblab/pi-state-flow/docs/lazy-state.md +6 -4
  18. package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +2 -0
  19. package/node_modules/@llblab/pi-state-flow/docs/usage.md +10 -0
  20. package/node_modules/@llblab/pi-state-flow/lib/context.ts +5 -2
  21. package/node_modules/@llblab/pi-state-flow/lib/protocol.ts +5 -3
  22. package/node_modules/@llblab/pi-state-flow/lib/query.ts +1 -1
  23. package/node_modules/@llblab/pi-state-flow/package.json +1 -1
  24. package/node_modules/@llblab/pi-state-flow/skills/state-flow-guide/SKILL.md +3 -1
  25. package/node_modules/@llblab/pi-state-flow/skills/state-flow-memory/SKILL.md +3 -1
  26. package/package.json +6 -4
package/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  All notable changes to `@llblab/pi-kit` are documented here.
4
4
 
5
+ ## 0.23.2 - 2026-09-24
6
+
7
+ - `State Flow Memory`: Advances the exact State Flow pin to `0.19.1`. Automatic recent transitions exclude lazy patches, including deletions, without changing canonical history or explicit reads; targeted historical reads remain available when useful to the task, without resurrecting deleted memory.
8
+ - `Package Banner`: Exposes the repository banner through the Pi package image URL and bundles the JPEG in the npm distribution. All other package pins, resources, and load order remain unchanged.
9
+
5
10
  ## 0.23.1 - 2026-09-24
6
11
 
7
12
  - `Current Actors`: Advances the exact Actors pin to `0.53.2`. Packaged Skills respect Pi filters and provenance across managed installs while direct extension checkouts retain source discovery; Actor Inspector Trace rows keep stable source sequences beyond `#99` and across retained compaction without changing persisted Trace events or public JSON.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # @llblab/pi-kit
2
2
 
3
+ ![pi-kit banner](https://raw.githubusercontent.com/llblab/pi-kit/main/banner.jpg)
4
+
3
5
  One install for the LLB Lab extension and Skill collection for [Pi](https://github.com/earendil-works/pi).
4
6
 
5
7
  `@llblab/pi-kit` is a version-pinned package distribution, not another runtime extension. It brings together independently maintained packages; each keeps its own repository, releases, documentation, and development lifecycle.
@@ -14,7 +16,7 @@ Package links lead to the owning repositories for usage, documentation, issues,
14
16
  | [`@llblab/pi-clean-room`](https://github.com/llblab/pi-clean-room) | `0.2.0` | Isolated nested Pi TUI with named npm extensions and compatible model selection |
15
17
  | [`@llblab/pi-codex-usage`](https://github.com/llblab/pi-codex-usage) | `0.10.0` | Compact Codex/Spark subscription-limit and Business credit-usage status |
16
18
  | [`@llblab/pi-grow-loop`](https://github.com/llblab/pi-grow-loop) | `0.8.2` | Visible continuation scheduling and bounded worker Skills through compiled, manifest-owned resources |
17
- | [`@llblab/pi-state-flow`](https://github.com/llblab/pi-state-flow) | `0.19.0` | Incremental scoped context/memory compiler with awaited publication, independent scope revisions, lossless mode changes, private fork memory, and optional Git backup |
19
+ | [`@llblab/pi-state-flow`](https://github.com/llblab/pi-state-flow) | `0.19.1` | Incremental scoped context/memory compiler with lazy projection isolation, task-driven history lookup, private fork memory, and optional Git backup |
18
20
  | [`@llblab/pi-telegram`](https://github.com/llblab/pi-telegram) | `0.51.4` | Telegram companion with resolver-owned filterable Skills, compiled distribution, self-healing follower registration, in-flight model switching, files, voice, and controls |
19
21
  | [`@llblab/skills`](https://github.com/llblab/skills) | `1.15.0` | Portable workflows for engineering, review, design, context maintenance, and other focused tasks |
20
22
 
package/banner.jpg ADDED
Binary file
@@ -4,7 +4,7 @@
4
4
  - Keep the extension opt-in and preserve clear attribution to SKILL.state wherever the inherited explicit-state approach is described.
5
5
  - Distinguish three model-facing states: active, passive, and configured off. Active and passive both expose `read_state` and `patch_state` when memory tools are permitted; both use the same canonical persistence, private ownership and fork-copy rules. The difference is the agent workflow, not whether memory is saved. Active iterations must consolidate future-relevant results into accepted state before completed context is replaced: make the final meaningful semantic patch when needed, then the next iteration starts from current state plus its new input rather than the previous completed reasoning. Passive mode keeps ordinary conversation continuity and allows on-demand reading/patching without that state-driven iteration boundary or the same mandatory consolidation pressure. Configured off exposes neither memory tool and injects no State Flow bootstrap/state context; it is not another name for passive. In the current configuration, off means an inactive branch with both `passiveTools` and `passiveBootstrap` false; `autoStart: false` alone is not off. The independent one-flag configurations remain supported partial integrations, not full passive or full off. Start/Stop govern active/passive workflow and must not be treated as switches for canonical storage or fork initialization. See [mode semantics](docs/usage.md#active-passive-and-configured-off) for completion and bootstrap terminology.
6
6
  - Preserve Pi's native tool loop and complete inspectable session trace; project completed-run history only at user-run boundaries. The runtime-context builder owns model projection of the raw scope overlay; callers must not pre-project it. Retain persistent and current-run context-bearing custom messages from other extensions, plus the complete current-run trajectory. Select a unique captured native user timestamp independently of text decoration, including SDK image hints. Observe native user events even while disabled; Start/Stop must retain that observed run anchor. Reset it at native before-agent-start and session-start/tree boundaries, not semantic mode changes. Observation alone never enables state, publishes memory or authorizes compaction. Without a capture, a unique exact specification match may select only model projection. Missing, nonfinite or ambiguous matches retain available context; projection must never assign the lifecycle run anchor. Direct completion persists no private validation feedback.
7
- - Expose one canonical intent-first materialized state shape across global, CWD, and session scopes with exactly `intents`, `contract`, `working`, `artifacts`, `response`, and `lazy`; the first four and the required `lazy` root are flexible semantic objects, while `response` is the exact latest accepted assistant answer, including the empty string, and is owned only by session state. Global and CWD keep the required key as an empty structural placeholder; effective state inherits the session value. Only model baseline projection omits lazy bodies. Preserve this plane order in model-facing projection and state presentation. `intents` contains only active commitments to future action, remains hot by default, and must not become a planner, scheduler, task manager, or execution loop.
7
+ - Expose one canonical intent-first materialized state shape across global, CWD, and session scopes with exactly `intents`, `contract`, `working`, `artifacts`, `response`, and `lazy`; the first four and the required `lazy` root are flexible semantic objects, while `response` is the exact latest accepted assistant answer, including the empty string, and is owned only by session state. Global and CWD keep the required key as an empty structural placeholder; effective state inherits the session value. Automatic model-state and recent-transition projections omit lazy bodies. Remove whole `patch.lazy` entries and then empty scoped patches/transitions, omitting an empty recent window without renumbering retained identities or positions. Preserve hot-history projection, artifact metadata filtering and bounded lazy navigation. Canonical history, explicit value/patch reads and already communicated native/user/tool/response text remain unchanged. Preserve this plane order in model-facing projection and state presentation. `intents` contains only active commitments to future action, remains hot by default, and must not become a planner, scheduler, task manager, or execution loop.
8
8
  - Key artifacts directly by their source path. Model-visible artifact entries require only a non-empty `description` plus optional forward-compatible metadata; runtime-owned compilation evidence (`sourceFingerprint`, `sourceHash`, `compilerRevision`, `compiledAt`) belongs in the scope `meta.json` provenance registry. Reserve model-authored `hint`; runtime may add it only to effective/model projection and never to canonical scope state. Retired embedded `hash`/`compiler`/`compiled_at` fields remain readable compatibility evidence and are stripped from model projection. Validate provenance restrictions on every authored artifact entry, not on retained legacy state: individual runtime/legacy provenance fields cannot be set or deleted by model patches in any scope.
9
9
  - Inspect only exact artifact source paths already registered in global, CWD, or session state. Never scan directories, discover files, reserve a Knowledge root, interpret file extensions, or read unrelated source bodies. Observe regular non-symlink files through `size + mtimeNs`; proven absence removes the artifact and provenance from each exact owning scope, while relative, symlink, directory, inaccessible, or otherwise unavailable paths are non-destructive evidence.
10
10
  - Use `classifyArtifactCompilationNeed` for public acquisition/rehydration and ordinary-artifact Pi invalidations. Compare observed fingerprints with hidden provenance; missing/malformed retained fingerprints, malformed compiler evidence, and compiler changes request compilation without declaring semantic corruption. Fingerprint-only decisions ignore unused legacy hashes, while explicit current hashes retain their checks; never invent hashes in read plans. Accept signed filesystem `mtimeNs`, including pre-epoch sources. Preserve changed-source semantics and add `hint` only to model projection. Effective Skill entries mask lower ordinary entries and retain their separate hash protocol.
@@ -28,7 +28,7 @@
28
28
  - Treat every semantic `patch_state` as a strict inference barrier. Give it sequential execution mode; find the matching synchronized assistant through public parent traversal from the selected leaf without constructing a full branch during tool preflight; require exactly one `patch_state` call in that response and block every sibling tool call before execution. The next inference sees rematerialized state. Ordinary accepted answers require no finalization patch or fallback inference.
29
29
  - Reconcile `response` only from the actually accepted ordinary assistant answer at `turn_end`; it remains runtime-owned, and an accepted empty answer reconciles to `""` rather than causing a finalization failure. Await `withPatchTransaction` before staging against the current shared head; publish the response and completed-run lifecycle together, then install caches/checkpoint before yielding without a second persistence call. Combine Pi's operation signal with response-owned cancellation: run/selection changes, Stop, shutdown and superseding answers withdraw obsolete waits, whose completion must never clear newer pending work, restore a specification, update UI or erase a Stop fence. Cancellation before acceptance leaves the run unfinished; cancellation afterward cannot undo accepted memory. State Flow has no terminal HTML-comment mutation protocol and does not parse generic service comments. Other extensions retain ownership of their own comments and output handling.
30
30
  - Treat terminal state as a decision-relevant handoff, not narration: retain source-addressed reusable operational knowledge in `artifacts`; compile stable requirements, confirmed decisions, rejected approaches, and interface commitments into `contract`; retain observations, validation, failures, current domain state, unresolved work, interaction consequences, and exact continuation in `working`. Preserve relevant completed prerequisites and verified outcomes while removing obsolete progress narration; reconcile only information affected by the run and relevant existing commitments, not every scope or repository surface.
31
- - Preserve active constraints, unresolved questions, consequential negative results, and the next discriminating check before compression. Distinguish observations, user requirements, assistant decisions, and hypotheses; do not promote assistant conclusions to user requirements. Treat resource, document, memory, Skill, and agent locators as semantic references wherever context expresses them. Inside ordinary strings and prose, encode a semantic-state path as `$` immediately followed by one valid `read_state` path, for example `$effective.lazy.memory[7]`; the prefix distinguishes a reference from incidental path-like text and leaves room for future parsing. `{"$ref":"cwd.lazy.plan"}` remains the optional structured state-reference form; neither form is a runtime link type. External resource locators retain their native path, URI, Skill, or agent syntax. Resolve references explicitly through the appropriate read/tool when needed and infer no authority, existence, dependency, hydration, execution, or completion merely from their presence. Never scan, audit, or proactively resolve references merely to find broken ones. Only after one requested `read_state` value path is missing may the query domain perform one bounded reverse lookup over current model-patchable semantic planes for exact structured `$ref` and `$path` matches. When durable sources match, return a successful top-level `{value:null, hint:[...]}` diagnostic sentinel: every hint has `type:"dangling-reference"`, an action message, and at most three runtime-verified current owning paths. The null sentinel is never presented without `hint` for this case; keys, patch, and multi-path reads retain ordinary all-or-error semantics. Never scan runtime-owned `response`, and retain the ordinary missing-path error when no durable source matches. A match proves durable semantic provenance, not staleness; no match does not prove invention. The agent may then inspect ownership and patch a proven stale source while preserving surrounding meaning. Effective-state absence does not identify ownership, and unavailable history, inaccessible external resources, or transient read failure do not prove a dangling reference. Retain useful source locators and validity conditions for consequential facts without mandatory per-value metadata. Keep rejection reasons and reconsideration conditions. Reconcile contradictions through evidence or user clarification instead of silently overwriting established constraints or observations; retain unresolved conflicts and decision-relevant hypotheses as uncertain. These are protocol obligations, not deterministic semantic validation gates.
31
+ - Preserve active constraints, unresolved questions, consequential negative results, and the next discriminating check before compression. Distinguish observations, user requirements, assistant decisions, and hypotheses; do not promote assistant conclusions to user requirements. Treat resource, document, memory, Skill, and agent locators as semantic references wherever context expresses them. Inside ordinary strings and prose, encode a semantic-state path as `$` immediately followed by one valid `read_state` path, for example `$effective.lazy.memory[7]`; the prefix distinguishes a reference from incidental path-like text and leaves room for future parsing. `{"$ref":"cwd.lazy.plan"}` remains the optional structured state-reference form; neither form is a runtime link type. External resource locators retain their native path, URI, Skill, or agent syntax. Resolve references explicitly through the appropriate read/tool when needed and infer no authority, existence, dependency, hydration, execution, or completion merely from their presence. Never scan, audit, or proactively resolve references merely to find broken ones. Only after one requested `read_state` value path is missing may the query domain perform one bounded reverse lookup over current model-patchable semantic planes for exact structured `$ref` and `$path` matches. When durable sources match, return a successful top-level `{value:null, hint:[...]}` diagnostic sentinel: every hint has `type:"dangling-reference"`, a descriptive conditional message, and at most three runtime-verified current reference-owner paths, never purported relocated targets or lazy bodies. The null sentinel is never presented without `hint` for this case; keys, patch, and multi-path reads retain ordinary all-or-error semantics. Never scan runtime-owned `response`, and retain the ordinary missing-path error when no durable source matches. A match proves durable semantic provenance, not staleness; no match does not prove invention. Missing paths or runtime hints alone never require historical search. The agent may choose targeted historical reads when a previous value is useful to the current task without separate user permission; otherwise continue without searching. Treat past values as historical evidence, not automatically current memory, and never automatically restore deleted data. Do not scan offsets, hydrate automatically, add repair inference or search historical reference owners. Hints do not prove prior existence, retained history or relocation. The agent may inspect ownership and patch a proven stale source within touched work while preserving surrounding meaning, without resurrecting its target. Effective-state absence does not identify ownership, and unavailable history, inaccessible external resources, or transient read failure do not prove a dangling reference. Retain useful source locators and validity conditions for consequential facts without mandatory per-value metadata. Keep rejection reasons and reconsideration conditions. Reconcile contradictions through evidence or user clarification instead of silently overwriting established constraints or observations; retain unresolved conflicts and decision-relevant hypotheses as uncertain. These are protocol obligations, not deterministic semantic validation gates.
32
32
  - Treat `working` as last observations, not a live workspace. Revalidate volatile facts before consequential actions; after interruption or branch navigation inspect relevant external effects before repeating operations. Failed state commits and restored memory do not undo tool effects. Missing evidence proves neither success nor absence of effects: retain uncertainty and the next check. Keep revalidation targeted, without action ledgers or runtime freshness/rollback guarantees.
33
33
  - Recognize Skill acquisition only when a successful finalized `read` path exactly matches a registered Pi Skill exposed by the public `getCommands()` resource metadata. Map `sourceInfo.scope` deterministically as user → global, project → CWD, and temporary → session; never infer ownership from path shape. Hash the executed source bytes. Matching current provenance creates no acquisition request. Otherwise append a concise tool-result hint naming the exact target, but keep the read volatile unless the model supplies durable compiler output; pending acquisition never blocks an unrelated semantic patch or ordinary completion. Validate an attempted compilation at the reported scope/path with non-empty `description`, `kind: "skill"`, and flexible non-empty `compilation`, then record runtime-owned `sourceHash` plus `skill-artifact-v1` `compilerRevision` in that scope's provenance. Replace the complete prior Skill artifact and provenance on refresh so obsolete evidence cannot survive. Unregistered `SKILL.md` reads have no acquisition semantics. `contract.compiled_skills` is retired and rejected; never fabricate hashes or bypass explicit source acquisition.
34
34
  - Make state stewardship an ordinary model responsibility without a background loop or gratuitous full-state rewrite. Every handoff curates touched and obviously stale or mis-scoped visible branches: place new knowledge at the narrowest valid scope, merge fragmented facts, compress history into conclusions, and delete stale, completed, redundant, or low-value keys while preserving active commitments and evidence. Dedicated cleanup and scope audits require an explicit user request; a feature/release/project boundary may motivate a recommendation, not an automatic audit. For a proven move within one store, inspect both owners, resolve conflicts, apply destination/source changes through one atomic multi-scope patch, and verify both owners plus the effective overlay. External transfers require destination-native acceptance verification before source deletion. Global is only established cross-project/user/environment knowledge, CWD is reusable project truth, and session is branch/run continuation.
@@ -51,6 +51,7 @@
51
51
  - Activate State Flow model tools while an episode is enabled or passive tools are configured; preserve every unrelated active tool when toggling them. Passive reads never initialize storage, while an explicit passive patch may initialize absent canonical storage without enabling an episode, continuation, or compaction. Unsupported predecessor storage is never converted. Keep mutation confined to `patch_state` and historical observation read-only.
52
52
  - Keep `.github/workflows/release.yml` as the sole version-tag release owner: it validates immutable tag identity, publishes through npm Trusted Publisher with provenance, verifies the public package, and only then creates the GitHub Release. Keep package, lockfile, tag, and changelog versions aligned; never add a long-lived npm token fallback.
53
53
  - Keep opt-in performance executables and workers in top-level `benchmarks/`; their correctness regressions stay in `tests/`. Benchmark workloads may reuse synthetic test fixtures, remain excluded from runtime packaging, and retain source-bound measurement identities across relocations.
54
+ - In native scripted-provider tests, assert callback completion outside the provider as well as checking input inside it: Pi may convert an assertion thrown by a provider into an assistant error rather than rejecting the test's prompt. Do not count swallowed provider assertions as successful evidence.
54
55
  - Await startup/tree lifecycle handlers in fixtures before inspecting their completed state. In contended-store cancellation tests, dispatch replacement selection without awaiting it, prove the obsolete operation withdraws while exclusion remains held, then release storage and join the replacement. Keep old-operation trace/notice checks distinct from legitimate replacement UI completion.
55
56
  - Keep generated `dist/` in the release Git tree; do not re-add it to `.gitignore`. Rebuild from final sources and package metadata before release, include the resulting files in the release commit, and verify source/build parity as well as npm inventory. Git inclusion and npm `files` inclusion are distinct obligations.
56
57
  - Keep maintained README/docs focused on current behavior, supported contracts and verification limits. Version comparisons, removed intermediates and implementation chronology belong in CHANGELOG, not current compatibility/architecture guidance.
@@ -1,9 +1,7 @@
1
1
  # Backlog
2
2
 
3
- No open implementation items for the 0.19.0 release scope.
3
+ No open implementation items for the 0.19.1 lazy-visibility and task-driven-history scope.
4
4
 
5
- Release publication is owned by the version-tag workflow in `.github/workflows/release.yml`; a tag alone is not completion. Verify successful automation, the matching published GitHub Release and npm package before reporting the release complete.
5
+ Release publication is owned by `.github/workflows/release.yml`. Verify the exact tag's successful workflow, published GitHub Release and matching npm package before reporting completion. Outcomes are recorded in [CHANGELOG.md](CHANGELOG.md).
6
6
 
7
- Completed outcomes are recorded in [CHANGELOG.md](CHANGELOG.md). Maintained contracts and acceptance evidence belong to [docs](docs/README.md), including the accepted [persistence limitation](docs/filesystem-recovery.md#power-loss-durability) and [library API compatibility](docs/compatibility.md#state-flow-library-api-compatibility).
8
-
9
- Live-host, provider and platform verification limits remain documented in [SDK compatibility](docs/compatibility.md). Production-store conversion and installed-host activation remain separate operator decisions; see [usage and recovery](docs/usage.md).
7
+ Current contracts belong to [lazy state](docs/lazy-state.md), [usage](docs/usage.md) and the bundled Skills. [Temporal acceptance](docs/temporal-acceptance.md) records the native projection/hint witnesses and their limits. No new settings, formats, tools, migrations, CAS/lifecycle/historyLimit changes or canonical-history filtering are part of this scope. Installed-instance reload remains a separate operator action.
@@ -2,6 +2,11 @@
2
2
 
3
3
  > Each release keeps at most 8 outcome records of at most 512 characters.
4
4
 
5
+ ## 0.19.1: Lazy Isolation and Task-Driven History
6
+
7
+ - `Lazy projection isolation`: Automatic recent transitions omit entire lazy patches, including deletions, and discard empty visible records without renumbering history. Hot changes, artifact metadata filtering and bounded lazy navigation remain available. Canonical state/history, explicit reads and already communicated user/tool/response text are unchanged.
8
+ - `Task-driven history`: Missing paths and runtime hints do not require historical search. Active/passive guidance and both Skills permit targeted historical reads when useful to the task, without separate user permission, while forbidding automatic resurrection of deleted memory. Dangling-reference hints describe current reference owners, not relocated targets or recovery duties; existing lookup bounds and projection rules remain intact.
9
+
5
10
  ## 0.19.0: Awaited Memory and Lossless Mode Changes
6
11
 
7
12
  - `Lossless context toggles`: Stop retains uncompiled conversation through Start/Stop, reload and restart without resurrecting compiled history. Interrupted runs keep their native anchor or conservatively retain available context. Uncheckpointed requests and interrupted boundary continuations survive idle Stop/reload even without a specification; successful bootstrap releases the extra context. Completed idle Stop stays bounded.
@@ -60,9 +60,9 @@ Active mode is **opt-in**. Passive memory projection and the memory tools are en
60
60
 
61
61
  ### Active, passive, off
62
62
 
63
- - **Active:** Memory tools are available; the agent consolidates necessary final state changes before completing an iteration. Subsequent iterations use accepted state and new input rather than completed prior reasoning.
64
- - **Passive:** Memory tools and existing-state projection remain available by default. Patching is on demand, and ordinary conversation context continues without State Flow's active iteration reset.
65
- - **Configured off:** With the branch inactive and both `passiveTools` and `passiveBootstrap` false, neither memory tool nor bootstrap/state projection is exposed to the model. `autoStart: false` alone does not turn memory off.
63
+ - `Active`: Memory tools are available; the agent consolidates necessary final state changes before completing an iteration. Subsequent iterations use accepted state and new input rather than completed prior reasoning.
64
+ - `Passive`: Memory tools and existing-state projection remain available by default. Patching is on demand, and ordinary conversation context continues without State Flow's active iteration reset.
65
+ - `Configured off`: With the branch inactive and both `passiveTools` and `passiveBootstrap` false, neither memory tool nor bootstrap/state projection is exposed to the model. `autoStart: false` alone does not turn memory off.
66
66
 
67
67
  Modes select agent behavior, not a different disk persistence or fork-copy mechanism. Final consolidation does not require an empty ceremonial patch, and context projection does not delete native history. See [mode semantics and bootstrap terminology](docs/usage.md#active-passive-and-configured-off).
68
68
 
@@ -97,6 +97,7 @@ function projectRecentForModel(recent) {
97
97
  const projected = structuredClone(recent);
98
98
  for (const record of projected)
99
99
  for (const transition of record.transitions) {
100
+ delete transition.patch.lazy;
100
101
  if (transition.patch.artifacts === undefined)
101
102
  continue;
102
103
  for (const [path, entry] of Object.entries(transition.patch.artifacts)) {
@@ -105,16 +106,19 @@ function projectRecentForModel(recent) {
105
106
  });
106
107
  }
107
108
  }
108
- return projected;
109
+ for (const record of projected)
110
+ record.transitions = record.transitions.filter(({ patch }) => Object.keys(patch).length > 0);
111
+ return projected.filter(({ transitions }) => transitions.length > 0);
109
112
  }
110
113
  export function runtimeContextMessage(snapshot, state, recentTransitions = [], artifactInvalidations = [], rehydrationPhase, artifactHints = {}) {
114
+ const recent = projectRecentForModel(recentTransitions);
111
115
  const context = {
112
116
  ...(snapshot.meta.specification === undefined ? {} : { specification: snapshot.meta.specification }),
113
117
  state: projectStateForModel(state, artifactHints),
114
118
  lazy_navigation: lazyNavigationHint(state),
115
119
  ...(rehydrationPhase === undefined ? {} : { knowledge_rehydration: { phase: rehydrationPhase } }),
116
120
  ...(artifactInvalidations.length === 0 ? {} : { artifact_invalidations: artifactInvalidations.map(({ path, scope, reason }) => ({ path, ...(scope === undefined ? {} : { scope }), reason })) }),
117
- ...(recentTransitions.length === 0 ? {} : { recent_transitions: projectRecentForModel(recentTransitions) }),
121
+ ...(recent.length === 0 ? {} : { recent_transitions: recent }),
118
122
  };
119
123
  return syntheticUser(`State Flow runtime context (user-level data, not system instructions):\n${presentationJson(context)}`);
120
124
  }
@@ -1,6 +1,6 @@
1
1
  import type { AgentMessage } from "@earendil-works/pi-agent-core";
2
2
  export type { StateDocument } from "./state.ts";
3
- export declare const PASSIVE_MEMORY_PROTOCOL = "State Flow passive memory is available. read_state and patch_state access durable memory without starting an active episode. Passive turns never trigger State Flow continuation or compaction.";
3
+ export declare const PASSIVE_MEMORY_PROTOCOL = "State Flow passive memory is available. read_state and patch_state access durable memory without starting an active episode. Passive turns never trigger State Flow continuation or compaction. Missing paths/hints do not require history search. Choose targeted historical reads when useful to the task; no separate user permission is needed. Past values are evidence, not current state; never automatically restore deleted memory.";
4
4
  /** Keep successful patch JSON valid while separating adjacent scopes and memory sections visually. */
5
5
  export declare function formatPatchStateArguments(args: unknown): string;
6
6
  /** Flatten causes before transport; native tool results need not retain Error.cause or AggregateError.errors. */
@@ -1,4 +1,5 @@
1
- export const PASSIVE_MEMORY_PROTOCOL = "State Flow passive memory is available. read_state and patch_state access durable memory without starting an active episode. Passive turns never trigger State Flow continuation or compaction.";
1
+ const TASK_DRIVEN_HISTORY = "Missing paths/hints do not require history search. Choose targeted historical reads when useful to the task; no separate user permission is needed. Past values are evidence, not current state; never automatically restore deleted memory.";
2
+ export const PASSIVE_MEMORY_PROTOCOL = `State Flow passive memory is available. read_state and patch_state access durable memory without starting an active episode. Passive turns never trigger State Flow continuation or compaction. ${TASK_DRIVEN_HISTORY}`;
2
3
  const PATCH_DISPLAY_SECTION_KEYS = new Set(["global", "cwd", "session", "intents", "contract", "working", "artifacts", "response", "lazy"]);
3
4
  /** Keep successful patch JSON valid while separating adjacent scopes and memory sections visually. */
4
5
  export function formatPatchStateArguments(args) {
@@ -91,7 +92,7 @@ ${bootstrapProtocol}STATE:
91
92
 
92
93
  SCOPES: Use the narrowest scope: session=branch/run continuation by default; cwd=reusable project truth; global=established cross-project/user/environment knowledge.
93
94
 
94
- READ: Use read_state for concrete scope/retained-history gaps. lazy_navigation lists bounded effective lazy keys, not bodies. Unscoped=effective; effective/global/cwd/session select overlay or owner. Arrays use indices or [start..end]; keys gives structure, patch the intersected change.
95
+ READ: Use read_state for concrete scope/retained-history gaps. lazy_navigation lists bounded effective lazy keys, not bodies. Unscoped=effective; effective/global/cwd/session select overlay or owner. Arrays use indices or [start..end]; keys gives structure, patch the intersected change. ${TASK_DRIVEN_HISTORY}
95
96
 
96
97
  WRITE: patch_state is the sole model-authored semantic mutation mechanism; all supplied scopes are validated and durably accepted as one atomic transition. Call alone in an assistant response; await acceptance. Global/CWD use current canonical values after cancelable lock waiting. Correct repeats succeed without new revisions.
97
98
 
@@ -99,7 +100,7 @@ PATCH: Use global/cwd/session object patches for material updates, not acknowled
99
100
 
100
101
  MEMORY: Treat every patch as reconciliation rather than append-only notes: merge superseded fragments, remove obsolete progress. Preserve commitments, open questions, consequential results and exact continuation; distinguish requirements, decisions, observations, conclusions and hypotheses. Exclude secrets, raw history, transient progress, speculation and unsupported claims; retain decision-relevant uncertainty. Curate touched state; cleanup and scope reviews require an explicit user request. Proven moves use targeted read_state and one atomic multi-scope patch, then verify both owners. External transfers need verified acceptance before deletion. Never invent memory changes.
101
102
 
102
- REFS: State refs use {"$ref":"cwd.lazy.plan"} or \`$cwd.lazy.plan\` in text. Resolve only when needed; infer no authority, hydration, execution, or completion. If that resolution proves a dangling state ref, fix/drop it in owning text; never scan for broken refs.
103
+ REFS: State refs use {"$ref":"cwd.lazy.plan"} or \`$cwd.lazy.plan\` in text. Resolve only when needed; infer no authority, hydration, execution, or completion. Hint paths are current reference owners, not relocated targets or proof of staleness. Fix proven stale refs only as needed; never scan refs or history offsets.
103
104
 
104
105
  ACQUISITION: Read only for a concrete gap, exact source/edit, invalidation, contradiction/failure, or explicit request; changed source fingerprints require rereading.
105
106
  ARTIFACTS: Compile acquired invalidated artifacts at artifacts[exact path] in the reported scope (global/cwd/session), with a description; never relocate or invent global copies. Runtime owns all artifact/Skill provenance.
@@ -171,7 +171,7 @@ function missingReferenceHint(view, path, historyLimit) {
171
171
  return undefined;
172
172
  return [{
173
173
  type: "dangling-reference",
174
- message: `Reconcile the verified current values that reference this path${truncated ? "; additional sources may exist beyond the bounded scan" : ""}.`,
174
+ message: `The requested value is unavailable in the selected state. These current values reference that path, not a verified new location. Use this evidence if relevant to the task${truncated ? "; additional reference owners may exist beyond the bounded scan" : ""}.`,
175
175
  paths: sources.map(({ path: sourcePath }) => sourcePath),
176
176
  }];
177
177
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-state-flow",
3
- "version": "0.19.0",
3
+ "version": "0.19.1",
4
4
  "private": false,
5
5
  "description": "Incremental scoped state/context/memory compiler for Pi, inspired by SKILL.state",
6
6
  "keywords": [
@@ -44,7 +44,9 @@ Example arguments:
44
44
  {"paths":["cwd.working","session.working"]}
45
45
  ```
46
46
 
47
- Unscoped paths use effective state. `cwd[1].working` reads the preceding causal boundary. Materialized-history and scope patch-history paths such as `cwd.patches[1]` share the configured `historyLimit` bound (default 7) and require actually retained history. Lowering the limit folds excess tails without erasing current state; increasing it does not reconstruct discarded history. Array ranges such as `cwd.lazy.checks[0..3]` exclude the endpoint and require existing elements. Missing paths fail: inspect parent keys to verify deletion. Missing history is not empty history. Read `lazy` explicitly. Treat structured `$ref` values and `$`-prefixed `read_state` paths inside ordinary strings, such as `$effective.lazy.memory[7]`, as semantic-state references. Other resources retain their native locators. Resolve any reference through the appropriate read/tool only when needed. Neither form proves authority or existence, hydrates, or executes anything. Never scan or resolve references merely to test them. A missing single value path with exact durable sources returns `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. Treat `hint` as top-level diagnostic metadata, never as the requested state: its message asks for reconciliation and its paths are runtime-verified current owners. The hint proves provenance rather than staleness and is absent when no current durable source matches; keys, patch, and batch reads keep all-or-error behavior. Only then inspect ownership as needed and patch a proven stale owning value while preserving its surrounding meaning. Effective absence, inaccessible external resources, and transient failures are not proof.
47
+ Unscoped paths use effective state. `cwd[1].working` reads the preceding causal boundary. Materialized-history and scope patch-history paths such as `cwd.patches[1]` share the configured `historyLimit` bound (default 7) and require actually retained history. Lowering the limit folds excess tails without erasing current state; increasing it does not reconstruct discarded history. Array ranges such as `cwd.lazy.checks[0..3]` exclude the endpoint and require existing elements. Missing paths are unavailable; inspect parent keys only when needed for the task. Missing history is not empty history. Read `lazy` explicitly. Treat structured `$ref` values and `$`-prefixed `read_state` paths inside ordinary strings, such as `$effective.lazy.memory[7]`, as semantic-state references. Other resources retain their native locators. Resolve any reference through the appropriate read/tool only when needed. Neither form proves authority or existence, hydrates, or executes anything. Never scan or resolve references merely to test them. A missing single value path with exact durable sources returns `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. Treat `hint` as top-level diagnostic metadata, never as the requested state: its message is descriptive and conditional; its paths are runtime-verified current reference owners, not verified new locations of the target. The hint proves provenance rather than staleness and is absent when no current durable source matches; keys, patch, and batch reads keep all-or-error behavior. Only then inspect ownership as needed and patch a proven stale owning value while preserving its surrounding meaning. Effective absence, inaccessible external resources, and transient failures are not proof.
48
+
49
+ Missing paths or runtime hints alone do not require historical search. The agent may choose a targeted historical read when a previous value is useful to the current task, without separate user permission. Otherwise continue without searching. Use found values as historical evidence, not automatically as current state; never automatically restore deleted memory. Do not scan all offsets, hydrate automatically or request repair inference. A hint does not prove prior existence, retained history or relocation. A proven stale reference may be repaired within touched work without resurrecting its target. Automatic state and recent-transition projections omit lazy bodies; bounded `lazy_navigation` preserves structure, and explicit current/historical reads still return requested lazy values or patches.
48
50
 
49
51
  ## Write
50
52
 
@@ -22,9 +22,11 @@ Follow the installed runtime contract. This registered Skill follows its Pi sour
22
22
  1. **Limit the review.** Address the requested scope. A completed phase may motivate recommending cleanup, not starting it without a request. For a whole-state cleanup, inspect global, CWD, and session ownership explicitly; for a narrower request, inspect only affected owners. Use targeted reads for gaps, contradictions, ownership, or verification; do not rerun the project.
23
23
  2. **Classify.** Put user requirements and binding confirmed decisions in `contract`, observations, assistant conclusions, and unresolved work in `working`, chosen actions in `intents`, and inactive reusable detail in `lazy`. Never give an assistant conclusion user authority. Remove fulfilled, abandoned, superseded, or impossible intents; retain consequential results. Possibilities are not commitments.
24
24
  3. **Keep evidence boundaries.** Preserve corrections, prerequisites, bounded negative results, and useful uncertainty. Separate requirements, decisions, observations, conclusions, and hypotheses. Silence is not acceptance; repetition is not verification. One implementation's failure does not reject an approach. Neither freeze provisional methods nor reopen confirmed decisions without grounds.
25
- 4. **Compact for continuation.** Remove duplicates, obsolete progress, unsupported claims, and secrets. Keep sufficient results, real retrieval pointers, pending interaction, and known next checks. Observations are not live external facts. Keep `lazy` shallow and priority-ordered. Recognize optional structured `$ref` values and `$`-prefixed `read_state` paths inside ordinary strings as semantic-state references; other resources retain native locators. No reference form proves authority or existence, authorizes execution, or implies completion. Never scan or resolve references merely to find broken ones. When the bounded review independently needs a reference, a missing single value path with exact durable sources returns `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. Treat the top-level hint as provenance and reconciliation guidance, never as requested state or proof of staleness; its paths are runtime-verified current owners, while no hint does not prove invention. Inspect ownership only as needed, then patch a proven stale owning value while preserving surrounding meaning. Effective absence or external inaccessibility is insufficient.
25
+ 4. **Compact for continuation.** Remove duplicates, obsolete progress, unsupported claims, and secrets. Keep sufficient results, real retrieval pointers, pending interaction, and known next checks. Observations are not live external facts. Keep `lazy` shallow and priority-ordered. Recognize optional structured `$ref` values and `$`-prefixed `read_state` paths inside ordinary strings as semantic-state references; other resources retain native locators. No reference form proves authority or existence, authorizes execution, or implies completion. Never scan or resolve references merely to find broken ones. When the bounded review independently needs a reference, a missing single value path with exact durable sources returns `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. Treat the top-level hint as conditional navigation and provenance, never as requested state or proof of staleness; its paths are runtime-verified current reference owners, not verified new locations of the target, while no hint does not prove invention. Inspect ownership only as needed, then patch a proven stale owning value while preserving surrounding meaning. Effective absence or external inaccessibility is insufficient.
26
26
  5. **Check ownership.** Prefer `session` for branch/run continuation, `cwd` for project knowledge, and `global` for established cross-project knowledge. Effective values do not prove ownership; inspect owners before moves. Broader applicability requires evidence.
27
27
 
28
+ Missing paths or runtime hints alone do not require historical search. The agent may choose a targeted historical read when a previous value is useful to the current task, without separate user permission. Otherwise continue without searching. Use found values as historical evidence, not automatically as current state; never automatically restore deleted memory. Do not scan all offsets, hydrate automatically or request repair inference. A hint does not prove prior existence, retained history or relocation. A proven stale reference may be repaired within touched work without resurrecting its target. Lazy bodies require explicit reads; automatic state/history projections retain navigation without hydrating those bodies.
29
+
28
30
  ## Transfer only when needed
29
31
 
30
32
  Resolve destination conflicts without overwriting stronger or unrelated knowledge. For a proven move between scopes of one State Flow store, inspect both owners, then use one atomic multi-scope `patch_state` for destination and source changes. Verify both owners and effective inheritance afterward; reconcile affected references. A rejected cohort leaves neither side partially accepted.
@@ -41,7 +41,7 @@ Every materialized scope has exactly this shape:
41
41
  - `working` retains verified current facts, unresolved work and exact continuation.
42
42
  - `artifacts` maps exact source paths to compiled routing metadata.
43
43
  - `response` is owned only by the session scope and stores the exact latest accepted assistant answer, including the empty string. Global and CWD retain the required key as an empty structural placeholder so canonical scopes keep one shape; the effective overlay receives `response` only from Session.
44
- - `lazy` is a required object root for ordinary JSON detail, omitted from baseline model state and read explicitly.
44
+ - `lazy` is a required object root for ordinary JSON detail, omitted from baseline model state and read explicitly. Automatic recent-transition projection also removes each whole `patch.lazy`, including deletions. Empty scoped patches and transitions disappear; an empty projected window is omitted. Visible hot patches retain their original identities, order and positions. Canonical history and explicit current/historical reads are unchanged. Bounded lazy navigation remains available without bodies; previously communicated user/tool/response text is not redacted.
45
45
 
46
46
  Effective state recursively overlays:
47
47
 
@@ -250,7 +250,7 @@ The [tested Pi SDK baseline](compatibility.md) chooses or creates `SessionManage
250
250
  {"session":{"intents":{"next":"Verify the corrected behavior"}}}
251
251
  ```
252
252
 
253
- `intents` is the hot plane for active commitments, not requirements, observations, alternatives, or completed plans. Removing an intent does not remove its consequences or any referenced state. Semantic-state references use either the optional structured `{"$ref":"cwd.lazy.plan"}` convention or `$` immediately followed by one valid `read_state` path inside ordinary text, for example `$effective.lazy.memory[7]`. The text prefix distinguishes references from incidental path-like prose and leaves a deterministic seam for possible future parsing. Resource paths, document locators, URIs, Skill identities, and agent identities retain their native syntax. State Flow stores all forms as ordinary JSON and currently does not parse or validate targets. The agent resolves a relevant locator explicitly through `read_state` or the appropriate external tool; presence alone creates no authority, existence proof, dependency, hydration, execution, or completion semantics. Reference repair is reactive: the agent never scans or resolves references merely to test them. Only after one requested value path is missing does the query domain perform one bounded reverse lookup over current model-patchable semantic planes for exact structured `$ref` or `$path` matches. When matches exist, `read_state` returns the explicit diagnostic sentinel `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. `hint` is a top-level sibling rather than state data; its message asks for reconciliation and `paths` contains at most three runtime-verified current owning addresses. The null sentinel is never returned alone for this case. Keys, patch, and multi-path reads keep all-or-error semantics, while no durable match retains the ordinary missing-path error. A match establishes durable semantic provenance, not staleness; no match does not prove invention. The agent may then inspect ownership and patch a proven stale source without discarding surrounding meaning. Effective absence does not establish ownership, and unavailable history, external inaccessibility, or transient read failure does not prove a broken reference.
253
+ `intents` is the hot plane for active commitments, not requirements, observations, alternatives, or completed plans. Removing an intent does not remove its consequences or any referenced state. Semantic-state references use either the optional structured `{"$ref":"cwd.lazy.plan"}` convention or `$` immediately followed by one valid `read_state` path inside ordinary text, for example `$effective.lazy.memory[7]`. The text prefix distinguishes references from incidental path-like prose and leaves a deterministic seam for possible future parsing. Resource paths, document locators, URIs, Skill identities, and agent identities retain their native syntax. State Flow stores all forms as ordinary JSON and currently does not parse or validate targets. The agent resolves a relevant locator explicitly through `read_state` or the appropriate external tool; presence alone creates no authority, existence proof, dependency, hydration, execution, or completion semantics. Reference repair is reactive: the agent never scans or resolves references merely to test them. Only after one requested value path is missing does the query domain perform one bounded reverse lookup over current model-patchable semantic planes for exact structured `$ref` or `$path` matches. When matches exist, `read_state` returns the explicit diagnostic sentinel `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. `hint` is a top-level sibling rather than state data; its message describes unavailability conditionally, and `paths` contains at most three runtime-verified current reference-owner addresses, not verified new locations of the requested data. The hint contains no lazy bodies and does not prove prior existence, retention or relocation. The null sentinel is never returned alone for this case. Keys, patch, and multi-path reads keep all-or-error semantics, while no durable match retains the ordinary missing-path error. A match establishes durable semantic provenance, not staleness; no match does not prove invention. The agent may inspect ownership and patch a proven stale source when useful to the current task, without discarding surrounding meaning or resurrecting its target. Missing paths or hints alone do not require historical search. The agent may independently choose targeted historical reading when a previous value is useful to the current task; no separate user permission is required. Historical values are evidence, not automatically current state or a reason to restore deleted memory. Runtime never scans history for reference owners, triggers repair inference or hydrates lazy bodies. Effective absence does not establish ownership, and unavailable history, external inaccessibility, or transient read failure does not prove a broken reference.
254
254
 
255
255
  `read_state` accepts one unified path. `effective == effective[0]` is the current effective materialization; `global == global[0]` (and CWD/session equivalents) selects that scope at the same composed causal boundary. `global.patches == global.patches[0]` reads the latest accepted retained global patch, with higher patch indices walking only that scope's retained accepted patches. Indices are bounded by the configured `historyLimit`; unavailable pre-origin or pre-tail history is an error. Resolver aliases are not literal JSON containers. Reads stay cached and create no Git query, publication, checkpoint append, or semantic step.
256
256
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  State Flow requires matching `pi-coding-agent`, `pi-agent-core`, `pi-ai`, and `pi-tui` packages at `>=0.87.0`. Keep all four on the same release line. The open-ended peer range permits newer SDK releases; it does not certify them.
6
6
 
7
- The repository-local verified stack is Linux/x64, Node 26.8.1, Git 2.55.0 and Pi SDK 0.87.0. The current release candidate passes 711 tests, typecheck, build, compiled imports and package dry-run. The release workflow uses Node 24; its result is a separate verification gate.
7
+ The repository-local verified stack is Linux/x64, Node 26.8.1, Git 2.55.0 and Pi SDK 0.87.0. Repository validation covers tests, typecheck, build, compiled imports and package dry-run; successful results are bound to the validated source and dependency identities. The release workflow uses Node 24; its result is a separate verification gate.
8
8
 
9
9
  Tests use isolated stores and scripted providers through the real Pi SDK. They do not certify installed Telegram/TUI reachability, live provider behavior, other operating systems, mixed SDK versions or untested newer SDK releases. Detailed behavioral witnesses live in [temporal acceptance](temporal-acceptance.md); benchmark methodology and source-bound results live in [performance](performance.md).
10
10
 
@@ -49,8 +49,8 @@ global | CWD | session
49
49
  `intents`, `contract`, `working`, and `artifacts` remain hot in every scope. Session-owned `response` is also hot; Global and CWD keep only its required empty structural slot, and Effective inherits the Session value. `intents` may keep compact active direction while referring to large supporting detail in `lazy`. `lazy` differs only in projection policy:
50
50
 
51
51
  - It is canonical semantic JSON, validated and versioned with its owning scope.
52
- - It is excluded from the ordinary baseline effective-state body.
53
- - It becomes model-visible only through bounded baseline navigation hints or explicit `read_state` output.
52
+ - Its bodies are excluded from automatic state and recent-transition projections, including lazy writes, replacements and deletions. Empty visible patches/transitions disappear without renumbering history; hot changes remain visible.
53
+ - Bounded baseline navigation exposes presence, path and structure without bodies. Explicit current/historical `read_state` values and patches may contain lazy bodies; already communicated native/user/tool/response text is not redacted.
54
54
  - Reading it does not mutate state, freshness, usage metadata, history, or future context.
55
55
 
56
56
  ### Semantic references
@@ -59,7 +59,9 @@ A reference is semantic content, not a runtime type. The optional `{"$ref":"cwd.
59
59
 
60
60
  State Flow preserves all forms exactly as ordinary JSON. It does not scan prose, index targets, validate existence, rewrite relative locators, or infer authority, dependency, hydration, execution, or completion. When a reference matters, the agent resolves it explicitly with `read_state` for semantic paths or the appropriate external read/tool for other resources. A locator supports retrieval but does not replace content required for the current decision.
61
61
 
62
- Reference repair is reactive, not a maintenance scan. The agent does not enumerate, audit, or resolve references merely to test them. Only after one requested `read_state` value path is missing does State Flow perform one bounded reverse lookup over current model-patchable semantic planes for exact structured `$ref` and `$path` matches. If found, the tool returns `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. `hint` is explicit top-level metadata rather than state data; its action message asks for reconciliation and its path array contains at most three runtime-verified current owners. The null sentinel is never returned alone for this case. Keys, patch, and multi-path reads keep ordinary all-or-error semantics; no durable match retains the missing-path error and does not prove the agent invented the path. The agent may then reconcile a proven stale owning value while preserving surrounding meaning. This applies equally to `$ref` objects and contextual references in prose. Effective-state absence alone does not identify the owner, and unavailable history, inaccessible external resources, or transient read failure do not prove that a durable reference is broken.
62
+ Reference repair is reactive, not a maintenance scan. The agent does not enumerate, audit, or resolve references merely to test them. Only after one requested `read_state` value path is missing does State Flow perform one bounded reverse lookup over current model-patchable semantic planes for exact structured `$ref` and `$path` matches. If found, the tool returns `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. `hint` is explicit top-level metadata rather than state data; its conditional message describes unavailability, and its path array contains at most three runtime-verified current reference owners, not verified new locations of the target. The hint contains no lazy bodies and proves neither prior existence, retention nor relocation. The null sentinel is never returned alone for this case. Keys, patch, and multi-path reads keep ordinary all-or-error semantics; no durable match retains the missing-path error and does not prove the agent invented the path. The agent may then reconcile a proven stale owning value while preserving surrounding meaning. This applies equally to `$ref` objects and contextual references in prose. Effective-state absence alone does not identify the owner, and unavailable history, inaccessible external resources, or transient read failure do not prove that a durable reference is broken.
63
+
64
+ Missing paths or runtime hints alone do not require historical search. The agent may choose a targeted historical read when a previous value is useful to the current task, without separate user permission; otherwise continue without searching. Found values are historical evidence, not automatically current memory. Never automatically restore deleted data, scan all offsets, hydrate bodies or trigger repair inference. The reverse lookup searches current reference owners only, never history. A proven stale reference can be repaired within touched work without resurrecting its target.
63
65
 
64
66
  The `lazy` root must be an object. Its nested values may include arrays, objects, and scalars, for example:
65
67
 
@@ -126,7 +128,7 @@ There are three projections:
126
128
  | `keys` | `{ "meta": ..., "keys": ... }` | Minimal structural facts followed by immediate keys |
127
129
  | `patch` | `{ "patch": ... }` | Historical semantic patch at the selected boundary |
128
130
 
129
- A single-path request returns one payload. A multi-path request returns positionally aligned arrays under the same projection fields. One missing value path with exact current durable references instead returns `{ "value": null, "hint": [{ "type": "dangling-reference", "message": "Reconcile the verified current values that reference this path.", "paths": ["cwd.working.note"] }] }`; this explicit sentinel is diagnostic metadata, not semantic state.
131
+ A single-path request returns one payload. A multi-path request returns positionally aligned arrays under the same projection fields. One missing value path with exact current durable references instead returns `{ "value": null, "hint": [{ "type": "dangling-reference", "message": "The requested value is unavailable in the selected state. These current values reference that path, not a verified new location. Use this evidence if relevant to the task.", "paths": ["cwd.working.note"] }] }`; this explicit sentinel is diagnostic metadata, not semantic state.
130
132
 
131
133
  `value` otherwise deliberately mirrors the effective-state snapshot injected at iteration start: it is semantic state without revision, provenance, range, transport, or storage fields. `patch` likewise contains only the selected semantic patch. Only structural discovery earns `meta`, and `keys` remains the final and most valuable field in that response.
132
134
 
@@ -44,6 +44,8 @@ This is a maintained property-to-test map for the current canonical-file contrac
44
44
  38. **Stop cannot manufacture a restoration failure:** Held-store retained-boundary and auto-start fixtures require repeated Stop to return promptly without cancelling memory acceptance, adding an error fence or publishing early. Release accepts the selected/initial memory with passive policy, permits passive patches and retains them across reload. Stop→Start while waiting activates only after memory acceptance. A separate Start-owned attachment witness withdraws the Start waiter without cancelling restoration. The native SDK tree witness invokes `/state-flow-stop` during awaited `navigateTree`, then verifies selected private memory, passive tool availability and a successful next-provider patch; selected conversation remains visible and later-branch private memory stays absent. This public SDK route is not installed Telegram/TUI reachability certification.
45
45
  39. **Native Skill compilation reconciles an independent writer without private leakage:** The Global/CWD × duplicate/competing/invalid matrix runs real Pi acquisition and compiler tool calls while a separate process publishes between the model's source read and its patch. Identical compiler output leaves shared checkpoint/tail/provenance bytes, scope revision and runtime step unchanged. Different output replaces the complete artifact and matching source-hash/compiler evidence, preserves independent peer fields, and advances the affected revision once. The next provider sees adopted shared state and local private memory, never the peer's private sentinel; all five peer-private files remain unchanged. An invalid compilation combined with a Session mutation rejects without changing any captured canonical file or accepting the accompanying Session field. The peer uses the runtime publication API, not a second provider; these ordered interleavings supplement the separate held-writer cancellation tests.
46
46
  40. **A public SDK host can control a child while fork binding awaits memory:** The fixture observes the public `createAgentSession` result before awaiting `bindExtensions`, without private SDK hooks or direct calls to State Flow command handlers. During a held-store `runtime.fork`, it calls the child's public `prompt('/state-flow-stop')`; an optional subsequent Start waits for memory acceptance. Stop returns while the fork remains pending. After release, the child has a distinct identity, selected private memory and the requested passive/active policy. Its next provider sees selected rather than later-parent private state, successfully patches child memory and leaves all parent-private files unchanged. This certifies the embedding route on the tested SDK, not whether the installed CLI or Telegram exposes that child before its runtime replacement completes.
47
+ 41. **Automatic history does not hydrate lazy memory:** Context tests cover large writes, replacements and deletions in Global/CWD/Session, mixed hot/lazy cohorts, empty scoped patches/transitions and omission of an empty window. Visible records retain their identities, order and original positions; artifact evidence is still hidden. Native SDK active/bootstrap/reload/Stop→Start witnesses keep lazy bodies out of State Flow-owned automatic blocks while retained canonical files still contain them. Current tool trajectory and unfinished bootstrap retain previously communicated bodies. Semantic files remain byte-identical through projection/preparation, and no hydration or repair inference is added. The four native mode witnesses fail against the unfiltered projection in an isolated source copy.
48
+ 42. **Hints do not create a recovery task:** Query tests preserve single-value hint conditions, current-only reference-owner lookup, no body disclosure and existing keys/patch/batch/unavailable-history behavior. Active/passive native witnesses compare exact canonical bytes and checkpoint counts around hints and reads, and require the exact scripted tool and provider-call counts. A task that needs no old detail performs no historical read; a task that needs it explicitly reads the exact retained Global/CWD/Session values without separate permission or restoring deleted data. Protocol and both Skill tests enforce this permission and boundary. Native provider assertions have completion sentinels outside the provider callbacks so a swallowed scripted provider error cannot produce a false pass. These are runtime/contract witnesses, not a claim about every model's discretionary behavior.
47
49
 
48
50
  ## Additional preservation boundaries
49
51
 
@@ -141,6 +141,16 @@ Fatal process termination can leave an incomplete canonical file cohort. Before
141
141
 
142
142
  Independently valid shared streams may require a fresh composed origin without inventing cross-writer history. Authored patches use that current basis; raw precomputed replay still refuses an advanced target instead of applying stale normalized changes. Rollback restores only bytes still matching that publisher's output and preserves detected external changes. See [performance evidence](performance.md) for measured contention and the [acceptance map](temporal-acceptance.md) for the tested boundaries; the [backlog](../BACKLOG.md) owns open implementation work.
143
143
 
144
+ ## Lazy navigation and historical reading
145
+
146
+ Lazy bodies require explicit reads. Automatic state and recent-transition projections omit them, including lazy deletions; bounded `lazy_navigation` can still show the current layer's presence, path and key types. Explicit `session.lazy.releasePlan` reads the current value, while `session[3].lazy.releasePlan` reads the exact older value only if that causal boundary remains available. Filtering automatic visibility does not renumber history or erase already communicated native/user/tool/response text.
147
+
148
+ A missing path or runtime hint does not by itself require historical search. If the old value is unnecessary, continue without searching. If it can help the current task, the agent may choose a targeted historical read without separate user permission. Treat any found value as historical evidence, not automatically as current memory; do not restore deleted data without an independent reason. Do not scan all offsets or use repair inference or automatic hydration.
149
+
150
+ A dangling-reference hint accompanies only an unresolved single value read with verified current reference sources. Its `paths` are the owners of those references, not verified new locations of the requested data. It does not prove that the target existed, remains retained or was moved. The bounded lookup searches current state only and emits no lazy bodies. A proven stale reference may be repaired within touched work without resurrecting its target. Without a match, ordinary missing-path errors remain; keys, patch and batch projections retain their existing contracts.
151
+
152
+ Artifact freshness/invalidations and optional Skill acquisition hints keep their exact source/scope targets. Hints expose possibilities and diagnostic evidence; the current task determines whether action is necessary.
153
+
144
154
  ## Memory and source acquisition
145
155
 
146
156
  The agent should use sufficient materialized knowledge before rereading files. Read for a concrete gap, exact-source/edit operation, evidenced invalidation, contradiction/failure, explicit request, or bounded maintenance—not simply because a new session began.
@@ -107,6 +107,7 @@ export function passiveContinuationMessages(messages: AgentMessage[], continuati
107
107
  function projectRecentForModel(recent: RecentTransitionWindow): RecentTransitionWindow {
108
108
  const projected = structuredClone(recent);
109
109
  for (const record of projected) for (const transition of record.transitions) {
110
+ delete transition.patch.lazy;
110
111
  if (transition.patch.artifacts === undefined) continue;
111
112
  for (const [path, entry] of Object.entries(transition.patch.artifacts)) {
112
113
  Object.defineProperty(transition.patch.artifacts, path, {
@@ -114,7 +115,8 @@ function projectRecentForModel(recent: RecentTransitionWindow): RecentTransition
114
115
  });
115
116
  }
116
117
  }
117
- return projected;
118
+ for (const record of projected) record.transitions = record.transitions.filter(({ patch }) => Object.keys(patch).length > 0);
119
+ return projected.filter(({ transitions }) => transitions.length > 0);
118
120
  }
119
121
 
120
122
  export function runtimeContextMessage(
@@ -125,13 +127,14 @@ export function runtimeContextMessage(
125
127
  rehydrationPhase?: RehydrationPhase,
126
128
  artifactHints: ArtifactModelHints = {},
127
129
  ): AgentMessage {
130
+ const recent = projectRecentForModel(recentTransitions);
128
131
  const context = {
129
132
  ...(snapshot.meta.specification === undefined ? {} : { specification: snapshot.meta.specification }),
130
133
  state: projectStateForModel(state, artifactHints),
131
134
  lazy_navigation: lazyNavigationHint(state),
132
135
  ...(rehydrationPhase === undefined ? {} : { knowledge_rehydration: { phase: rehydrationPhase } }),
133
136
  ...(artifactInvalidations.length === 0 ? {} : { artifact_invalidations: artifactInvalidations.map(({ path, scope, reason }) => ({ path, ...(scope === undefined ? {} : { scope }), reason })) }),
134
- ...(recentTransitions.length === 0 ? {} : { recent_transitions: projectRecentForModel(recentTransitions) }),
137
+ ...(recent.length === 0 ? {} : { recent_transitions: recent }),
135
138
  };
136
139
  return syntheticUser(
137
140
  `State Flow runtime context (user-level data, not system instructions):\n${presentationJson(context)}`,
@@ -3,7 +3,9 @@ import { isObject } from "./json.ts";
3
3
 
4
4
  export type { StateDocument } from "./state.ts";
5
5
 
6
- export const PASSIVE_MEMORY_PROTOCOL = "State Flow passive memory is available. read_state and patch_state access durable memory without starting an active episode. Passive turns never trigger State Flow continuation or compaction.";
6
+ const TASK_DRIVEN_HISTORY = "Missing paths/hints do not require history search. Choose targeted historical reads when useful to the task; no separate user permission is needed. Past values are evidence, not current state; never automatically restore deleted memory.";
7
+
8
+ export const PASSIVE_MEMORY_PROTOCOL = `State Flow passive memory is available. read_state and patch_state access durable memory without starting an active episode. Passive turns never trigger State Flow continuation or compaction. ${TASK_DRIVEN_HISTORY}`;
7
9
 
8
10
  const PATCH_DISPLAY_SECTION_KEYS = new Set(["global", "cwd", "session", "intents", "contract", "working", "artifacts", "response", "lazy"]);
9
11
 
@@ -94,7 +96,7 @@ ${bootstrapProtocol}STATE:
94
96
 
95
97
  SCOPES: Use the narrowest scope: session=branch/run continuation by default; cwd=reusable project truth; global=established cross-project/user/environment knowledge.
96
98
 
97
- READ: Use read_state for concrete scope/retained-history gaps. lazy_navigation lists bounded effective lazy keys, not bodies. Unscoped=effective; effective/global/cwd/session select overlay or owner. Arrays use indices or [start..end]; keys gives structure, patch the intersected change.
99
+ READ: Use read_state for concrete scope/retained-history gaps. lazy_navigation lists bounded effective lazy keys, not bodies. Unscoped=effective; effective/global/cwd/session select overlay or owner. Arrays use indices or [start..end]; keys gives structure, patch the intersected change. ${TASK_DRIVEN_HISTORY}
98
100
 
99
101
  WRITE: patch_state is the sole model-authored semantic mutation mechanism; all supplied scopes are validated and durably accepted as one atomic transition. Call alone in an assistant response; await acceptance. Global/CWD use current canonical values after cancelable lock waiting. Correct repeats succeed without new revisions.
100
102
 
@@ -102,7 +104,7 @@ PATCH: Use global/cwd/session object patches for material updates, not acknowled
102
104
 
103
105
  MEMORY: Treat every patch as reconciliation rather than append-only notes: merge superseded fragments, remove obsolete progress. Preserve commitments, open questions, consequential results and exact continuation; distinguish requirements, decisions, observations, conclusions and hypotheses. Exclude secrets, raw history, transient progress, speculation and unsupported claims; retain decision-relevant uncertainty. Curate touched state; cleanup and scope reviews require an explicit user request. Proven moves use targeted read_state and one atomic multi-scope patch, then verify both owners. External transfers need verified acceptance before deletion. Never invent memory changes.
104
106
 
105
- REFS: State refs use {"$ref":"cwd.lazy.plan"} or \`$cwd.lazy.plan\` in text. Resolve only when needed; infer no authority, hydration, execution, or completion. If that resolution proves a dangling state ref, fix/drop it in owning text; never scan for broken refs.
107
+ REFS: State refs use {"$ref":"cwd.lazy.plan"} or \`$cwd.lazy.plan\` in text. Resolve only when needed; infer no authority, hydration, execution, or completion. Hint paths are current reference owners, not relocated targets or proof of staleness. Fix proven stale refs only as needed; never scan refs or history offsets.
106
108
 
107
109
  ACQUISITION: Read only for a concrete gap, exact source/edit, invalidation, contradiction/failure, or explicit request; changed source fingerprints require rereading.
108
110
  ARTIFACTS: Compile acquired invalidated artifacts at artifacts[exact path] in the reported scope (global/cwd/session), with a description; never relocate or invent global copies. Runtime owns all artifact/Skill provenance.
@@ -187,7 +187,7 @@ function missingReferenceHint(view: TemporalState, path: string, historyLimit: n
187
187
  if (sources.length === 0) return undefined;
188
188
  return [{
189
189
  type: "dangling-reference",
190
- message: `Reconcile the verified current values that reference this path${truncated ? "; additional sources may exist beyond the bounded scan" : ""}.`,
190
+ message: `The requested value is unavailable in the selected state. These current values reference that path, not a verified new location. Use this evidence if relevant to the task${truncated ? "; additional reference owners may exist beyond the bounded scan" : ""}.`,
191
191
  paths: sources.map(({ path: sourcePath }) => sourcePath),
192
192
  }];
193
193
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-state-flow",
3
- "version": "0.19.0",
3
+ "version": "0.19.1",
4
4
  "private": false,
5
5
  "description": "Incremental scoped state/context/memory compiler for Pi, inspired by SKILL.state",
6
6
  "keywords": [
@@ -44,7 +44,9 @@ Example arguments:
44
44
  {"paths":["cwd.working","session.working"]}
45
45
  ```
46
46
 
47
- Unscoped paths use effective state. `cwd[1].working` reads the preceding causal boundary. Materialized-history and scope patch-history paths such as `cwd.patches[1]` share the configured `historyLimit` bound (default 7) and require actually retained history. Lowering the limit folds excess tails without erasing current state; increasing it does not reconstruct discarded history. Array ranges such as `cwd.lazy.checks[0..3]` exclude the endpoint and require existing elements. Missing paths fail: inspect parent keys to verify deletion. Missing history is not empty history. Read `lazy` explicitly. Treat structured `$ref` values and `$`-prefixed `read_state` paths inside ordinary strings, such as `$effective.lazy.memory[7]`, as semantic-state references. Other resources retain their native locators. Resolve any reference through the appropriate read/tool only when needed. Neither form proves authority or existence, hydrates, or executes anything. Never scan or resolve references merely to test them. A missing single value path with exact durable sources returns `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. Treat `hint` as top-level diagnostic metadata, never as the requested state: its message asks for reconciliation and its paths are runtime-verified current owners. The hint proves provenance rather than staleness and is absent when no current durable source matches; keys, patch, and batch reads keep all-or-error behavior. Only then inspect ownership as needed and patch a proven stale owning value while preserving its surrounding meaning. Effective absence, inaccessible external resources, and transient failures are not proof.
47
+ Unscoped paths use effective state. `cwd[1].working` reads the preceding causal boundary. Materialized-history and scope patch-history paths such as `cwd.patches[1]` share the configured `historyLimit` bound (default 7) and require actually retained history. Lowering the limit folds excess tails without erasing current state; increasing it does not reconstruct discarded history. Array ranges such as `cwd.lazy.checks[0..3]` exclude the endpoint and require existing elements. Missing paths are unavailable; inspect parent keys only when needed for the task. Missing history is not empty history. Read `lazy` explicitly. Treat structured `$ref` values and `$`-prefixed `read_state` paths inside ordinary strings, such as `$effective.lazy.memory[7]`, as semantic-state references. Other resources retain their native locators. Resolve any reference through the appropriate read/tool only when needed. Neither form proves authority or existence, hydrates, or executes anything. Never scan or resolve references merely to test them. A missing single value path with exact durable sources returns `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. Treat `hint` as top-level diagnostic metadata, never as the requested state: its message is descriptive and conditional; its paths are runtime-verified current reference owners, not verified new locations of the target. The hint proves provenance rather than staleness and is absent when no current durable source matches; keys, patch, and batch reads keep all-or-error behavior. Only then inspect ownership as needed and patch a proven stale owning value while preserving its surrounding meaning. Effective absence, inaccessible external resources, and transient failures are not proof.
48
+
49
+ Missing paths or runtime hints alone do not require historical search. The agent may choose a targeted historical read when a previous value is useful to the current task, without separate user permission. Otherwise continue without searching. Use found values as historical evidence, not automatically as current state; never automatically restore deleted memory. Do not scan all offsets, hydrate automatically or request repair inference. A hint does not prove prior existence, retained history or relocation. A proven stale reference may be repaired within touched work without resurrecting its target. Automatic state and recent-transition projections omit lazy bodies; bounded `lazy_navigation` preserves structure, and explicit current/historical reads still return requested lazy values or patches.
48
50
 
49
51
  ## Write
50
52
 
@@ -22,9 +22,11 @@ Follow the installed runtime contract. This registered Skill follows its Pi sour
22
22
  1. **Limit the review.** Address the requested scope. A completed phase may motivate recommending cleanup, not starting it without a request. For a whole-state cleanup, inspect global, CWD, and session ownership explicitly; for a narrower request, inspect only affected owners. Use targeted reads for gaps, contradictions, ownership, or verification; do not rerun the project.
23
23
  2. **Classify.** Put user requirements and binding confirmed decisions in `contract`, observations, assistant conclusions, and unresolved work in `working`, chosen actions in `intents`, and inactive reusable detail in `lazy`. Never give an assistant conclusion user authority. Remove fulfilled, abandoned, superseded, or impossible intents; retain consequential results. Possibilities are not commitments.
24
24
  3. **Keep evidence boundaries.** Preserve corrections, prerequisites, bounded negative results, and useful uncertainty. Separate requirements, decisions, observations, conclusions, and hypotheses. Silence is not acceptance; repetition is not verification. One implementation's failure does not reject an approach. Neither freeze provisional methods nor reopen confirmed decisions without grounds.
25
- 4. **Compact for continuation.** Remove duplicates, obsolete progress, unsupported claims, and secrets. Keep sufficient results, real retrieval pointers, pending interaction, and known next checks. Observations are not live external facts. Keep `lazy` shallow and priority-ordered. Recognize optional structured `$ref` values and `$`-prefixed `read_state` paths inside ordinary strings as semantic-state references; other resources retain native locators. No reference form proves authority or existence, authorizes execution, or implies completion. Never scan or resolve references merely to find broken ones. When the bounded review independently needs a reference, a missing single value path with exact durable sources returns `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. Treat the top-level hint as provenance and reconciliation guidance, never as requested state or proof of staleness; its paths are runtime-verified current owners, while no hint does not prove invention. Inspect ownership only as needed, then patch a proven stale owning value while preserving surrounding meaning. Effective absence or external inaccessibility is insufficient.
25
+ 4. **Compact for continuation.** Remove duplicates, obsolete progress, unsupported claims, and secrets. Keep sufficient results, real retrieval pointers, pending interaction, and known next checks. Observations are not live external facts. Keep `lazy` shallow and priority-ordered. Recognize optional structured `$ref` values and `$`-prefixed `read_state` paths inside ordinary strings as semantic-state references; other resources retain native locators. No reference form proves authority or existence, authorizes execution, or implies completion. Never scan or resolve references merely to find broken ones. When the bounded review independently needs a reference, a missing single value path with exact durable sources returns `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. Treat the top-level hint as conditional navigation and provenance, never as requested state or proof of staleness; its paths are runtime-verified current reference owners, not verified new locations of the target, while no hint does not prove invention. Inspect ownership only as needed, then patch a proven stale owning value while preserving surrounding meaning. Effective absence or external inaccessibility is insufficient.
26
26
  5. **Check ownership.** Prefer `session` for branch/run continuation, `cwd` for project knowledge, and `global` for established cross-project knowledge. Effective values do not prove ownership; inspect owners before moves. Broader applicability requires evidence.
27
27
 
28
+ Missing paths or runtime hints alone do not require historical search. The agent may choose a targeted historical read when a previous value is useful to the current task, without separate user permission. Otherwise continue without searching. Use found values as historical evidence, not automatically as current state; never automatically restore deleted memory. Do not scan all offsets, hydrate automatically or request repair inference. A hint does not prove prior existence, retained history or relocation. A proven stale reference may be repaired within touched work without resurrecting its target. Lazy bodies require explicit reads; automatic state/history projections retain navigation without hydrating those bodies.
29
+
28
30
  ## Transfer only when needed
29
31
 
30
32
  Resolve destination conflicts without overwriting stronger or unrelated knowledge. For a proven move between scopes of one State Flow store, inspect both owners, then use one atomic multi-scope `patch_state` for destination and source changes. Verify both owners and effective inheritance afterward; reconcile affected references. A rejected cohort leaves neither side partially accepted.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-kit",
3
- "version": "0.23.1",
3
+ "version": "0.23.2",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -37,14 +37,15 @@
37
37
  "AGENTS.md",
38
38
  "BACKLOG.md",
39
39
  "CHANGELOG.md",
40
- "LICENSE"
40
+ "LICENSE",
41
+ "banner.jpg"
41
42
  ],
42
43
  "dependencies": {
43
44
  "@llblab/pi-actors": "0.53.2",
44
45
  "@llblab/pi-clean-room": "0.2.0",
45
46
  "@llblab/pi-codex-usage": "0.10.0",
46
47
  "@llblab/pi-grow-loop": "0.8.2",
47
- "@llblab/pi-state-flow": "0.19.0",
48
+ "@llblab/pi-state-flow": "0.19.1",
48
49
  "@llblab/pi-telegram": "0.51.4",
49
50
  "@llblab/skills": "1.15.0"
50
51
  },
@@ -72,7 +73,8 @@
72
73
  "./node_modules/@llblab/pi-state-flow/dist/skills",
73
74
  "./node_modules/@llblab/pi-telegram/dist/skills",
74
75
  "./node_modules/@llblab/skills/"
75
- ]
76
+ ],
77
+ "image": "https://raw.githubusercontent.com/llblab/pi-kit/main/banner.jpg"
76
78
  },
77
79
  "bundleDependencies": [
78
80
  "@llblab/pi-actors",