@llblab/pi-kit 0.28.0 → 0.29.1
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/BACKLOG.md +3 -1
- package/CHANGELOG.md +8 -0
- package/README.md +3 -3
- package/node_modules/@llblab/pi-state-flow/AGENTS.md +2 -2
- package/node_modules/@llblab/pi-state-flow/BACKLOG.md +1 -29
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +12 -0
- package/node_modules/@llblab/pi-state-flow/README.md +7 -8
- package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +94 -47
- package/node_modules/@llblab/pi-state-flow/dist/lib/logging.js +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.d.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.d.ts +8 -27
- package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.js +16 -151
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.d.ts +3 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.js +4 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.d.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.js +4 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.d.ts +2 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.js +6 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.d.ts +0 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.js +0 -36
- package/node_modules/@llblab/pi-state-flow/dist/package.json +1 -1
- package/node_modules/@llblab/pi-state-flow/docs/agent-contract-relocation.md +1 -1
- package/node_modules/@llblab/pi-state-flow/docs/architecture.md +20 -31
- package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +8 -9
- package/node_modules/@llblab/pi-state-flow/docs/filesystem-recovery.md +4 -4
- package/node_modules/@llblab/pi-state-flow/docs/fork-contract.md +18 -23
- package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +19 -21
- package/node_modules/@llblab/pi-state-flow/docs/usage.md +26 -27
- package/node_modules/@llblab/pi-state-flow/lib/extension.ts +89 -48
- package/node_modules/@llblab/pi-state-flow/lib/logging.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +22 -146
- package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +6 -3
- package/node_modules/@llblab/pi-state-flow/lib/status.ts +4 -2
- package/node_modules/@llblab/pi-state-flow/lib/telegram.ts +8 -2
- package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +0 -36
- package/node_modules/@llblab/pi-state-flow/package.json +1 -1
- package/package.json +2 -2
|
@@ -53,7 +53,7 @@ On the tested SDK, `before_agent_start` precedes the low-level agent's `prompt`;
|
|
|
53
53
|
2. The active `context` hook supplies the operation signal and awaits preparation/maintenance before provider inference.
|
|
54
54
|
3. If preparation fails, State Flow calls public `ctx.abort()`. Pi catches context-hook errors and may otherwise continue inference, so a thrown error alone is not a fence.
|
|
55
55
|
|
|
56
|
-
Native tests prove no provider call before coherent acceptance, cancellation while an independent writer remains held, rollback without draft installation and preservation of uncompiled native input.
|
|
56
|
+
Native tests prove no provider call before coherent acceptance, cancellation while an independent writer remains held, rollback without draft installation and preservation of uncompiled native input. Unreadable current Active memory also aborts live inference before the provider; native witnesses cover contradictory private lineage and malformed runtime files without changing canonical bytes, while old-step tree selection/reload is not a failure. Failed attachment retains Active policy and exposes `active (blocked)` in terminal/Telegram; the fence is derived from selected mode plus unavailable-memory validation. Active controls retry current-memory acceptance rather than claiming it is already active. Explicit Passive accepts validated current memory and releases both fences; explicit Off releases only the inference fence.
|
|
57
57
|
|
|
58
58
|
**Signals are not universal.** Idle commands and session events can lack them. Do not infer native Abort cancellation from an extension-owned shutdown signal or generalize active-run tests to idle waits.
|
|
59
59
|
|
|
@@ -76,7 +76,7 @@ Native tests prove no provider call before coherent acceptance, cancellation whi
|
|
|
76
76
|
|
|
77
77
|
To use Passive, select it in the current session or set global `mode: "passive"` for new sessions.
|
|
78
78
|
|
|
79
|
-
**SDK and Telegram controls.** The extension SDK accepts an optional `mode` default override. Both Telegram port variants use `snapshot.mode` plus `select(mode)`. A stale callback keyboard may refresh the view without selecting a mode. Synchronous enum-based ports are supported; Start/Stop port signatures are not.
|
|
79
|
+
**SDK and Telegram controls.** The extension SDK accepts an optional `mode` default override. Both Telegram port variants use `snapshot.mode` plus `select(mode)`. The optional additive `snapshot.inferenceBlocked` diagnostic marks failed Active restoration; legacy ports may omit it. A stale callback keyboard may refresh the view without selecting a mode. Synchronous enum-based ports are supported; Start/Stop port signatures are not.
|
|
80
80
|
|
|
81
81
|
## Mode selection and memory restoration
|
|
82
82
|
|
|
@@ -84,17 +84,17 @@ To use Passive, select it in the current session or set global `mode: "passive"`
|
|
|
84
84
|
|
|
85
85
|
- Activates current same-session authority under awaited exclusion.
|
|
86
86
|
- Rechecks physical identity and initialization permission after waiting, accepts once, then installs policy, memory and checkpoint.
|
|
87
|
-
-
|
|
87
|
+
- Uses current memory; branch checkpoints never select a past revision.
|
|
88
88
|
- Native tests prove current shared plus local-private memory at the next provider, and actual Abort withdrawal for in-run Start with an operation signal.
|
|
89
89
|
|
|
90
90
|
**Passive:**
|
|
91
91
|
|
|
92
92
|
- Selects local tools/context policy before waiting for persistence.
|
|
93
93
|
- For accepted memory, publishes lifecycle metadata without rewriting semantic/provenance files. Pending inactive choices share one acceptance of the latest mode.
|
|
94
|
-
- Keeps independently owned
|
|
94
|
+
- Keeps independently owned current-memory attachment, Active-default initialization and fork copying; the latest inactive policy is applied at acceptance.
|
|
95
95
|
- Read-only recovery preserves an intervening Passive choice and its write fence.
|
|
96
96
|
- Selection, shutdown and accepted Start cancel obsolete Stop persistence; rejected Start does not.
|
|
97
|
-
- Genuine persistence failure retains readable memory and native context while fencing writes until accepted Start.
|
|
97
|
+
- Genuine persistence failure retains readable memory and native context while fencing writes until accepted Start or a later explicit Passive that successfully accepts current memory. A Passive retry that still fails adds no duplicate fence marker.
|
|
98
98
|
|
|
99
99
|
**Off:**
|
|
100
100
|
|
|
@@ -104,7 +104,7 @@ To use Passive, select it in the current session or set global `mode: "passive"`
|
|
|
104
104
|
|
|
105
105
|
Modes select workflow policy, not whether canonical memory exists. Cancelling a Start waiter does not cancel independently owned restoration. Selection changes, shutdown and an available native operation signal can revoke obsolete restoration; failure after acceptance cannot undo memory.
|
|
106
106
|
|
|
107
|
-
**Native
|
|
107
|
+
**Native attachment evidence.** Startup and tree handlers await attachment. Tests cover held-store tree/fork selection, current private state over live shared streams after old-step navigation, fork copies of the parent's current memory, unchanged parent-private files, cold reopening, failed-Stop recovery and next-provider input with current private values.
|
|
108
108
|
|
|
109
109
|
A public SDK host can observe the child factory result before awaiting extension binding and send Stop or Stop→Start through the child's public `prompt` method while copying waits. This proves that embedding route, not that the installed CLI or Telegram exposes the child before runtime replacement finishes.
|
|
110
110
|
|
|
@@ -153,8 +153,7 @@ The package root exports `TemporalRuntime`. The Pi registration shim is a separa
|
|
|
153
153
|
- **Authored semantic patch — `withPatchTransaction`:** current shared basis and selected private authority; one atomic acceptance.
|
|
154
154
|
- **Accepted-runtime lifecycle — `withLifecycleTransaction`:** config/runtime only; cannot initialize or repair semantic storage.
|
|
155
155
|
- **Current-head activation — `withStartTransaction`:** origin creation defaults off and requires explicit authorization.
|
|
156
|
-
- **
|
|
157
|
-
- **Child creation — `withForkTransaction`:** exact parent authority and an unoccupied independent child.
|
|
156
|
+
- **Child creation — `withForkTransaction(source, lifecycle, …)`:** the parent's current memory copied into an unoccupied independent child; `lifecycle` supplies only mode/bootstrap.
|
|
158
157
|
|
|
159
158
|
Await completion before consuming results. Transaction callbacks:
|
|
160
159
|
|
|
@@ -166,7 +165,7 @@ Keep inference, source acquisition and Git outside canonical exclusion. Raw prec
|
|
|
166
165
|
|
|
167
166
|
Continuation inspection/candidate building and Git backup also return Promises. Await them rather than treating a Promise as a boolean or accessing a result before completion. Continuation inspection is advisory: it cannot initialize, restore or select a session on the host's behalf.
|
|
168
167
|
|
|
169
|
-
**Synchronous runtime methods:** `loadPassive`, `prepareBoundaryRestore`, `restoreBoundary`, `acceptRestoredOrigin`, `prepareBoundaryFork` and `
|
|
168
|
+
**Synchronous runtime methods:** `loadPassive` and `initialize`. Version 0.26.0 removed the boundary-restoration APIs (`withRestoreTransaction`, `prepareBoundaryRestore`, `restoreBoundary`, `acceptRestoredOrigin`, `prepareBoundaryFork`) and `HistoryBoundaryExpiredError`; memory never rewinds to an older boundary.
|
|
170
169
|
|
|
171
170
|
- They are supported for library consumers and local tests/benchmarks; production lifecycle wiring uses the awaited APIs.
|
|
172
171
|
- They are not signature-compatible substitutes and do not acquire the awaited APIs' cancellation behavior.
|
|
@@ -21,9 +21,9 @@ State Flow classifies absence separately from partial or malformed evidence. Rec
|
|
|
21
21
|
### Session `checkpoint.json` + `patches.jsonl`
|
|
22
22
|
|
|
23
23
|
- **Authority:** State Flow; authoritative private semantics.
|
|
24
|
-
- **Wholly absent:** Fresh lifecycle origin may initialize; an existing
|
|
24
|
+
- **Wholly absent:** Fresh lifecycle origin may initialize; an existing session with a checkpoint requires its current files.
|
|
25
25
|
- **Partial or malformed:** Partial or malformed pair fails closed.
|
|
26
|
-
- **Allowed repair and writes:** Fresh initialization or
|
|
26
|
+
- **Allowed repair and writes:** Fresh initialization or acceptance of validated current memory only.
|
|
27
27
|
|
|
28
28
|
### Global/CWD `meta.json`
|
|
29
29
|
|
|
@@ -91,8 +91,8 @@ State Flow classifies absence separately from partial or malformed evidence. Rec
|
|
|
91
91
|
### Pi State Flow entries
|
|
92
92
|
|
|
93
93
|
- **Authority:** Pi session log / State Flow entry owner.
|
|
94
|
-
- **Wholly absent:**
|
|
95
|
-
- **Partial or malformed:** Malformed or
|
|
94
|
+
- **Wholly absent:** No checkpoint means no recorded branch mode; memory is not affected.
|
|
95
|
+
- **Partial or malformed:** Malformed or unsupported envelopes are skipped or fail the dependent mode selection; a checkpoint boundary is never a memory revision to restore.
|
|
96
96
|
- **Allowed repair and writes:** Append through Pi entry APIs only; never replace failed selection with passive state.
|
|
97
97
|
|
|
98
98
|
### Optional diagnostic log
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
# Physical fork:
|
|
1
|
+
# Physical fork: current session-memory copy
|
|
2
2
|
|
|
3
3
|
[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 fresh child session from
|
|
7
|
+
A physical Pi fork creates a fresh child session from its direct parent's **current** canonical session memory. State Flow does not depend on the Pi step the fork starts from:
|
|
8
8
|
|
|
9
9
|
```text
|
|
10
10
|
child.global = current live global
|
|
11
11
|
child.cwd = current live CWD
|
|
12
|
-
child.session = parent session
|
|
12
|
+
child.session = parent session current head
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
The adapter reads Pi's persisted direct-parent header, requires matching CWD and session identity,
|
|
15
|
+
The adapter reads Pi's persisted direct-parent header, requires matching CWD and session identity, reads the parent's current memory and uses its head as the copied boundary. It never consults Git, a storage receipt or an older checkpoint revision.
|
|
16
16
|
|
|
17
17
|
The child receives:
|
|
18
18
|
|
|
19
19
|
- its own UUID, native session key, runtime metadata, and fresh lineage origin;
|
|
20
|
-
- the
|
|
20
|
+
- the parent's current session materialization and matching artifact provenance;
|
|
21
21
|
- current live global/CWD values and provenance without rewinding them;
|
|
22
22
|
- selected `mode` and bootstrap lifecycle state, with step reset to zero and no inherited unfinished specification or validation diagnostic.
|
|
23
23
|
|
|
@@ -27,47 +27,42 @@ The child receives:
|
|
|
27
27
|
- 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.
|
|
28
28
|
- Forking semantic memory does not clone or roll back project files or tool effects.
|
|
29
29
|
|
|
30
|
-
**Artifact evidence is current-only, not a historical registry.**
|
|
31
|
-
|
|
32
|
-
- 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.
|
|
33
|
-
- The child keeps the selected artifact semantics but omits that provenance until explicit reacquisition and compilation.
|
|
34
|
-
- Untouched artifact paths retain their evidence, including provenance-only refreshes of unchanged semantics; shared provenance remains live.
|
|
30
|
+
**Artifact evidence is current-only, not a historical registry.** Because the child copies the parent's current head, current artifact semantics and their current provenance stay together; shared provenance remains live.
|
|
35
31
|
|
|
36
32
|
## Lifecycle and failure
|
|
37
33
|
|
|
38
|
-
**Copying and acceptance.** `TemporalRuntime.withForkTransaction(source,
|
|
34
|
+
**Copying and acceptance.** `TemporalRuntime.withForkTransaction(source, lifecycle, action, signal?)`:
|
|
39
35
|
|
|
40
|
-
1. Pins source identity
|
|
36
|
+
1. Pins source identity and the parent's current head boundary before waiting.
|
|
41
37
|
2. Selects exact parent authority plus an unoccupied child under one awaited exclusion.
|
|
42
38
|
3. Lets the caller recheck native selection/policy and publish its child lifecycle synchronously, once.
|
|
43
39
|
4. Revalidates parent evidence before publication and protects the child cohort with CAS. Only accepted memory installs.
|
|
44
40
|
|
|
45
|
-
Cancellation or rejection cannot initialize an empty child. Failure after acceptance cannot roll it back or authorize another parent copy. Existing child storage, an identity mismatch, missing parent files, malformed storage
|
|
41
|
+
Cancellation or rejection cannot initialize an empty child. Failure after acceptance cannot roll it back or authorize another parent copy. Existing child storage, an identity mismatch, missing parent files, malformed storage or a concurrency conflict fails closed.
|
|
46
42
|
|
|
47
43
|
**Forking while Off:**
|
|
48
44
|
|
|
49
45
|
- Parent-header acquisition and canonical copying are deferred. Only a child-owned pending-fork marker is appended to the native trace; it carries no semantic authority.
|
|
50
|
-
- The marker survives cold extension reload and permits later explicit Passive/Active acquisition
|
|
46
|
+
- The marker survives cold extension reload and permits later explicit Passive/Active acquisition, which copies the parent's then-current memory subject to the same identity and occupied-child checks.
|
|
51
47
|
- Accepted initialization resets the marker.
|
|
52
|
-
- Parent expiry while Off is diagnosed only on explicit acquisition, never silently replaced with newer parent memory.
|
|
53
48
|
|
|
54
|
-
Memory-enabled native fork adoption and Start's
|
|
49
|
+
Memory-enabled native fork adoption and Start's fork retry use this transaction inside the extension's owned restoration lifetime. It publishes the fresh child origin before any runtime-only lifecycle write. Native evidence holds a publisher across fork adoption; it does not certify idle native Abort.
|
|
55
50
|
|
|
56
51
|
**Retry and cancellation:**
|
|
57
52
|
|
|
58
|
-
- A failed
|
|
53
|
+
- A failed copy never substitutes empty or foreign memory and never falls through to an older disabled marker.
|
|
59
54
|
- In the same live extension instance, explicit Start may retry the unaccepted fork after missing identity or storage evidence is corrected.
|
|
60
55
|
- Passive selection retains an in-flight fork or its activation-owned retry and applies Passive inside that existing acceptance.
|
|
61
|
-
- Off aborts the owned copy/retry before acceptance and records child-owned native Off/pending-fork policy without publishing memory. A later explicit Passive/Active request
|
|
56
|
+
- Off aborts the owned copy/retry before acceptance and records child-owned native Off/pending-fork policy without publishing memory. A later explicit Passive/Active request copies the parent's current memory.
|
|
62
57
|
- Cancelling the Start waiter does not cancel that independently owned copy.
|
|
63
|
-
- Off, selection, shutdown, native Abort
|
|
58
|
+
- Off, selection, shutdown, native Abort and invalid source evidence can prevent acceptance.
|
|
64
59
|
|
|
65
60
|
**After acceptance:**
|
|
66
61
|
|
|
67
62
|
- Passive exposes both tools for child memory without active episode behavior; Off exposes neither.
|
|
68
63
|
- Ordinary memory-enabled cold reopening loads that child-owned state; Off defers loading it.
|
|
69
|
-
-
|
|
70
|
-
- Child-owned checkpoints use ordinary
|
|
64
|
+
- Navigating to an inherited parent step keeps current child-owned memory; it neither rewinds nor recopies parent data.
|
|
65
|
+
- Child-owned checkpoints use ordinary current-memory reload/resume without rereading the parent header.
|
|
71
66
|
|
|
72
67
|
**Before the first child-owned checkpoint:** cold recovery requires the explicit Off-deferred pending marker. Missing child files alone never authorize a parent recopy.
|
|
73
68
|
|
|
@@ -75,8 +70,8 @@ Memory-enabled native fork adoption and Start's exact-source retry use this tran
|
|
|
75
70
|
|
|
76
71
|
- A child-owned passive-projection reset prevents copied parent Stop markers from resurfacing after child reload.
|
|
77
72
|
- Inactive sources retain their selected mode, including a same-owner native failed-Stop policy that could not reach canonical config.
|
|
78
|
-
- A child inherits neither its parent's write fence nor its passive projection.
|
|
79
|
-
- Nested forks
|
|
73
|
+
- A child inherits neither its parent's write fence nor its passive projection. Parent current memory must be valid, and copying must pass CAS; ordinary activation policy is not overridden.
|
|
74
|
+
- Nested forks copy each direct parent's current memory. Ancestry is not recursively reconstructed.
|
|
80
75
|
|
|
81
76
|
## Support boundary
|
|
82
77
|
|
|
@@ -75,19 +75,19 @@ This is a maintained property-to-test map for the current canonical-file contrac
|
|
|
75
75
|
- `tests/temporal.test.ts` verifies hot-range and unavailable pre-origin boundaries; the real-Pi history-reader test rejects offset eight at the default limit seven without a transition.
|
|
76
76
|
- `tests/config.test.ts` exercises materialized and scope patch-history paths at limits 0, 1, 7, and 12, including single-path/one-item batch reads above seven and distinct configured versus actually retained boundaries.
|
|
77
77
|
|
|
78
|
-
### 17.
|
|
78
|
+
### 17. Memory never depends on the Pi step
|
|
79
79
|
|
|
80
|
-
- `tests/recovery.test.ts` rejects
|
|
81
|
-
- Extension/native tests
|
|
82
|
-
- Native “real Pi
|
|
80
|
+
- `tests/recovery.test.ts` rejects unsupported checkpoint envelopes without older-pointer or disabled-marker fallback.
|
|
81
|
+
- Extension/native tests prove old-step tree navigation, reload and resume keep current memory writable in Active and Passive; unreadable current files block Active visibly, Passive retries acceptance and Off releases inference only, with unchanged canonical bytes.
|
|
82
|
+
- Native “real Pi keeps current … memory after old-step tree selection and reload” cases cover passive, active and interrupted work plus the next provider's private-memory input.
|
|
83
83
|
- Runtime current-head tests preserve semantics, provenance, revisions, step and available history across old modes, distinguish absent from incomplete private authority, adopt validated foreign shared streams without private leakage or invented history, and reject a concurrent private writer.
|
|
84
84
|
- Native pre-runtime and inherited-fork-selection witnesses preserve current owned session memory instead of resetting it or recopying a parent.
|
|
85
85
|
- Repeated active Start leaves response reconciliation intact.
|
|
86
|
-
- Ordinary conversation with only a pre-runtime mode checkpoint still bootstraps; unaccepted fork identity/CWD repair retries the
|
|
86
|
+
- Ordinary conversation with only a pre-runtime mode checkpoint still bootstraps; unaccepted fork identity/CWD repair retries copying the parent's current memory.
|
|
87
87
|
|
|
88
|
-
### 18. Tree/resume
|
|
88
|
+
### 18. Tree/resume restore branch mode over current memory
|
|
89
89
|
|
|
90
|
-
- `tests/integration.test.ts` — “real Pi
|
|
90
|
+
- `tests/integration.test.ts` — “real Pi branch navigation through compaction restores branch modes over current memory” and “real Pi old tree branch stop and resume keep current semantics without rewinding any files”.
|
|
91
91
|
|
|
92
92
|
### 19. Stop changes policy, not semantic history
|
|
93
93
|
|
|
@@ -99,7 +99,7 @@ This is a maintained property-to-test map for the current canonical-file contrac
|
|
|
99
99
|
- Pure passive-selector tests cover missing, colliding and nonfinite recorded active anchors and explicit preservation of unfinished compilation.
|
|
100
100
|
- The native “real Pi repeated Start/Stop preserves uncompiled conversation and its prior boundary” cases cover initial/restarted bootstrap, repeated idle toggles, reload, unchanged native trace, and release after accepted compilation; extension tests cover interrupted idle Stop with and without a captured anchor.
|
|
101
101
|
- Completed idle and marker-based cutoffs remain bounded.
|
|
102
|
-
- The extension's failed-Stop matrix covers concurrent private writers, invalid lock ownership and malformed runtime files in both inactive modes: the selected mode remains applied, canonical bytes stay unchanged, accepted memory and native conversation survive, and only Passive projects the handoff; reload is read-only, and writes remain fenced until accepted Start.
|
|
102
|
+
- The extension's failed-Stop matrix covers concurrent private writers, invalid lock ownership and malformed runtime files in both inactive modes: the selected mode remains applied, canonical bytes stay unchanged, accepted memory and native conversation survive, and only Passive projects the handoff; reload is read-only, and writes remain fenced until accepted Start or a successful explicit Passive retry; failed retries add no duplicate fence.
|
|
103
103
|
- Native “real Pi failed Stop stays passive through late tools, tree, reload and resume” cases verify provider inputs, rejected tool calls, untouched trace prefixes, private memory, current foreign writes, and recovery through explicit Start.
|
|
104
104
|
- A native fork witness retains disabled policy without inheriting the parent's fence.
|
|
105
105
|
- Session tests bind fence lifetime to owner/reset/accepted-checkpoint evidence; runtime current-head tests prove read-only loading changes no canonical bytes.
|
|
@@ -193,20 +193,18 @@ This is a maintained property-to-test map for the current canonical-file contrac
|
|
|
193
193
|
- Native “real Pi Abort cancels an in-run Start without waiting for the canonical owner or another provider call” uses the actual command and active operation signal: cancellation returns while the store remains held, without changed files/checkpoints, another provider call or late activation.
|
|
194
194
|
- Idle/no-signal waits and the separate initial-attachment/fork recovery paths are not certified by that Abort witness.
|
|
195
195
|
|
|
196
|
-
### 31.
|
|
196
|
+
### 31. Branch attachment accepts one coherent current cohort
|
|
197
197
|
|
|
198
|
-
-
|
|
199
|
-
-
|
|
200
|
-
-
|
|
201
|
-
- Further witnesses cover expiry during the wait, missing/malformed/foreign authority, private checkpoint/runtime CAS races, rollback/retry, expired/single-use capabilities and post-acceptance failure.
|
|
202
|
-
- No current-head/empty fallback, invented history or unaccepted cache installation is permitted.
|
|
198
|
+
- Attachment uses the current-head Start transaction, whose witnesses cover foreign shared adoption, incomplete private storage, noncooperating private replacement, single-use acceptance and preserved cohorts on publication failure.
|
|
199
|
+
- Runtime attach/fork cases reject contradictory session lineage without installing a cache or changing files.
|
|
200
|
+
- No empty fallback, invented history or unaccepted cache installation is permitted; there is no boundary-restoration API.
|
|
203
201
|
- Native caller cutover evidence is item 35.
|
|
204
202
|
|
|
205
|
-
### 32. Awaited
|
|
203
|
+
### 32. Awaited fork copies current parent memory and preserves parent and child authority
|
|
206
204
|
|
|
207
|
-
- Runtime
|
|
208
|
-
- An independent partial writer held over two seconds proves responsive cancellation, pinned source identity/checkpoint, current shared adoption and
|
|
209
|
-
-
|
|
205
|
+
- Runtime fork cases cover limits 0/1/12 from an old step, current artifact provenance and contradictory lineage.
|
|
206
|
+
- An independent partial writer held over two seconds proves responsive cancellation, pinned source identity/checkpoint, current shared adoption and private copying without parent/foreign-private changes. The extension pins the parent's current head, so native fork copies never depend on the fork step.
|
|
207
|
+
- Competing child acceptances prove post-wait checks.
|
|
210
208
|
- Every occupied child file, unsupported storage evidence, invalid/missing parent authority and parent/child byte races refuse publication.
|
|
211
209
|
- Fault injection proves rollback/retry; expired/single-use capabilities and post-acceptance checkpoint failure cannot replace accepted child memory.
|
|
212
210
|
- Child lifecycle resets step and unfinished specification while retaining selected mode/bootstrap; later child writes leave the parent unchanged.
|
|
@@ -304,7 +302,7 @@ This is a maintained property-to-test map for the current canonical-file contrac
|
|
|
304
302
|
- `tests/config.test.ts` and `tests/snapshot.test.ts` cover enum round trips, read-only compatibility decoding, invalid/mixed session policies and pre-runtime mode retention without semantic initialization.
|
|
305
303
|
- Native global-default tests prove later defaults affect only new sessions.
|
|
306
304
|
- Extension inactive-choice matrices prove coalescing, no semantic revision and last-choice wins.
|
|
307
|
-
- Held-store “fenced reload preserves …” cases cover
|
|
305
|
+
- Held-store “fenced reload preserves …” cases cover Off with unchanged canonical bytes and retained fence, and Passive joining read-only recovery before accepting current memory and staying writable across reload.
|
|
308
306
|
- Telegram “pre-runtime Telegram Passive reports only its current successful selection” proves truthful success after cache installation and suppression of superseded receipts through the real composition port.
|
|
309
307
|
|
|
310
308
|
|
|
@@ -401,9 +399,9 @@ This is a maintained property-to-test map for the current canonical-file contrac
|
|
|
401
399
|
- Current-head Start and accepted-runtime Stop are covered above; optional settlement backup uses the selected no-signal deferral rather than an upstream release gate.
|
|
402
400
|
- `tests/runtime.test.ts` and native Pi lifecycle tests cover retained-boundary restart, immediate barriers, finalized response, config-only stop, and unavailable-reference provenance.
|
|
403
401
|
- Canonical files supply current state and bounded hot history; arbitrary cold revision recovery is unsupported.
|
|
404
|
-
- `tests/runtime.test.ts`
|
|
402
|
+
- `tests/runtime.test.ts` covers fork after lowering `historyLimit` to 0/1; native integration proves reload keeps current state and exactly the retained window, parent-private fork files remain unchanged, and later increases do not reconstruct discarded history.
|
|
405
403
|
- `tests/config.test.ts` covers optional agent configuration, path precedence/expansion, invalid input, load-time caching and read-only behavior.
|
|
406
|
-
- Session tests and native Pi distinguish configured new-session auto-start from branch-
|
|
404
|
+
- Session tests and native Pi distinguish configured new-session auto-start from branch-mode resume/tree/stop over current memory.
|
|
407
405
|
- `tests/extension.test.ts` proves registered artifacts are reconciled only at enabled inference boundaries.
|
|
408
406
|
- The global default is Off without a configured mode; CWD materialization alone never grants Active mode.
|
|
409
407
|
|
|
@@ -35,7 +35,7 @@ Each `patch_state` is an inference barrier, not automatically the end of an iter
|
|
|
35
35
|
|
|
36
36
|
Native compaction is separate from model-context projection; its safety checks and usage threshold still apply.
|
|
37
37
|
|
|
38
|
-
Active, Passive and Off select the session's workflow and model-facing access, not a different storage algorithm. Native Off attachment defers memory acquisition, including creation of a fork's private memory, until Passive or Active is explicitly selected. Once acquired, a fork owns Session state copied from the
|
|
38
|
+
Active, Passive and Off select the session's workflow and model-facing access, not a different storage algorithm. Native Off attachment defers memory acquisition, including creation of a fork's private memory, until Passive or Active is explicitly selected. Once acquired, a fork owns Session state copied from the parent's current memory and lives independently in its selected mode. See [fork support](#fork-support-and-limits).
|
|
39
39
|
|
|
40
40
|
### Lifecycle operations
|
|
41
41
|
|
|
@@ -44,8 +44,8 @@ Active, Passive and Off select the session's workflow and model-facing access, n
|
|
|
44
44
|
- Starting mid-conversation keeps Pi's active context for one complete bootstrap run, during which the agent must compile future-relevant information into state.
|
|
45
45
|
- Repeating Active while already active leaves the in-progress run unchanged.
|
|
46
46
|
- On an attached branch, activation waits asynchronously for a coherent canonical cohort; pending repeats share the wait.
|
|
47
|
-
- Until acceptance, the existing inactive mode
|
|
48
|
-
- Cancelling a pending Active from Off preserves later acquisition choices
|
|
47
|
+
- Until acceptance, the existing inactive mode and any write fence stay in effect.
|
|
48
|
+
- Cancelling a pending Active from Off preserves later acquisition choices; ordinary cancellation creates no write fence.
|
|
49
49
|
- Passive, Off or a branch selection can withdraw an obsolete activation. An error after acceptance does not undo accepted memory.
|
|
50
50
|
|
|
51
51
|
How each lifecycle event behaves:
|
|
@@ -54,9 +54,10 @@ How each lifecycle event behaves:
|
|
|
54
54
|
- An inactive default is recorded once in Pi as `{mode:"off"}` or `{mode:"passive"}`, without creating semantic storage.
|
|
55
55
|
- An Active default initializes a distinct empty Session layer over global/CWD memory, never another session's private continuation.
|
|
56
56
|
- **Resume:** Keeps the selected session's mode; later global default changes do not override it.
|
|
57
|
-
- Passive/Active
|
|
57
|
+
- Passive/Active attach the current same-session memory and its retained history.
|
|
58
58
|
- Off attaches native policy only, without probing semantic files or emitting recovery warnings.
|
|
59
|
-
- **Tree navigation:**
|
|
59
|
+
- **Tree navigation:** Restores the selected branch's mode, but never rewinds memory: State Flow does not depend on the Pi step. Passive/Active keep the current JSON state of every scope, which changes only through accepted patches. Off defers acquisition until a mode is explicitly selected.
|
|
60
|
+
- **Fork:** The child copies its parent's current memory into its own session layer, independent of the step it forked from.
|
|
60
61
|
- **Abort inference:** Stops generation or an outstanding response-publication wait. Already accepted patches stay durable, so work and corrected direction can continue in the same session.
|
|
61
62
|
- Cancellation before response acceptance keeps the previous response and the unfinished run.
|
|
62
63
|
- Cancellation after acceptance never rolls it back.
|
|
@@ -75,7 +76,7 @@ How each lifecycle event behaves:
|
|
|
75
76
|
- The selected Passive policy stays applied. Accepted memory and the native conversation stay intact.
|
|
76
77
|
- Pi records the selected mode and a write fence, not a replacement semantic checkpoint. This needs a writable Pi trace and never repairs storage; native fenced policy overrides an older canonical config.
|
|
77
78
|
- Tree/reload/resume in Passive read validated current same-session memory without publishing or restoring an older selection.
|
|
78
|
-
- Off keeps the native policy and the write fence without reading memory, and still exposes no State Flow context or tools
|
|
79
|
+
- Off keeps the native policy and the write fence without reading memory, and still exposes no State Flow context or tools. A later explicit Passive retries current-memory acceptance; success clears the fence.
|
|
79
80
|
- Newer mode choices survive an in-flight read-only recovery. Repeating the same choice is inert; changing the inactive mode updates only native policy and keeps the fence.
|
|
80
81
|
- Explicit Active clears the fence only after canonical acceptance.
|
|
81
82
|
- **Continue in Passive after Active:** The same physical session projects a frozen state handoff, any interrupted current request and tool trajectory (including late results), and the conversation after Stop. Which earlier conversation is kept:
|
|
@@ -101,11 +102,10 @@ State Flow does not undo tool effects. After an interruption or a return to an o
|
|
|
101
102
|
|
|
102
103
|
### Fork support and limits
|
|
103
104
|
|
|
104
|
-
**What a fork copies.** Memory-enabled native fork replacement copies the
|
|
105
|
+
**What a fork copies.** Memory-enabled native fork replacement copies the parent's **current** session checkpoint, retained patch tail and matching provenance into the new session's own storage, independent of the Pi step it forked from.
|
|
105
106
|
|
|
106
107
|
- Off records only a child-owned pending-fork policy. Header/store reads and copying wait until an explicit Passive/Active, including after a cold reload.
|
|
107
108
|
- Global/CWD values and provenance stay current. Applying a smaller `historyLimit` may fold shared tails under CAS.
|
|
108
|
-
- An earlier fork selection copies that point's private state, not the parent's later private work.
|
|
109
109
|
- Parent-private data and history stay intact. The selected mode is kept, so an inactive source does not become Active automatically.
|
|
110
110
|
|
|
111
111
|
**The child's own history.** The child starts at step zero with a new temporal origin.
|
|
@@ -114,11 +114,11 @@ State Flow does not undo tool effects. After an interruption or a return to an o
|
|
|
114
114
|
- The child's own transitions build its hot window, and owned checkpoints support normal reload/resume.
|
|
115
115
|
- Parent Stop projection is not inherited, including after a child reload.
|
|
116
116
|
|
|
117
|
-
**Requirements for the initial copy:** a native fork start event, a regular canonical direct-parent session file, matching CWD/identity, a readable temporal source and an unused child namespace. Missing or unsafe evidence or a CAS conflict leaves the copy unavailable rather than importing unrelated
|
|
117
|
+
**Requirements for the initial copy:** a native fork start event, a regular canonical direct-parent session file, matching CWD/identity, a readable temporal source and an unused child namespace. Missing or unsafe evidence or a CAS conflict leaves the copy unavailable rather than importing unrelated private state. Explicit Start can retry an unaccepted copy in the same loaded fork once the cause is corrected.
|
|
118
118
|
|
|
119
119
|
**Limits:**
|
|
120
120
|
|
|
121
|
-
- Selecting a copied parent
|
|
121
|
+
- Selecting a copied parent step through the child's `/tree` keeps current child-owned memory; it neither rewinds nor recopies parent data.
|
|
122
122
|
- Cold recovery before the first child checkpoint requires an Off-deferred pending-fork marker. Otherwise, it and startup paths lacking the fork event remain unsupported.
|
|
123
123
|
- In-memory parent locators and cross-CWD imports remain unsupported.
|
|
124
124
|
- File-only copying requires an exact still-available source cohort.
|
|
@@ -144,7 +144,7 @@ The canonical store is `state-flow/` beneath the agent directory. Keeping config
|
|
|
144
144
|
- Active initializes missing storage when safe.
|
|
145
145
|
- Passive reads existing memory without publishing; its first explicit patch may initialize absent storage without starting an episode or compaction.
|
|
146
146
|
- Off exposes neither memory tools nor State Flow context.
|
|
147
|
-
- `logging`: Defaults to `false`. When enabled, rejected patch executions, active barrier blocks, preparation failures and accepted-answer reconciliation failures are recorded locally at `tmp/state-flow/logs.jsonl` beneath the agent directory. Asynchronous Git push failures are recorded there even when this setting is off.
|
|
147
|
+
- `logging`: Defaults to `false`. When enabled, rejected patch executions, active barrier blocks, preparation failures and accepted-answer reconciliation failures are recorded locally at `tmp/pi-state-flow/logs.jsonl` beneath the agent directory. Older `tmp/state-flow` logs are left untouched and are not migrated. Asynchronous Git push failures are recorded there even when this setting is off.
|
|
148
148
|
- `showSuccessfulPatches`: Defaults to `true`. In interactive Pi, `patch_state` rows show pretty-printed JSON arguments once in the call, with blank lines between adjacent memory sections; the result shows the acceptance or no-op acknowledgement, never a second patch. Set it to `false` to hide call arguments and keep the compact acknowledgement. Rejected calls retain their arguments and error acknowledgement; State Flow adds no private validation turn.
|
|
149
149
|
- `historyLimit`: Defaults to `7` and accepts integers from `0` through `100`. It counts accepted semantic transitions, **not elapsed time or conversation length**, and bounds materialized-history and scope patch-history offsets.
|
|
150
150
|
- Lowering it on reload/restore/fork folds excess tails forward without losing current state; selected boundaries outside the new window become unavailable.
|
|
@@ -194,21 +194,21 @@ Treat logs and state files as private. Removing a secret from current state does
|
|
|
194
194
|
- A `Scope memory:` block with one line per scope that has content: the UTF-8 byte size of each present nonempty plane and, when `working` or `lazy` has top-level entries, the share owned by an open intent of that scope (for example `- cwd: intents 137 B, working 32 B; intent-owned working 1/2`). It is operator-only: no notice, threshold or model-facing effect.
|
|
195
195
|
- One JSON representation of effective global → CWD → session memory, with a blank line between top-level semantic planes. Nested JSON is unchanged; individual scope JSON remains available through `read_state`.
|
|
196
196
|
|
|
197
|
-
Status
|
|
197
|
+
Status reports the selected mode and any Active restoration inference fence, while omitting generic ownership/configuration prose. Failed inspection reports unavailable evidence, not invented empty state. Status is observational: it does not read source files, calculate fingerprints, create invalidations or mutate semantic state.
|
|
198
198
|
|
|
199
199
|
**Revisions and indicators:**
|
|
200
200
|
|
|
201
|
-
- The terminal indicator is accent `state-flow` plus dim `active` or `passive`; Off hides it.
|
|
201
|
+
- The terminal indicator is accent `state-flow` plus dim `active` or `passive`; Off hides it. Failed Active restoration stays visible as `active (blocked)`, never as an apparently inactive mode.
|
|
202
202
|
- Global, CWD and Session own independent semantic revisions. One atomic transition advances each materially changed scope once, including session-only response reconciliation.
|
|
203
203
|
- Effective has no scalar counter. It uses the compact lowercase `g#c#s#` revision vector (for example, `g15c8s31`), with no slashes or spaces between counters. The vector appears in `/state-flow-status` and in Telegram's Effective inspection, not in the compact indicators.
|
|
204
204
|
|
|
205
205
|
### Telegram controls
|
|
206
206
|
|
|
207
|
-
When `pi-telegram` is available, its main-menu section shows `State Flow: active`, `State Flow: passive` or `State Flow: off`. The adapter is optional; the Pi commands work without it. All Telegram controls use the same lifecycle owners as the terminal commands.
|
|
207
|
+
When `pi-telegram` is available, its main-menu section shows `State Flow: active`, `State Flow: passive` or `State Flow: off`. Failed Active restoration shows `State Flow: active (blocked)` and recovery guidance in the submenu; the Active control can retry current-memory acceptance. The adapter is optional; the Pi commands work without it. All Telegram controls use the same lifecycle owners as the terminal commands.
|
|
208
208
|
|
|
209
209
|
**Mode controls:**
|
|
210
210
|
|
|
211
|
-
- A horizontal radio row presents `Off | Passive | Active`. The selected option uses
|
|
211
|
+
- A horizontal radio row presents `Off | Passive | Active`. The selected option uses 🟣, 🟡 or 🟢 respectively; each inactive option uses ⚫️.
|
|
212
212
|
- Telegram Active requested during a run waits for settlement; Passive and Off apply immediately.
|
|
213
213
|
- Ordinary successful controls add no redundant mode receipt; diagnostic outcomes stay visible.
|
|
214
214
|
- Off exposes neither tool nor State Flow model context.
|
|
@@ -234,9 +234,8 @@ When `pi-telegram` is available, its main-menu section shows `State Flow: active
|
|
|
234
234
|
**Inspecting while Off.** Explicit Off inspection reads current stored memory through a disposable reader.
|
|
235
235
|
|
|
236
236
|
- Session and Effective require validated same-session private authority and cannot show a fabricated empty layer or revision. Shared Global/CWD inspection stays available independently of private failures.
|
|
237
|
-
- These reads install no model/runtime cache, change no bytes or mode, clear no write fence, and leave
|
|
237
|
+
- These reads install no model/runtime cache, change no bytes or mode, clear no write fence, and leave pending fork acquisition intact for a future Passive/Active selection.
|
|
238
238
|
- Automatic Off callbacks never acquire memory.
|
|
239
|
-
- Current stored data does not prove that a selected past boundary is restorable.
|
|
240
239
|
|
|
241
240
|
Open implementation work is tracked in [BACKLOG.md](../BACKLOG.md).
|
|
242
241
|
|
|
@@ -277,25 +276,25 @@ See the [storage contract](architecture.md#storage-and-identity) for the exact l
|
|
|
277
276
|
- semantic/metadata boundary mismatches and identity contradictions;
|
|
278
277
|
- partial session runtime evidence.
|
|
279
278
|
|
|
280
|
-
|
|
279
|
+
Memory never depends on the Pi step, so an old or expired branch checkpoint is not a failure: attachment always uses the current same-session files. State Flow does not substitute Git history, empty memory or another session's files.
|
|
281
280
|
|
|
282
|
-
**
|
|
281
|
+
**When current session memory is unreadable** (missing, corrupt, partial or contradictory files):
|
|
283
282
|
|
|
284
|
-
-
|
|
285
|
-
-
|
|
286
|
-
-
|
|
287
|
-
-
|
|
283
|
+
- Under Active, the selected mode remains Active and the indicator shows `active (blocked)`. Live inference is aborted before the provider instead of silently sending native history under an inactive fallback. Reload/resume retains this fence. Repair the files and choose Active/Passive; explicit Off permits native context without reading memory. Signal-less inspection remains observational.
|
|
284
|
+
- Global/CWD memory stays readable; the unavailable session layer is never replaced by an empty one.
|
|
285
|
+
- Session reads and every `patch_state` refuse without changing canonical files or appending substitute checkpoints.
|
|
286
|
+
- **Modes are stable.** Explicit Passive accepts validated current same-session memory exactly like Active, keeping Passive policy. Only while current memory is still unreadable or unpublishable does Passive keep native inference with paused writes and report the cause. Off records native policy only.
|
|
288
287
|
- Status distinguishes a write fence from unavailable materialization.
|
|
289
288
|
|
|
290
|
-
**Explicit Start uses current memory
|
|
289
|
+
**Explicit Start uses current memory.**
|
|
291
290
|
|
|
292
291
|
- It independently validates the current same-session canonical cohort, preserving private memory, artifact provenance, revisions, step and available aligned history.
|
|
293
292
|
- Expired active/passive pointers and unfinished runtime work do not block activation. A pre-runtime selection also keeps current accepted same-session memory instead of resetting it.
|
|
294
293
|
- Start bootstraps the conversation available on the selected Pi branch, without resurrecting an old unfinished specification or claiming that expired historical private state was restored.
|
|
295
294
|
- Independently advanced shared scopes may require a new temporal origin; unavailable history is never invented.
|
|
296
295
|
- Exact-cohort CAS rejects a concurrent writer, and incomplete or corrupt storage stays untouched.
|
|
297
|
-
- An unaccepted native fork
|
|
298
|
-
- When evidence is missing, repair it
|
|
296
|
+
- An unaccepted native fork retries copying its parent's current memory rather than inventing child memory.
|
|
297
|
+
- When evidence is missing, repair it or open a genuinely new Pi session.
|
|
299
298
|
|
|
300
299
|
**Artifact evidence and replication:**
|
|
301
300
|
|
|
@@ -307,7 +306,7 @@ See the complete [filesystem recovery contract](filesystem-recovery.md).
|
|
|
307
306
|
|
|
308
307
|
### Canonical files and optional Git backup
|
|
309
308
|
|
|
310
|
-
Canonical scope/runtime files own the current materialization and retained hot history, whether or not Git is available. Pi checkpoints
|
|
309
|
+
Canonical scope/runtime files own the current materialization and retained hot history, whether or not Git is available. Pi checkpoints record mode and run lifecycle for a branch, not a Git commit or a memory revision to rewind to. Restart and branch navigation always attach the current files; historical states remain available only through explicit `read_state` offsets within retained history.
|
|
311
310
|
|
|
312
311
|
**Local backup commit:**
|
|
313
312
|
|