@llblab/pi-kit 0.18.2 → 0.19.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.
- package/CHANGELOG.md +6 -0
- package/README.md +3 -1
- package/node_modules/@llblab/pi-state-flow/AGENTS.md +35 -37
- package/node_modules/@llblab/pi-state-flow/BACKLOG.md +5 -3
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +19 -1
- package/node_modules/@llblab/pi-state-flow/README.md +102 -48
- package/node_modules/@llblab/pi-state-flow/dist/index.d.ts +6 -9
- package/node_modules/@llblab/pi-state-flow/dist/index.js +6 -9
- package/node_modules/@llblab/pi-state-flow/dist/lib/acquisition.d.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/acquisition.js +21 -8
- package/node_modules/@llblab/pi-state-flow/dist/lib/artifact.d.ts +40 -24
- package/node_modules/@llblab/pi-state-flow/dist/lib/artifact.js +93 -63
- package/node_modules/@llblab/pi-state-flow/dist/lib/compaction.d.ts +4 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/compaction.js +9 -9
- package/node_modules/@llblab/pi-state-flow/dist/lib/config.d.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/config.js +6 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/context.d.ts +8 -7
- package/node_modules/@llblab/pi-state-flow/dist/lib/context.js +56 -58
- package/node_modules/@llblab/pi-state-flow/dist/lib/continuation.js +12 -24
- package/node_modules/@llblab/pi-state-flow/dist/lib/durable.d.ts +7 -18
- package/node_modules/@llblab/pi-state-flow/dist/lib/durable.js +47 -78
- package/node_modules/@llblab/pi-state-flow/dist/lib/extension.d.ts +4 -6
- package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +241 -437
- package/node_modules/@llblab/pi-state-flow/dist/lib/git.d.ts +2 -72
- package/node_modules/@llblab/pi-state-flow/dist/lib/git.js +120 -499
- package/node_modules/@llblab/pi-state-flow/dist/lib/history.d.ts +2 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/history.js +4 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/json.d.ts +3 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/json.js +43 -22
- package/node_modules/@llblab/pi-state-flow/dist/lib/logging.d.ts +1 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/logging.js +0 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/memory.d.ts +1 -14
- package/node_modules/@llblab/pi-state-flow/dist/lib/memory.js +5 -37
- package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.d.ts +1 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.js +13 -32
- package/node_modules/@llblab/pi-state-flow/dist/lib/query.d.ts +6 -6
- package/node_modules/@llblab/pi-state-flow/dist/lib/query.js +25 -21
- package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.d.ts +3 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.js +15 -12
- package/node_modules/@llblab/pi-state-flow/dist/lib/rehydration.d.ts +2 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/rehydration.js +5 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.d.ts +26 -88
- package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.js +159 -255
- package/node_modules/@llblab/pi-state-flow/dist/lib/skills.d.ts +0 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/skills.js +1 -47
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.d.ts +16 -33
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.js +48 -137
- package/node_modules/@llblab/pi-state-flow/dist/lib/state.d.ts +16 -11
- package/node_modules/@llblab/pi-state-flow/dist/lib/state.js +13 -14
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.d.ts +1 -9
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.js +15 -43
- package/node_modules/@llblab/pi-state-flow/dist/lib/storage.d.ts +5 -9
- package/node_modules/@llblab/pi-state-flow/dist/lib/storage.js +13 -45
- package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.js +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.d.ts +15 -7
- package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.js +104 -24
- package/node_modules/@llblab/pi-state-flow/dist/lib/transition.d.ts +0 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/transition.js +11 -14
- package/node_modules/@llblab/pi-state-flow/dist/package.json +9 -6
- package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-guide/SKILL.md +11 -17
- package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-memory/SKILL.md +8 -8
- package/node_modules/@llblab/pi-state-flow/docs/README.md +2 -2
- package/node_modules/@llblab/pi-state-flow/docs/architecture.md +64 -67
- package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +24 -6
- package/node_modules/@llblab/pi-state-flow/docs/filesystem-recovery.md +12 -15
- package/node_modules/@llblab/pi-state-flow/docs/fork-contract.md +22 -27
- package/node_modules/@llblab/pi-state-flow/docs/lazy-state.md +25 -41
- package/node_modules/@llblab/pi-state-flow/docs/performance.md +38 -421
- package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +33 -46
- package/node_modules/@llblab/pi-state-flow/docs/usage.md +37 -61
- package/node_modules/@llblab/pi-state-flow/index.ts +7 -71
- package/node_modules/@llblab/pi-state-flow/lib/acquisition.ts +26 -11
- package/node_modules/@llblab/pi-state-flow/lib/artifact.ts +116 -88
- package/node_modules/@llblab/pi-state-flow/lib/compaction.ts +12 -10
- package/node_modules/@llblab/pi-state-flow/lib/config.ts +6 -6
- package/node_modules/@llblab/pi-state-flow/lib/context.ts +52 -59
- package/node_modules/@llblab/pi-state-flow/lib/continuation.ts +11 -20
- package/node_modules/@llblab/pi-state-flow/lib/durable.ts +44 -86
- package/node_modules/@llblab/pi-state-flow/lib/extension.ts +237 -460
- package/node_modules/@llblab/pi-state-flow/lib/git.ts +110 -552
- package/node_modules/@llblab/pi-state-flow/lib/history.ts +4 -3
- package/node_modules/@llblab/pi-state-flow/lib/json.ts +39 -23
- package/node_modules/@llblab/pi-state-flow/lib/logging.ts +1 -7
- package/node_modules/@llblab/pi-state-flow/lib/memory.ts +5 -44
- package/node_modules/@llblab/pi-state-flow/lib/protocol.ts +14 -25
- package/node_modules/@llblab/pi-state-flow/lib/query.ts +26 -22
- package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +17 -11
- package/node_modules/@llblab/pi-state-flow/lib/rehydration.ts +7 -5
- package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +154 -254
- package/node_modules/@llblab/pi-state-flow/lib/skills.ts +1 -49
- package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +58 -142
- package/node_modules/@llblab/pi-state-flow/lib/state.ts +27 -19
- package/node_modules/@llblab/pi-state-flow/lib/status.ts +16 -54
- package/node_modules/@llblab/pi-state-flow/lib/storage.ts +12 -40
- package/node_modules/@llblab/pi-state-flow/lib/telegram.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +104 -22
- package/node_modules/@llblab/pi-state-flow/lib/transition.ts +16 -26
- package/node_modules/@llblab/pi-state-flow/package.json +9 -6
- package/node_modules/@llblab/pi-state-flow/skills/state-flow-guide/SKILL.md +11 -17
- package/node_modules/@llblab/pi-state-flow/skills/state-flow-memory/SKILL.md +8 -8
- package/package.json +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/discovery.d.ts +0 -21
- package/node_modules/@llblab/pi-state-flow/dist/lib/discovery.js +0 -125
- package/node_modules/@llblab/pi-state-flow/dist/lib/maintenance.d.ts +0 -36
- package/node_modules/@llblab/pi-state-flow/dist/lib/maintenance.js +0 -98
- package/node_modules/@llblab/pi-state-flow/dist/lib/migration.d.ts +0 -13
- package/node_modules/@llblab/pi-state-flow/dist/lib/migration.js +0 -167
- package/node_modules/@llblab/pi-state-flow/dist/lib/publication.d.ts +0 -86
- package/node_modules/@llblab/pi-state-flow/dist/lib/publication.js +0 -437
- package/node_modules/@llblab/pi-state-flow/lib/discovery.ts +0 -133
- package/node_modules/@llblab/pi-state-flow/lib/maintenance.ts +0 -147
- package/node_modules/@llblab/pi-state-flow/lib/migration.ts +0 -171
- package/node_modules/@llblab/pi-state-flow/lib/publication.ts +0 -458
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
# Pi SDK compatibility
|
|
2
2
|
|
|
3
|
-
State Flow requires matching Pi SDK packages at `>=0.
|
|
3
|
+
State Flow requires matching Pi SDK packages at `>=0.87.0` without an upper peer-dependency bound. Keep `pi-coding-agent`, `pi-agent-core`, `pi-ai`, and `pi-tui` on the same release line.
|
|
4
4
|
|
|
5
5
|
The peer range permits newer releases so npm does not impose an artificial ceiling. It does not claim that every future SDK release has been tested. Revalidate the public host seams below when adopting a new Pi release line.
|
|
6
6
|
|
|
7
7
|
## Tested stacks
|
|
8
8
|
|
|
9
|
-
The current repository-local stack uses Linux/x64, Node 26.8.1, Git 2.55.0, and Pi SDK 0.
|
|
9
|
+
The current repository-local stack uses Linux/x64, Node 26.8.1, Git 2.55.0, and Pi SDK 0.87.0.
|
|
10
10
|
|
|
11
11
|
| Pi SDK stack | Validation | Evidence status |
|
|
12
12
|
| --- | --- | --- |
|
|
13
|
-
| 0.
|
|
14
|
-
| 0.
|
|
13
|
+
| 0.87.0 | Build, typecheck, import, package dry-run, 438/438 tests | Current full-suite baseline |
|
|
14
|
+
| 0.84.4 | Historical full-suite baseline | Unsupported by State Flow 0.17.0 |
|
|
15
|
+
| 0.85.1 | Historical full-suite baseline | Unsupported by State Flow 0.17.0 |
|
|
15
16
|
|
|
16
17
|
Only exact matching stacks that were actually exercised are test evidence. Mixed SDK versions and untested newer releases are permitted by package metadata but remain unverified.
|
|
17
18
|
|
|
@@ -21,14 +22,29 @@ State Flow depends on these public Pi SDK behaviors:
|
|
|
21
22
|
|
|
22
23
|
- Extension lifecycle events and branch metadata for start, stop, reload, resume, fork, and tree navigation.
|
|
23
24
|
- Read-only session parent traversal through `getLeafEntry()` and `getEntry(id)`.
|
|
24
|
-
- `message_end` and `
|
|
25
|
-
-
|
|
25
|
+
- `message_end`, actionable `turn_end`, `agent_before_settle`, and `agent_settled` ordering around accepted assistant messages.
|
|
26
|
+
- Canonical session context, `ContextEditEntry`, ordinary context transformation, and `context_with_system` extension boundaries.
|
|
26
27
|
- `getContextUsage()` and native compaction hooks.
|
|
27
28
|
- Sequential tool execution and tool-call preflight.
|
|
28
29
|
- Session replacement awaiting outgoing shutdown before invalidation.
|
|
29
30
|
|
|
30
31
|
Compatibility with those seams does not prove every UI mode, provider, operating system, extension combination, or future SDK release.
|
|
31
32
|
|
|
33
|
+
## Pi 0.87.0 feature applicability
|
|
34
|
+
|
|
35
|
+
This inventory follows the [tagged release](https://github.com/earendil-works/pi/releases/tag/v0.87.0), its linked [extension contract](https://github.com/earendil-works/pi/blob/v0.87.0/packages/coding-agent/docs/extensions.md), [session format](https://github.com/earendil-works/pi/blob/v0.87.0/packages/coding-agent/docs/session-format.md) and [image limits](https://github.com/earendil-works/pi/blob/v0.87.0/packages/coding-agent/docs/models.md#image-input-limits). It separates extension-owned behavior from inherited SDK behavior. The scoped 0.87 applicability pass is complete for the pinned scripted SDK stack; this is not a release, live-provider or cross-platform readiness claim. Open implementation work belongs to [BACKLOG.md](../BACKLOG.md).
|
|
36
|
+
|
|
37
|
+
- **Actionable `turn_end` / `agent_before_settle` — adapted and native-tested.** A companion can append context-bearing drafts and request continuation without another `before_agent_start`. State Flow now projects accepted memory on every enabled request even after completion removed `specification`; it neither resurrects that prompt nor creates a second continuation owner. The native boundary-continuation pair checks actual event fields, accepted state/response before and after another patch, model-visible tool declarations, retained runtime checkpoints, one user-run preparation and the exact provider-call count.
|
|
38
|
+
- **Canonical `SessionManager` and `ContextEditEntry` — native-tested without an extra projection owner.** Native user replacement, assistant/custom-message omission and tool-result replacement inside the tool loop reach the provider correctly. Tree selection applies only branch-relative edits; fixture reload preserves the edited projection. Raw trace bytes remain intact and selecting a pre-runtime branch does not overwrite accepted semantic files. State Flow neither assigns `agent.state.messages` as history authority nor reconstructs omitted raw entries; trajectory edits do not authorize rewriting separately owned semantic memory. Pi retains ownership of string-replacement normalization, protection of unseen boundary input and edited-usage freshness; no alternative transcript or accounting implementation is added.
|
|
39
|
+
- **Conversation `context` versus full `context_with_system` — adapted and native-tested.** State Flow supplies protocol via `before_agent_start.systemPromptOptions.sections.state_flow`, no longer forcing the entire prompt. Companion before-run sections and full-system additions now survive active/passive requests and tools; conversation hooks exclude systems while full-system hooks include them. Tests inspect model-visible declarations and read evidence, not just scripted execution. Explicit foreign forced prompts still override per-request system additions by Pi's contract. Native section diffs remove/reinstate State Flow's protocol on subsequent user requests after Stop/Start.
|
|
40
|
+
- **Mid-tool protocol-mode refresh — adapted and native-tested.** The next request after mid-read Stop, passive Stop, mid-read Start or accepted-boundary Stop/continuation now receives current protocol without another user-run preparation. `context_with_system` projects only the owned section; it keeps source frames immutable, conversation identities/order, foreign sections/content/tools and explicit forced-prompt precedence. Unchanged effective protocol is a no-op, including native later system deltas. No missing system frame, lifecycle field, controller or State Flow persistence format is invented. Retained red-to-green tests supersede the earlier defect-only diagnostic.
|
|
41
|
+
- **Deferred work from `agent_settled` — adapted and native-tested.** State Flow awaits its admitted native compaction's completion/error callback before returning from the settled handler. Fire-and-forget compaction previously overlapped Pi's deferred companion prompt dispatch and rejected that prompt. Native low-pressure, admitted-compaction and explicit-refusal cases now complete all settled observers before one follow-up starts, with correct memory/step and no lost or duplicate inference. Existing eligibility/leaf/generation/shutdown guards remain; backup stays at `agent_before_settle`. No new timer, queue or continuation owner is introduced.
|
|
42
|
+
- **Retain-none compaction — deliberately unused for State Flow-owned shortening.** Canonical memory is not a lossless replacement for the original request, images, tools or foreign custom context. Owned compaction therefore retains the complete accepted run; ordinary native manual/threshold/overflow compaction stays Pi-owned. R12/R14 native witnesses cover normalized images, steering and split-turn Stop continuation without trace rewriting.
|
|
43
|
+
- **Persisted retry/length/overflow omissions and edited-context accounting — inherited SDK behavior, now native-tested.** Retryable error, recoverable length and explicit overflow keep failed attempts raw while persisting omission edits; recovery and reload exclude them. Native split-turn recovery uses two summary requests within one compaction and one coding continuation. Failed attempts/summaries never advance State Flow response or semantic step. Separate accounting coverage replaces a large source message, observes reduced native usage without changing raw trace/memory, and rules out phantom recovery/compaction from stale provider counts. These are scripted SDK witnesses, not live-provider guarantees.
|
|
44
|
+
- **Per-model image resize profiles — SDK-owned and native-tested.** Real wide/tall PNG payloads exercise `inputLimits.images.resize` on prompt images, built-in image reads and generic tool-result images. Native model selection changes bounds from 1800×1200 to 900×600: new payloads use the smaller profile while historical user/read/generic-tool payloads remain byte-identical through later provider inputs and fixture reload. Disabled and bootstrap-enabled State Flow controls pass, alongside normalized-image steering/compaction and actual prompt/tool declarations after owned compaction. No State Flow image pipeline is introduced. Pi 0.87 describes other hard image/request-limit fields as metadata; codec byte/quality settings and provider enforcement remain upstream-owned, not independently live-provider/cross-platform certified here.
|
|
45
|
+
- **Removed `shouldStopAfterTurn` and changed runner/event shapes — no direct low-level migration required.** State Flow registers typed extension handlers rather than configuring an Agent termination option or calling `ExtensionRunner.emit("turn_end")`. Native SDK fixtures dispatch through Pi's `finishTurn`/`emitBoundary` implementation; the new companion tests exercise required boundary fields and draft persistence.
|
|
46
|
+
- **Other release fixes — inherited or outside this extension's ownership.** GIF-prefixed text detection belongs to built-in `read`; provider strict-schema defaults, cache-warming timing and crash diagnostics belong to Pi. Offline `/bug` upload behavior and prompt-template frontmatter diagnostics do not require State Flow features. No duplicate image pipeline, HTTP adapter, diagnostics service or cache scheduler is introduced. This classification is not a live-provider or cross-platform verification claim.
|
|
47
|
+
|
|
32
48
|
## Validation procedure
|
|
33
49
|
|
|
34
50
|
Validate another Pi SDK line in an isolated copy so the live extension, sessions, and runtime store remain unchanged:
|
|
@@ -44,3 +60,5 @@ npm run validate
|
|
|
44
60
|
```
|
|
45
61
|
|
|
46
62
|
A successful focused test does not replace the full suite. Record the exact dependency graph and command exit for any compatibility claim.
|
|
63
|
+
|
|
64
|
+
For compiled public-API checks, follow `package.json.exports["."].default` (`dist/index.js`). Pi loads the separate `pi.extensions` entry (`dist/pi-state-flow/index.js`), a default-only registration shim: importing it proves extension loadability, not the presence or absence of named library exports. Check both surfaces and compare packaged Skills with their source. Documentation-only changes may reuse source-bound build/test/benchmark evidence when its actual inputs remain identical; refresh the package inventory after the final documentation edits.
|
|
@@ -6,31 +6,28 @@ State Flow classifies absence separately from partial or malformed evidence. Rec
|
|
|
6
6
|
| --- | --- | --- | --- | --- |
|
|
7
7
|
| Global `checkpoint.json` + `patches.jsonl` | State Flow; authoritative shared semantics | Untouched publication adopts a fresh empty scope; a targeted patch conflicts | Either half missing, malformed replay, or invalid envelope fails closed | Normal CAS publication may materialize the complete empty pair |
|
|
8
8
|
| CWD `checkpoint.json` + `patches.jsonl` | State Flow; authoritative shared semantics with CWD identity | Same as global; selected values are not resurrected | Same as global; owner mismatch also fails closed | Normal CAS publication may materialize the complete empty pair |
|
|
9
|
-
| Session `checkpoint.json` + `patches.jsonl` | State Flow; authoritative private semantics | Fresh lifecycle origin may initialize; an existing selected session requires exact retained authority | Partial or malformed pair fails closed | Fresh initialization or exact
|
|
9
|
+
| Session `checkpoint.json` + `patches.jsonl` | State Flow; authoritative private semantics | Fresh lifecycle origin may initialize; an existing selected session requires exact retained authority | Partial or malformed pair fails closed | Fresh initialization or exact retained-boundary recovery only |
|
|
10
10
|
| Global/CWD `meta.json` | State Flow; temporal boundaries, CWD identity, and artifact provenance | Missing metadata removes temporal authority and fails closed; only an omitted `artifacts` leaf degrades provenance to `{}` | Malformed metadata or semantic/boundary mismatch fails closed | Normal CAS publication from a complete proven cohort |
|
|
11
11
|
| Session `meta.json` | State Flow; session temporal boundaries and artifact provenance | Fresh origin may initialize; selected sessions recover only from exact scope authority | Partial, malformed, or contradictory boundary evidence fails closed | Canonical scope publication from the selected temporal state |
|
|
12
|
-
| Session `config.json` + `runtime.json` | State Flow; behavior plus authoritative runtime identity, lineage,
|
|
13
|
-
| Unsupported `state.json`, hashed layouts, or semantic Pi checkpoints | No current authority | Ignored | Presence never becomes recovery or
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
| Publication locks | State Flow; mutual exclusion | Unlocked | Present lock excludes publishers, including interrupted owners | Current owner releases; no opportunistic deletion |
|
|
19
|
-
| Temporary queue files / isolated Git index | Creating State Flow operation; transient | No pending preparation | Unknown surviving files grant no authority | Creating operation cleans its own temporary path; fatal residue is not adopted |
|
|
20
|
-
| Repository-root `config.json` | Operator; optional global configuration, versioned with the store | Built-in defaults | Present unreadable/malformed/unknown settings fail extension configuration | State Flow never creates or rewrites it; ordinary repository publication preserves and versions operator edits |
|
|
21
|
-
| Knowledge root and Markdown | External Knowledge owner | Freshness unavailable; durable semantic state remains | Unsafe paths or malformed/unreadable sources disable acquisition locally | Never create; semantic removal only under existing confirmed ownership rules |
|
|
12
|
+
| Session `config.json` + `runtime.json` | State Flow; behavior plus authoritative runtime identity, lineage, and counters | Fresh origin may initialize; selected sessions recover only from exact authority | Partial, malformed, contradictory identity or lineage fails closed | Canonical runtime publication from proven lifecycle/selected state; combined predecessor metadata is unsupported |
|
|
13
|
+
| Unsupported predecessor envelopes, `state.json`, hashed layouts, or semantic Pi checkpoints | No current authority | Ignored | Presence never becomes recovery or conversion input | Preserve bytes; operator-managed removal or external conversion only |
|
|
14
|
+
| Retained Pi boundary | State Flow/Pi entry; current canonical lineage | Expired or missing boundary is unavailable | Identity, lifecycle, or lineage contradiction fails closed | Select exact retained private history over live shared scopes; never consult Git |
|
|
15
|
+
| Canonical writer lock | State Flow; file-cohort mutual exclusion | Unlocked | Present lock excludes cooperating publishers, including interrupted owners | Current owner releases; no opportunistic deletion |
|
|
16
|
+
| Repository-root `config.json` | Operator; optional read-only global configuration | Built-in defaults | Present unreadable/malformed/unknown settings fail extension configuration | State Flow never creates, rewrites, or stages operator edits; include it in operator-managed copies/versioning |
|
|
17
|
+
| Registered artifact source path | External source owner | Exact proven absence permits owning-scope artifact/provenance removal | Relative, symlink, directory, malformed, or unreadable paths disable maintenance locally | Never create; semantic removal only for exact proven absence |
|
|
22
18
|
| Skill and external artifact sources | External package/user owner | Freshness unavailable unless ownership proves removal semantics | Unsafe/non-regular/unreadable sources disable acquisition locally | Never create or fabricate source/provenance |
|
|
23
|
-
| Pi State Flow entries
|
|
19
|
+
| Pi State Flow entries | Pi session log / State Flow entry owner | Missing required selected boundary blocks that restore | Malformed or contradictory owner/version/boundary fails the dependent restore | Append through Pi entry APIs only; never replace failed selection with passive state |
|
|
20
|
+
| Optional diagnostic log | State Flow logger; outside the canonical repository | No diagnostic evidence | I/O failure warns once without changing accepted state | Append local JSONL only when opted in; never use it as semantic recovery authority |
|
|
24
21
|
|
|
25
22
|
## Transaction rule
|
|
26
23
|
|
|
27
24
|
Every semantic repair follows the ordinary transaction path:
|
|
28
25
|
|
|
29
|
-
1. Capture the live
|
|
26
|
+
1. Capture the live canonical-file basis under the existing publication lock.
|
|
30
27
|
2. Classify each cohort as present, absent, partial, or malformed.
|
|
31
28
|
3. Derive only an authorized replacement.
|
|
32
29
|
4. Stage the complete canonical cohort.
|
|
33
30
|
5. Recheck CAS and ownership.
|
|
34
|
-
6.
|
|
31
|
+
6. Publish with per-file atomic replacement, conflict-preserving rollback, and then install the accepted runtime state; this is not kernel-atomic multi-file CAS.
|
|
35
32
|
|
|
36
|
-
A current wholly absent shared scope is newer live reality for an untouched transition dependency. Its replacement begins empty at a fresh reconciliation origin. If the accepted transition targets that missing scope, publication refuses the stale target and requires a later inference against the refreshed basis.
|
|
33
|
+
A current wholly absent shared scope is newer live reality for an untouched transition dependency. Its replacement begins empty at a fresh reconciliation origin. If the accepted transition targets that missing scope, publication refuses the stale target and requires a later inference against the refreshed basis. Discarded history is unavailable and is never reconstructed or promoted back into current shared memory.
|
|
@@ -1,47 +1,42 @@
|
|
|
1
|
-
# Physical fork: session-stream copy
|
|
1
|
+
# Physical fork: retained session-stream copy
|
|
2
2
|
|
|
3
|
-
Status: **locally implemented and validated; not released**. [Usage](usage.md#fork-support-and-limits) owns operation and recovery; [BACKLOG.md](../BACKLOG.md) owns
|
|
3
|
+
Status: **locally implemented and validated; not released**. [Usage](usage.md#fork-support-and-limits) owns operation and recovery; [BACKLOG.md](../BACKLOG.md) owns release tracking.
|
|
4
4
|
|
|
5
5
|
## Contract
|
|
6
6
|
|
|
7
|
-
A physical Pi fork creates a
|
|
7
|
+
A physical Pi fork creates a fresh child session from a retained boundary in its direct parent's canonical session lineage:
|
|
8
8
|
|
|
9
9
|
```text
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
child.global = current live global
|
|
11
|
+
child.cwd = current live CWD
|
|
12
|
+
child.session = parent session selected at retained boundary
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
-
|
|
16
|
-
- Copy the session checkpoint, retained tail of up to seven patches and matching session artifact provenance. Preserve replay records and transition identities rather than flattening them into a new materialized-only snapshot.
|
|
17
|
-
- Adopt current proven live global/CWD streams and provenance without rewriting or pruning them. They need not equal the selected source revision's older shared layers.
|
|
18
|
-
- Give B its own UUID, native session key, config/meta and durable checkpoint. Retain selected enablement/publication policy and any pending bootstrap requirement, but start at step zero without the parent's run specification, validation feedback, publication acknowledgement or process ownership.
|
|
19
|
-
- Preserve A's private files, native trace and accepted history. Subsequent B session writes do not modify A's session layer.
|
|
20
|
-
- Forking conversation/memory does not clone or roll back project files or tool effects.
|
|
15
|
+
The adapter reads Pi's persisted direct-parent header, requires matching CWD and session identity, and selects the boundary only if it remains in the parent's retained canonical lineage. It never consults Git, a storage receipt, an older checkpoint entry, or the parent's newer private state.
|
|
21
16
|
|
|
22
|
-
|
|
17
|
+
The child receives:
|
|
23
18
|
|
|
24
|
-
|
|
19
|
+
- its own UUID, native session key, runtime metadata, and fresh lineage origin;
|
|
20
|
+
- the selected parent session materialization and matching artifact provenance;
|
|
21
|
+
- current live global/CWD values and provenance without rewinding them;
|
|
22
|
+
- selected enablement and bootstrap lifecycle state, with step reset to zero and no inherited unfinished specification or validation diagnostic.
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
The parent's private files and native trace remain unchanged. Later child session writes cannot modify the parent's private layer. Applying a smaller configured `historyLimit` may fold excess shared tails during child acceptance under file-cohort CAS, without changing current shared materialization or provenance. Without retention reduction, the shared files remain unchanged too. Forking semantic memory does not clone or roll back project files or tool effects.
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
Artifact provenance is current-only, not a historical registry. Any retained parent session patch touching an artifact after the selected boundary makes its current provenance unproven for that selection, even if a later patch restores an equal value. The child keeps the selected artifact semantics but omits that provenance until explicit reacquisition and compilation. Untouched artifact paths retain their evidence, including provenance-only refreshes of unchanged semantics; shared provenance remains live.
|
|
29
27
|
|
|
30
|
-
|
|
28
|
+
## Lifecycle and failure
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
`TemporalRuntime.prepareBoundaryFork()` prepares a detached, single-use copy from current canonical files. Acceptance publishes the fresh child origin before any runtime-only lifecycle write. Existing child storage, identity mismatch, missing parent files, malformed storage, concurrency conflict, or an expired boundary fails closed.
|
|
31
|
+
|
|
32
|
+
A failed or expired selection never substitutes the parent's current/newer private state and never falls through to an older disabled marker. Explicit Start may retry the same unaccepted fork after missing identity or storage evidence is corrected. Child-owned checkpoints subsequently use ordinary retained-boundary reload/resume without rereading the parent header.
|
|
33
|
+
|
|
34
|
+
A child-owned passive-projection reset prevents copied parent Stop markers from resurfacing after child reload. Disabled sources remain disabled; ordinary activation policy is not overridden. Nested forks require each direct parent boundary to remain retained; ancestry is not recursively reconstructed.
|
|
33
35
|
|
|
34
36
|
## Support boundary
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
- Source or publication failure leaves the selected reference intact. Explicit Start can retry an unaccepted copy in that same loaded fork instance after evidence or contention is corrected.
|
|
38
|
-
- Cold recovery before the first child checkpoint, startup/CLI paths that do not emit the native fork reason, in-memory parent locators and arbitrary cross-CWD imports are not added by this slice. Existing child-owned checkpoints use normal reload/resume without rereading the parent header.
|
|
39
|
-
- Nested copying works only where the selected pointer is owned by the direct parent; inherited pointers to earlier ancestors are not recursively resolved.
|
|
40
|
-
- The file backend copies only an available exact current cohort. Expired file references do not authorize copying newer parent data. Legacy Git storage requires its existing explicit migration path rather than migration during fork.
|
|
41
|
-
- Uncommitted shared streams, collisions and concurrent modifications retain the existing publication guards; failure does not authorize broadening the fork's writes.
|
|
38
|
+
Supported copying requires a persisted regular parent session file, matching header UUID/CWD, current canonical scope/runtime files, and an available retained boundary. Arbitrary session search, UUID aliases, cross-CWD imports, in-memory-only parent locators, predecessor conversion, unlimited history, and Git recovery are unsupported.
|
|
42
39
|
|
|
43
40
|
## Evidence
|
|
44
41
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
`tests/runtime.test.ts` covers an exact seven-record session copy with provenance, unchanged live shared files including unreferenced provenance, detached/single-use preparation, occupied live/HEAD targets, CAS races and file-only source expiration. `tests/continuation.test.ts` checks header-only reading and refusal of non-regular/symlink locators. These are synthetic fixtures, not production-session or arbitrary-host validation.
|
|
42
|
+
Native integration tests cover retained private selection versus newer parent/shared state, fresh child origin, independent child mutation, child reload/resume, disabled sources, Stop projection fencing, malformed parent identity/CWD, retry, and expired-boundary refusal. Runtime tests cover single-use preparation, canonical child publication, live shared ownership, artifact provenance, occupied child storage, and retention reduction/increase without parent-private mutation or reconstructed history. Continuation tests cover header-only reading and refusal of non-regular or symlinked locators.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Lazy state through progressive `read_state`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This document describes the implemented lazy-state contract. [BACKLOG.md](../BACKLOG.md) owns release readiness; [temporal acceptance](temporal-acceptance.md) maps behavior to executable evidence.
|
|
4
4
|
|
|
5
5
|
## Thesis
|
|
6
6
|
|
|
7
|
-
State Flow
|
|
7
|
+
State Flow provides `lazy` as a required object-root semantic plane in every scope. Nested lazy values are ordinary JSON: durable and versioned with the same causal lineage as hot state, but excluded from ordinary baseline hydration.
|
|
8
8
|
|
|
9
9
|
The model-facing surface remains small:
|
|
10
10
|
|
|
@@ -34,19 +34,19 @@ The model-facing surface remains small:
|
|
|
34
34
|
|
|
35
35
|
## Semantic model
|
|
36
36
|
|
|
37
|
-
Each scope
|
|
37
|
+
Each scope contains six semantic planes in intent-first presentation order:
|
|
38
38
|
|
|
39
39
|
```text
|
|
40
40
|
global | CWD | session
|
|
41
|
-
├──
|
|
41
|
+
├── intents
|
|
42
42
|
├── contract
|
|
43
43
|
├── working
|
|
44
|
-
├──
|
|
44
|
+
├── artifacts
|
|
45
45
|
├── response (session-owned where applicable)
|
|
46
46
|
└── lazy
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
`
|
|
49
|
+
`intents`, `contract`, `working`, `artifacts`, and `response` remain hot. `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
52
|
- It is excluded from the ordinary baseline effective-state body.
|
|
@@ -61,7 +61,7 @@ State Flow preserves all forms exactly as ordinary JSON. It does not scan prose,
|
|
|
61
61
|
|
|
62
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.
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
The `lazy` root must be an object. Its nested values may include arrays, objects, and scalars, for example:
|
|
65
65
|
|
|
66
66
|
```json
|
|
67
67
|
["important thought", "next thought"]
|
|
@@ -136,7 +136,7 @@ Errors use the normal tool-error channel rather than successful JSON containing
|
|
|
136
136
|
|
|
137
137
|
### Path and range model
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
Unscoped semantic paths alias current effective state. Explicit roots and selectors address:
|
|
140
140
|
|
|
141
141
|
- `effective` for the current composed overlay or an indexed historical effective root.
|
|
142
142
|
- `global`, `cwd`, and `session` for explicit current or historical scopes.
|
|
@@ -156,11 +156,11 @@ cwd.lazy.memory[10:20]
|
|
|
156
156
|
session[3].lazy.investigation
|
|
157
157
|
```
|
|
158
158
|
|
|
159
|
-
Indices are zero-based. Negative indices, open-ended ranges, steps, predicates, wildcards, unions, and cross-array expressions are rejected
|
|
159
|
+
Indices are zero-based. Negative indices, open-ended ranges, steps, predicates, wildcards, unions, and cross-array expressions are rejected.
|
|
160
160
|
|
|
161
161
|
A range must fit entirely within the current array. If an array has length 10, `[0:10]` and `[10:10]` are valid, while `[0:15]` and `[11:11]` fail. The fallback `..` spelling has identical semantics. A successful result always contains exactly the requested range. State Flow never returns a shorter successful range with truncation metadata.
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
All projections use the same strict member grammar; no separate lazy path language exists.
|
|
164
164
|
|
|
165
165
|
## Projections
|
|
166
166
|
|
|
@@ -396,8 +396,7 @@ Array index selectors extend recursive addressing:
|
|
|
396
396
|
"[4]": "corrected fifth thought"
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
|
-
}
|
|
400
|
-
"final": true
|
|
399
|
+
}
|
|
401
400
|
}
|
|
402
401
|
```
|
|
403
402
|
|
|
@@ -425,8 +424,7 @@ Nested addressing remains ordinary patch structure:
|
|
|
425
424
|
}
|
|
426
425
|
}
|
|
427
426
|
}
|
|
428
|
-
}
|
|
429
|
-
"final": true
|
|
427
|
+
}
|
|
430
428
|
}
|
|
431
429
|
```
|
|
432
430
|
|
|
@@ -440,24 +438,23 @@ Lazy mutations inherit existing guarantees:
|
|
|
440
438
|
- One lock/CAS publication cohort.
|
|
441
439
|
- Atomic hot-plus-lazy multi-scope changes.
|
|
442
440
|
- Scope-local deletion and effective revelation semantics.
|
|
443
|
-
- Exact
|
|
441
|
+
- Exact retained-boundary selection on restore and branch navigation.
|
|
444
442
|
- Read-only discovery with no commit, timestamp update, or transition.
|
|
445
443
|
|
|
446
|
-
|
|
444
|
+
Lazy trees are co-located in canonical scope checkpoints/tails and use the same bounded lineage as hot state. Git-era publication and cold-restoration measurements do not describe this implementation. The [performance guide](performance.md) owns current synthetic workloads and measurement limits. No separate lazy index or sharded authority exists; any future layout change requires measured need and must preserve canonical semantics, ownership, and one causal lineage.
|
|
447
445
|
|
|
448
446
|
## Failure semantics
|
|
449
447
|
|
|
450
448
|
- A nonexistent path, wrong target kind, malformed selector, or out-of-bounds index/range is a tool error.
|
|
451
449
|
- One invalid member of a path batch fails the entire read before returning partial success.
|
|
452
450
|
- One invalid indexed patch fails the entire mutation before publication.
|
|
453
|
-
-
|
|
454
|
-
-
|
|
455
|
-
-
|
|
456
|
-
- Mechanical index rebuilds create no semantic transition.
|
|
451
|
+
- Malformed canonical lazy data fails the dependent scope/runtime load without rewriting retained bytes; it is not silently discarded to manufacture valid hot state.
|
|
452
|
+
- Invalid reads and rejected patches create no semantic transition and preserve accepted hot state.
|
|
453
|
+
- Independent scopes remain usable only where the ordinary filesystem/recovery contract proves their authority.
|
|
457
454
|
|
|
458
455
|
## Normative invariants
|
|
459
456
|
|
|
460
|
-
1. **
|
|
457
|
+
1. **Object root, ordinary JSON children**: Every scope has a lazy object whose nested values contain domain semantics, never mandatory State Flow record wrappers.
|
|
461
458
|
2. **Semantic snapshots**: `value` contains only the selected state snapshot and `patch` only the selected semantic patch; `keys` alone adds closed structural `meta` before `keys`.
|
|
462
459
|
3. **Exact success**: A successful read returns everything requested; it never truncates or paginates silently.
|
|
463
460
|
4. **Runtime-owned concurrency**: Revisions, locks, and CAS remain internal unless explicitly needed for diagnostics.
|
|
@@ -468,7 +465,7 @@ The first implementation keeps lazy trees co-located in the existing scope seman
|
|
|
468
465
|
9. **Explicit frontier crossing**: Only a visible hot-state patch promotes a lazy consequence.
|
|
469
466
|
10. **Patch remains patch**: Array indices extend recursive addressing without introducing an edit-command language.
|
|
470
467
|
11. **Index safety**: Array indices are interpreted only against one captured basis under lock/CAS.
|
|
471
|
-
12. **Failure
|
|
468
|
+
12. **Failure preservation**: Invalid reads or patches preserve accepted bytes; canonical corruption fails closed rather than granting partial authority.
|
|
472
469
|
|
|
473
470
|
## Validation contract
|
|
474
471
|
|
|
@@ -487,27 +484,14 @@ Before release, implementation evidence must prove:
|
|
|
487
484
|
- `effective.lazy` follows global → CWD → session overlay while explicit scope paths preserve ownership.
|
|
488
485
|
- Reads create no semantic transition, Git commit, publication, freshness update, or future activation.
|
|
489
486
|
- Whole-array replacement and indexed scalar, array, object, nested, multi-index, and stale-basis patches remain atomic.
|
|
490
|
-
- Restore
|
|
491
|
-
-
|
|
492
|
-
-
|
|
493
|
-
|
|
494
|
-
## Remaining evolution decisions
|
|
495
|
-
|
|
496
|
-
- Exact member escaping beyond the current strict grammar for names containing separators or brackets.
|
|
497
|
-
- A measured real-workload threshold that would justify replacing the initial co-located semantic layout.
|
|
498
|
-
- Cold Git-history access beyond retained hot history.
|
|
487
|
+
- Restore and fork select lazy state from the same retained canonical boundary as the rest of the owning session scope.
|
|
488
|
+
- Malformed canonical lazy data fails closed without rewriting the store; rejected queries and patches preserve accepted hot state.
|
|
489
|
+
- Unsupported predecessor stores and retired `read_state` inputs fail actionably without rewriting retained bytes.
|
|
499
490
|
|
|
500
|
-
|
|
491
|
+
## Limits and change authority
|
|
501
492
|
|
|
502
|
-
|
|
493
|
+
Retained hot history is the entire semantic history available to these readers; cold Git-history access is unsupported. Names must fit the shared path grammar. Generalized querying, sharding, mandatory record objects, metadata envelopes, pagination, and a second mutation language are not implied future work and require a separate evidence-backed design decision.
|
|
503
494
|
|
|
504
|
-
|
|
505
|
-
2. Implement semantic-snapshot `value`, structural `meta` + `keys`, and semantic `patch` reads over current hot state first.
|
|
506
|
-
3. Add indexed recursive array patching through the existing lock/CAS barrier.
|
|
507
|
-
4. Add `lazy` to scope validation, persistence, history, restore, and explicit scoped reads.
|
|
508
|
-
5. Add the read-only `effective.lazy` overlay and bounded baseline navigation hint.
|
|
509
|
-
6. Add migration, corruption, stale-basis, restore, fork, file-only, Git-backed, and concurrency coverage.
|
|
510
|
-
7. Measure repository growth, publication latency, restoration latency, and package/store size before selecting any sharded layout.
|
|
511
|
-
8. Update runtime protocol and user documentation, run full validation, and release through the repository's guarded minor-release flow.
|
|
495
|
+
The [canonical backlog](../BACKLOG.md) owns remaining implementation and release gates. This contract is not a parallel delivery plan.
|
|
512
496
|
|
|
513
497
|
The stopping rule is conceptual economy: ordinary JSON, one effective lazy overlay, pure state and patch snapshots, one narrow structural `meta` + `keys` projection, recursive patches with indexed array addressing, and one mutation/publication barrier.
|