@llblab/pi-kit 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +10 -0
  3. package/README.md +6 -5
  4. package/node_modules/@llblab/pi-claude-usage/AGENTS.md +20 -0
  5. package/node_modules/@llblab/pi-claude-usage/BACKLOG.md +3 -0
  6. package/node_modules/@llblab/pi-claude-usage/CHANGELOG.md +13 -0
  7. package/node_modules/@llblab/pi-claude-usage/LICENSE +22 -0
  8. package/node_modules/@llblab/pi-claude-usage/README.md +110 -0
  9. package/node_modules/@llblab/pi-claude-usage/banner.jpg +0 -0
  10. package/node_modules/@llblab/pi-claude-usage/index.ts +1159 -0
  11. package/node_modules/@llblab/pi-claude-usage/package.json +60 -0
  12. package/node_modules/@llblab/pi-state-flow/AGENTS.md +42 -56
  13. package/node_modules/@llblab/pi-state-flow/BACKLOG.md +16 -3
  14. package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +19 -0
  15. package/node_modules/@llblab/pi-state-flow/README.md +15 -12
  16. package/node_modules/@llblab/pi-state-flow/dist/index.d.ts +2 -2
  17. package/node_modules/@llblab/pi-state-flow/dist/index.js +2 -2
  18. package/node_modules/@llblab/pi-state-flow/dist/lib/config.d.ts +7 -3
  19. package/node_modules/@llblab/pi-state-flow/dist/lib/config.js +16 -7
  20. package/node_modules/@llblab/pi-state-flow/dist/lib/context.d.ts +9 -9
  21. package/node_modules/@llblab/pi-state-flow/dist/lib/context.js +5 -4
  22. package/node_modules/@llblab/pi-state-flow/dist/lib/continuation.js +2 -2
  23. package/node_modules/@llblab/pi-state-flow/dist/lib/durable.d.ts +1 -1
  24. package/node_modules/@llblab/pi-state-flow/dist/lib/durable.js +7 -4
  25. package/node_modules/@llblab/pi-state-flow/dist/lib/episode.d.ts +3 -3
  26. package/node_modules/@llblab/pi-state-flow/dist/lib/episode.js +5 -5
  27. package/node_modules/@llblab/pi-state-flow/dist/lib/extension.d.ts +3 -5
  28. package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +275 -199
  29. package/node_modules/@llblab/pi-state-flow/dist/lib/history.d.ts +11 -4
  30. package/node_modules/@llblab/pi-state-flow/dist/lib/history.js +6 -7
  31. package/node_modules/@llblab/pi-state-flow/dist/lib/logging.d.ts +4 -1
  32. package/node_modules/@llblab/pi-state-flow/dist/lib/logging.js +1 -0
  33. package/node_modules/@llblab/pi-state-flow/dist/lib/query.d.ts +4 -5
  34. package/node_modules/@llblab/pi-state-flow/dist/lib/query.js +13 -13
  35. package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.d.ts +7 -6
  36. package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.js +9 -9
  37. package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.d.ts +3 -2
  38. package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.js +17 -12
  39. package/node_modules/@llblab/pi-state-flow/dist/lib/session.d.ts +4 -1
  40. package/node_modules/@llblab/pi-state-flow/dist/lib/session.js +2 -1
  41. package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.d.ts +17 -8
  42. package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.js +49 -20
  43. package/node_modules/@llblab/pi-state-flow/dist/lib/state.d.ts +22 -3
  44. package/node_modules/@llblab/pi-state-flow/dist/lib/state.js +30 -10
  45. package/node_modules/@llblab/pi-state-flow/dist/lib/status.d.ts +5 -3
  46. package/node_modules/@llblab/pi-state-flow/dist/lib/status.js +19 -28
  47. package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.d.ts +17 -15
  48. package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.js +52 -52
  49. package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.d.ts +8 -4
  50. package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.js +34 -18
  51. package/node_modules/@llblab/pi-state-flow/dist/lib/transition.d.ts +5 -5
  52. package/node_modules/@llblab/pi-state-flow/dist/lib/transition.js +13 -19
  53. package/node_modules/@llblab/pi-state-flow/dist/package.json +3 -3
  54. package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-guide/SKILL.md +2 -2
  55. package/node_modules/@llblab/pi-state-flow/docs/README.md +2 -1
  56. package/node_modules/@llblab/pi-state-flow/docs/agent-contract-relocation.md +72 -0
  57. package/node_modules/@llblab/pi-state-flow/docs/architecture.md +36 -32
  58. package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +12 -4
  59. package/node_modules/@llblab/pi-state-flow/docs/fork-contract.md +5 -5
  60. package/node_modules/@llblab/pi-state-flow/docs/lazy-state.md +6 -6
  61. package/node_modules/@llblab/pi-state-flow/docs/performance.md +1 -1
  62. package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +13 -12
  63. package/node_modules/@llblab/pi-state-flow/docs/usage.md +32 -29
  64. package/node_modules/@llblab/pi-state-flow/index.ts +3 -2
  65. package/node_modules/@llblab/pi-state-flow/lib/config.ts +20 -10
  66. package/node_modules/@llblab/pi-state-flow/lib/context.ts +15 -14
  67. package/node_modules/@llblab/pi-state-flow/lib/continuation.ts +1 -1
  68. package/node_modules/@llblab/pi-state-flow/lib/durable.ts +8 -6
  69. package/node_modules/@llblab/pi-state-flow/lib/episode.ts +6 -6
  70. package/node_modules/@llblab/pi-state-flow/lib/extension.ts +274 -197
  71. package/node_modules/@llblab/pi-state-flow/lib/history.ts +16 -11
  72. package/node_modules/@llblab/pi-state-flow/lib/logging.ts +5 -1
  73. package/node_modules/@llblab/pi-state-flow/lib/query.ts +16 -16
  74. package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +11 -11
  75. package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +19 -13
  76. package/node_modules/@llblab/pi-state-flow/lib/session.ts +6 -3
  77. package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +55 -22
  78. package/node_modules/@llblab/pi-state-flow/lib/state.ts +46 -13
  79. package/node_modules/@llblab/pi-state-flow/lib/status.ts +23 -32
  80. package/node_modules/@llblab/pi-state-flow/lib/telegram.ts +66 -65
  81. package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +39 -19
  82. package/node_modules/@llblab/pi-state-flow/lib/transition.ts +19 -27
  83. package/node_modules/@llblab/pi-state-flow/package.json +3 -3
  84. package/node_modules/@llblab/pi-state-flow/skills/state-flow-guide/SKILL.md +2 -2
  85. package/node_modules/@llblab/pi-telegram/AGENTS.md +1 -1
  86. package/node_modules/@llblab/pi-telegram/CHANGELOG.md +5 -0
  87. package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.d.ts +2 -0
  88. package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.js +55 -2
  89. package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.d.ts +21 -0
  90. package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.js +144 -1
  91. package/node_modules/@llblab/pi-telegram/dist/lib/bus.d.ts +9 -0
  92. package/node_modules/@llblab/pi-telegram/dist/lib/bus.js +19 -0
  93. package/node_modules/@llblab/pi-telegram/dist/lib/commands.d.ts +13 -0
  94. package/node_modules/@llblab/pi-telegram/dist/lib/commands.js +29 -6
  95. package/node_modules/@llblab/pi-telegram/dist/lib/extension.js +16 -0
  96. package/node_modules/@llblab/pi-telegram/dist/lib/locks.js +5 -1
  97. package/node_modules/@llblab/pi-telegram/dist/lib/polling.js +6 -2
  98. package/node_modules/@llblab/pi-telegram/dist/lib/threads.d.ts +7 -0
  99. package/node_modules/@llblab/pi-telegram/dist/lib/threads.js +13 -5
  100. package/node_modules/@llblab/pi-telegram/dist/package.json +1 -1
  101. package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +2 -2
  102. package/node_modules/@llblab/pi-telegram/docs/public-api.md +1 -1
  103. package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +79 -1
  104. package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +197 -0
  105. package/node_modules/@llblab/pi-telegram/lib/bus.ts +33 -0
  106. package/node_modules/@llblab/pi-telegram/lib/commands.ts +38 -6
  107. package/node_modules/@llblab/pi-telegram/lib/extension.ts +15 -0
  108. package/node_modules/@llblab/pi-telegram/lib/locks.ts +6 -1
  109. package/node_modules/@llblab/pi-telegram/lib/polling.ts +10 -2
  110. package/node_modules/@llblab/pi-telegram/lib/threads.ts +19 -5
  111. package/node_modules/@llblab/pi-telegram/package.json +1 -1
  112. package/package.json +7 -3
@@ -1,6 +1,6 @@
1
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 release tracking.
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
 
@@ -19,7 +19,7 @@ The child receives:
19
19
  - its own UUID, native session key, runtime metadata, and fresh lineage origin;
20
20
  - the selected parent session materialization and matching artifact provenance;
21
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.
22
+ - selected `mode` and bootstrap lifecycle state, with step reset to zero and no inherited unfinished specification or validation diagnostic.
23
23
 
24
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.
25
25
 
@@ -29,11 +29,11 @@ Artifact provenance is current-only, not a historical registry. Any retained par
29
29
 
30
30
  `TemporalRuntime.withForkTransaction(source, checkpoint, action, signal?)` pins source identity/boundary before waiting and selects exact parent authority plus an unoccupied child under one awaited exclusion. The caller rechecks native selection/policy and publishes its child lifecycle synchronously once. Parent evidence is revalidated before publication, the child cohort is CAS-protected, and only accepted memory installs. Cancellation or rejection cannot initialize an empty child; post-acceptance failure cannot roll it back or authorize another parent copy. Existing child storage, identity mismatch, missing parent files, malformed storage, concurrency conflict, or an expired boundary fails closed.
31
31
 
32
- Native fork adoption and Start's exact-source retry use this transaction inside the extension's owned restoration lifetime; the synchronous `prepareBoundaryFork()` adapter remains public only until consumer cleanup. Both paths publish 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.
32
+ Native fork adoption and Start's exact-source retry use this transaction inside the extension's owned restoration lifetime; the synchronous `prepareBoundaryFork()` adapter remains supported for library consumers. Both paths publish 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.
33
33
 
34
- A failed or expired selection never substitutes the parent's current/newer private state and never falls through to an older disabled marker. In the same live extension instance, explicit Start may retry the unaccepted fork after missing identity or storage evidence is corrected. Stop does not cancel an in-flight fork or its Start-owned retry: it selects passive child policy, which is applied inside the existing fork acceptance. Cancelling the Start waiter does not cancel that independently owned copy. After acceptance, configured passive tools can patch child memory without enabling active behavior; ordinary cold reopening loads that child-owned state. Selection, shutdown, native Abort, invalid source evidence and expired history still can prevent acceptance. Recovery of forks abandoned before this correction is not certified; missing child files never authorize a parent recopy. Once child storage has been accepted, explicit Start can activate its validated current child-owned memory even after selecting an inherited parent checkpoint; this neither restores parent history nor copies newer parent data. Child-owned checkpoints subsequently use ordinary retained-boundary reload/resume without rereading the parent header.
34
+ A failed or expired selection never substitutes the parent's current/newer private state and never falls through to an older disabled marker. In the same live extension instance, explicit Start may retry the unaccepted fork after missing identity or storage evidence is corrected. Passive/Off selection does not cancel an in-flight fork or its activation-owned retry: the latest requested inactive mode is applied inside the existing fork acceptance. Cancelling the Start waiter does not cancel that independently owned copy. After acceptance, Passive exposes both tools for child memory without active episode behavior, while Off exposes neither; ordinary cold reopening loads that child-owned state. Selection, shutdown, native Abort, invalid source evidence and expired history still can prevent acceptance. Cold recovery before the first child-owned checkpoint remains unsupported; missing child files never authorize a parent recopy. Once child storage has been accepted, explicit Start can activate its validated current child-owned memory even after selecting an inherited parent checkpoint; this neither restores parent history nor copies newer parent data. Child-owned checkpoints subsequently use ordinary retained-boundary reload/resume without rereading the parent header.
35
35
 
36
- A child-owned passive-projection reset prevents copied parent Stop markers from resurfacing after child reload. Disabled sources remain disabled, including a same-owner native failed-Stop policy that could not reach canonical config. A child inherits neither that parent's write fence nor its passive projection; source history must still be provable and copying must pass CAS. Ordinary activation policy is not overridden. Nested forks require each direct parent boundary to remain retained; ancestry is not recursively reconstructed.
36
+ A child-owned passive-projection reset prevents copied parent Stop markers from resurfacing after child reload. Inactive sources retain their selected mode, including a same-owner native failed-Stop policy that could not reach canonical config. A child inherits neither that parent's write fence nor its passive projection; source history must still be provable and copying must pass CAS. Ordinary activation policy is not overridden. Nested forks require each direct parent boundary to remain retained; ancestry is not recursively reconstructed.
37
37
 
38
38
  ## Support boundary
39
39
 
@@ -4,7 +4,7 @@ This document describes the implemented lazy-state contract. [BACKLOG.md](../BAC
4
4
 
5
5
  ## Thesis
6
6
 
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.
7
+ State Flow provides `lazy` as an object-root semantic plane in every scope's runtime view. It may be absent from stored state; reads then use `{}` or values inherited through the effective overlay without rewriting storage. 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,7 +34,7 @@ The model-facing surface remains small:
34
34
 
35
35
  ## Semantic model
36
36
 
37
- Each scope contains six semantic planes in intent-first presentation order:
37
+ Runtime views select present documented semantic planes in intent-first order, omitting absent fields, empty responses and unknown fields:
38
38
 
39
39
  ```text
40
40
  global | CWD | session
@@ -46,7 +46,7 @@ global | CWD | session
46
46
  └── lazy
47
47
  ```
48
48
 
49
- `intents`, `contract`, `working`, and `artifacts` remain hot in every scope. Session-owned `response` is also hot; Global and CWD keep only its required empty structural slot, and Effective inherits the Session value. `intents` may keep compact active direction while referring to large supporting detail in `lazy`. `lazy` differs only in projection policy:
49
+ `intents`, `contract`, `working`, and `artifacts` remain hot in every scope. Session-owned `response` is also hot; New Global and CWD states use an empty structural slot; stored scopes may omit it. Effective uses the highest-priority present response, and each newly accepted answer is written only in Session. `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
  - Its bodies are excluded from automatic state and recent-transition projections, including lazy writes, replacements and deletions. Empty visible patches/transitions disappear without renumbering history; hot changes remain visible.
@@ -63,7 +63,7 @@ Reference repair is reactive, not a maintenance scan. The agent does not enumera
63
63
 
64
64
  Missing paths or runtime hints alone do not require historical search. The agent may choose a targeted historical read when a previous value is useful to the current task, without separate user permission; otherwise continue without searching. Found values are historical evidence, not automatically current memory. Never automatically restore deleted data, scan all offsets, hydrate bodies or trigger repair inference. The reverse lookup searches current reference owners only, never history. A proven stale reference can be repaired within touched work without resurrecting its target.
65
65
 
66
- The `lazy` root must be an object. Its nested values may include arrays, objects, and scalars, for example:
66
+ When present, the `lazy` root must be an object. Its nested values may include arrays, objects, and scalars, for example:
67
67
 
68
68
  ```json
69
69
  ["important thought", "next thought"]
@@ -114,7 +114,7 @@ Active obligations, current constraints, unresolved next actions, and facts requ
114
114
  }
115
115
  ```
116
116
 
117
- `projection` defaults to `value`. A batch uses one projection for every path, evaluates every path against one captured state view, and returns results in request order. Duplicate paths remain duplicate results. If any path is invalid, the whole read fails; there is no mixed partial result.
117
+ `projection` defaults to `value`. A batch uses one projection for every path, evaluates every path against one captured state view, and returns results in request order. Duplicate paths remain duplicate results. An absent documented top-level field has value `null`, including an empty or absent `response`; the root view simply omits it. If any other path is invalid, the whole read fails; there is no mixed partial result.
118
118
 
119
119
  The single `path` form is first-class. The retired top-level `offset` and `scope` inputs are rejected; history and ownership belong in the semantic path itself, such as `cwd[1].lazy.memory`.
120
120
 
@@ -456,7 +456,7 @@ Lazy trees are co-located in canonical scope checkpoints/tails and use the same
456
456
 
457
457
  ## Normative invariants
458
458
 
459
- 1. **Object root, ordinary JSON children**: Every scope has a lazy object whose nested values contain domain semantics, never mandatory State Flow record wrappers.
459
+ 1. **Object root, ordinary JSON children**: Every runtime scope view has a lazy object, defaulting to `{}` when absent from stored semantics. Its nested values contain domain semantics, never mandatory State Flow record wrappers.
460
460
  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`.
461
461
  3. **Exact success**: A successful read returns everything requested; it never truncates or paginates silently.
462
462
  4. **Runtime-owned concurrency**: Revisions, locks, and CAS remain internal unless explicitly needed for diagnostics.
@@ -56,7 +56,7 @@ In that baseline, Stop handoff already reused a frozen message, unlike active an
56
56
 
57
57
  ### Frozen-head measurement
58
58
 
59
- The implemented projection freezes whole heads, including timestamps, and delivers accepted values and changing notices at stable tail positions. Active completion/new runs, native compaction/selection and Start/Stop are cache boundaries; passive user turns and patches are not. Volatile projection IDs distinguish current updates from retained results after a rebase. See [projection semantics](architecture.md#pi-lifecycle) for ownership and limits.
59
+ The implemented projection freezes whole heads, including timestamps, and delivers accepted values and changing notices at stable tail positions. Active completion/new runs, native compaction/selection and mode changes are cache boundaries; passive user turns and patches are not. Volatile projection IDs distinguish current updates from retained results after a rebase. See [projection semantics](architecture.md#pi-lifecycle) for ownership and limits.
60
60
 
61
61
  The identical trajectory workload (`1785e73e4992c3d986d2851f2d81963c0b0cfde8ceacfd4337659ebc9d1492ba`) on the same Node/Pi stack measured runtime SHA-256 `d2c424a52d55b0c1ca47a8b1a1beba9c0dda665c8f024d6aa3b6ad95af9d3b46`, with unchanged base commit and uncommitted implementation changes. Both source identities remained stable; all native workload assertions passed. Local report: `/tmp/state-flow-prefix-after.json`.
62
62
 
@@ -1,6 +1,6 @@
1
1
  # Temporal acceptance
2
2
 
3
- This is a maintained property-to-test map for the current canonical-file contract, not a second backlog or a substitute for running tests. Paths and quoted test names refer to a source checkout; tests are not shipped in the npm runtime package.
3
+ This is a maintained property-to-test map for the current canonical-file contract, not a second backlog or a substitute for running tests. Paths and quoted test names refer to a source checkout; tests are not shipped in the npm runtime package. Some test labels retain internal Start/Stop terminology: activation uses `/state-flow-active`; inactive scenarios explicitly select Passive or Off according to their tools/context assertions.
4
4
 
5
5
  ## Required properties and witnesses
6
6
 
@@ -20,10 +20,10 @@ This is a maintained property-to-test map for the current canonical-file contrac
20
20
  14. **Accepted response changes are transitions:** `tests/extension.test.ts` verifies that an ordinary accepted answer becomes runtime-owned `response` without a finalization patch or fallback inference, and “an empty accepted answer finalizes the run and stores an empty response” proves `""` is accepted after an earlier barrier. `tests/transition.test.ts` proves the empty value is an ordinary Session-owned semantic change when it replaces prior text.
21
21
  15. **Correct repeats succeed without semantic changes:** “accepts canonical atomic scope patches and correct repeats without another checkpoint” preserves canonical bytes and native checkpoint count on repetition, while still rejecting empty supplied scopes and obsolete finalization-shaped calls. Runtime current-head witnesses preserve revisions, lineage and step across identical patches and compilations; a changed accepted response remains a runtime-owned transition.
22
22
  16. **Configured hot-history bounds:** `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. `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.
23
- 17. **Historical restoration is distinct from activation:** `tests/recovery.test.ts` rejects unavailable selections without older-pointer or disabled-marker fallback. Extension/native tests fence passive publication until explicit current-memory activation, with unchanged canonical bytes and all passive-policy combinations. Native “real Pi activates current … memory after expired tree selection and reload” cases cover passive, active and interrupted work plus the next provider's private-memory input. 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. Native pre-runtime and inherited-fork-selection witnesses preserve current owned session memory instead of resetting it or recopying a parent. Repeated active Start leaves response reconciliation intact. Checkpoint-free ordinary conversation still bootstraps; unaccepted fork identity/CWD repair retries the exact source.
23
+ 17. **Historical restoration is distinct from activation:** `tests/recovery.test.ts` rejects unavailable selections without older-pointer or disabled-marker fallback. Extension/native tests fence passive publication until explicit current-memory activation, with unchanged canonical bytes in both inactive modes. Native “real Pi activates current … memory after expired tree selection and reload” cases cover passive, active and interrupted work plus the next provider's private-memory input. 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. Native pre-runtime and inherited-fork-selection witnesses preserve current owned session memory instead of resetting it or recopying a parent. Repeated active Start leaves response reconciliation intact. Ordinary conversation with only a pre-runtime mode checkpoint still bootstraps; unaccepted fork identity/CWD repair retries the exact source.
24
24
  18. **Tree/resume select the correct lineage:** `tests/integration.test.ts` — “real Pi preserves branch-local state through compaction and rejects an expired sibling after fresh-origin navigation” and “real Pi old tree branch stop and resume preserve selected semantics without rewinding shared files”.
25
- 19. **Stop changes policy, not semantic history:** `tests/runtime.test.ts` lifecycle-only witnesses use a separate process to advance global/CWD semantics or provenance, including wider foreign retention, then prove exact semantic/sidecar preservation, unchanged steps, idempotent Stop, and same-session/stale-evidence refusal. Native Stop/new-request witnesses verify the accepted shared view reaches handoff/inference without a lifecycle semantic write, while the current-head native witness accepts a shared write racing after inference and retains its actual accepted predecessor. Mid-tool Stop tests preserve ordinary/bootstrap trajectories through tree, reload, resume, and restart. The native “real Pi retains a native split-turn continuation through late tools” Stop/no-Stop controls actually remove the original user with native threshold compaction, then require summary, paired reads and foreign context in model input. The Stop case also checks frozen semantics/step, unchanged trace prefix, tree/reload/cold resume/bootstrap restart, no resurrection of discarded input, and persistent foreign context after the next active run. Pure passive-selector tests cover missing, colliding and nonfinite recorded active anchors and explicit preservation of unfinished compilation. 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. Completed idle/legacy cutoffs remain bounded. The extension's failed-Stop matrix covers concurrent private writers, invalid lock ownership and malformed runtime files across all passive-policy combinations: local mode turns off, canonical bytes stay unchanged, cached memory and available context survive, reload is read-only, and writes remain fenced until accepted Start. 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. A native fork witness retains disabled policy without inheriting the parent's fence. Session tests bind fence lifetime to owner/reset/accepted-checkpoint evidence; runtime current-head tests prove read-only loading changes no canonical bytes. `tests/storage.test.ts` fences lifecycle-only writes to config/runtime files; `tests/extension.test.ts` covers idle/legacy cutoffs and new/fork boundaries.
26
- 20. **Passive observability omits active status without hiding owner revisions:** `tests/status.test.ts` proves an accepted passive patch advances semantic history while compact terminal status stays absent. `tests/telegram.test.ts` drives the real extension port after Stop, requires the passive main-menu identity to render `State Flow: off`, verifies an owner Rich-state heading uses its independent `#revision` and Effective uses `G#/C#/S#`, and separately proves Telegram can lazily observe existing shared canonical state when passive model tools are disabled without initializing or mutating storage. A failed-Stop callback reports local disablement and keeps accepted cached memory inspectable without overwriting the concurrent writer.
25
+ 19. **Stop changes policy, not semantic history:** `tests/runtime.test.ts` lifecycle-only witnesses use a separate process to advance global/CWD semantics or provenance, including wider foreign retention, then prove exact semantic/sidecar preservation, unchanged steps, idempotent Stop, and same-session/stale-evidence refusal. Native Stop/new-request witnesses verify the accepted shared view reaches handoff/inference without a lifecycle semantic write, while the current-head native witness accepts a shared write racing after inference and retains its actual accepted predecessor. Mid-tool Stop tests preserve ordinary/bootstrap trajectories through tree, reload, resume, and restart. The native “real Pi retains a native split-turn continuation through late tools” Stop/no-Stop controls actually remove the original user with native threshold compaction, then require summary, paired reads and foreign context in model input. The Stop case also checks frozen semantics/step, unchanged trace prefix, tree/reload/cold resume/bootstrap restart, no resurrection of discarded input, and persistent foreign context after the next active run. Pure passive-selector tests cover missing, colliding and nonfinite recorded active anchors and explicit preservation of unfinished compilation. 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. Completed idle/legacy cutoffs remain bounded. 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. 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. A native fork witness retains disabled policy without inheriting the parent's fence. Session tests bind fence lifetime to owner/reset/accepted-checkpoint evidence; runtime current-head tests prove read-only loading changes no canonical bytes. `tests/storage.test.ts` fences lifecycle-only writes to config/runtime files; `tests/extension.test.ts` covers idle/legacy cutoffs and new/fork boundaries.
26
+ 20. **Compact mode, inspectable revisions:** `tests/status.test.ts` proves Active/Passive terminal indicators omit revisions, Off alone hides the indicator, and `/state-flow-status` retains the effective `g#c#s#` vector with blank lines between top-level JSON planes. `tests/telegram.test.ts` verifies mode-only section labels, capitalized radio options with one mode-specific selected marker and ⚫️ inactive markers, direct scope buttons, owner Rich headings with `#revision` and Effective with `g#c#s#`. Telegram can inspect existing shared memory even in Off without initializing or mutating storage. Failure-fenced inspection retains accepted cached memory without overwriting another writer.
27
27
  21. **Independent revisions survive folding and foreign writers:** `tests/temporal.test.ts` proves each materially changed scope advances once for sparse and multi-scope cohorts, response-only transitions advance only Session, no-ops advance none, selected retained history restores the matching revision, and folding never resets it. `tests/durable.test.ts` covers revision serialization plus the pre-revision 0.17 retained-tail baseline. `tests/runtime.test.ts` uses an independent file-backed writer to advance Global, then refreshes the first runtime without file mutation and proves `G1/C0/S1` becomes `G1/C0/S2` after one private Session patch.
28
28
  22. **Current-head atomic model publication:** `tests/runtime.test.ts` applies authored independent/overlapping assignments, deletion and arrays to current shared values, preserves another owner's private files, and derives the predecessor/revisions from that basis. Compilation witnesses replace complete cards with matching provenance, preserve untouched evidence, accept repeats and refuse orphaned evidence after semantic-pair disappearance. Partial/malformed shared evidence and concurrent/unselected private authority stay fenced. Fault injection rolls back a mixed publication without installing the candidate's shared adoption or private draft. Extension tests reject a first passive patch without publishing empty setup, and recheck acquired-source freshness after lock waiting. Native “real Pi awaits foreign publication” cases hold an independent process beyond the former wait budget, verify responsive waiting/cancellation with unchanged canonical bytes, and require the next provider to see accepted current Global/CWD plus its own Session, never the foreign private layer.
29
29
  23. **Awaited response acceptance owns its lifecycle:** `tests/extension.test.ts` verifies waiting against current shared memory, one accepted checkpoint without a second publication, rollback without candidate/cache or lifecycle installation, cancellation at Stop/session/tree/shutdown boundaries, shutdown fencing and superseding-answer isolation. Native “real Pi awaits response publication” witnesses wait behind an independent writer for over two seconds, then prove later boundary handlers and continuation inference see the accepted response, current Global/CWD and only their own Session. Native Abort withdraws the wait without changing canonical bytes, the prior response or unfinished specification, and without requesting a repair inference.
@@ -32,25 +32,26 @@ This is a maintained property-to-test map for the current canonical-file contrac
32
32
  26. **Advisory startup inspection awaits coherent evidence:** `tests/continuation.test.ts` pauses an independent publisher between private-tail and metadata replacement for over two seconds. Inspection and the default-launch recommendation wait; cancellation rejects without suggesting another session or changing bytes/lock ownership. After release, eligibility uses the complete accepted cohort. Absent/empty stores stay uninitialized; malformed, orphaned, symlinked and invalid-lock evidence stays ineligible. Async host callbacks preserve detached native headers and eligibility, cannot override native identity, and cannot return late decisions or inspect more candidates after cancellation. Existing native-session, shared-drift and private-lineage witnesses remain applicable; these are advisory APIs, not an installed native startup hook.
33
33
  27. **Awaited runtime-only acceptance preserves semantic authority:** `tests/runtime.test.ts` applies both raw and awaited lifecycle publication beside independently advanced Global/CWD state or evidence at limits 0/7, preserving wider stored tails, orphaned provenance, unknown metadata and private values. An independent publisher pauses mid-cohort for over two seconds; waiting/cancellation changes no accepted bytes/cache, and the post-wait callback uses current lifecycle input. Authority, malformed/partial/absent storage, private races, newer selections, single-use/expired capabilities and rollback remain fenced; correct repeats add no history. Native “real Pi context provides a cancellable lifecycle boundary” probes prove acceptance before the provider and actual Abort cancellation without later inference/publication. Those embedding probes establish the SDK seam; production preparation is covered separately below. No-transition patch publication passes the same wider-history/evidence matrix for complete accepted cohorts; an absence witness distinguishes its normal atomic initialization from the explicit lifecycle-only API, which still refuses missing semantic storage.
34
34
  28. **Pre-inference preparation accepts once or stops inference:** Extension witnesses prove capture/no-signal projection is read-only, current-head maintenance shares lifecycle acceptance, reappearing sources survive, duplicate contexts reuse preparation and pre-acceptance failure rolls back both maintenance and metadata. Abort, Stop, selection, shutdown and superseded runs preserve newer state/fences; post-acceptance failure cannot replay an old specification. Native “real Pi production preparation” holds an independent partial publisher for over two seconds, then proves matching `G2/C2/S2`, source/provenance cleanup and private isolation before the first provider, while the native missing-CWD witness preserves current-empty initialization without resurrection, or actual Abort with no publication/inference after release. Native fault injection proves public `ctx.abort()` fences Pi's otherwise fail-open context hook. Session/native tests retain uncheckpointed input through reload/Stop/cold resume and interrupted boundary-continuation tool evidence through idle Stop/reload, without inventing a run or reviving a completed specification.
35
- 29. **Awaited Stop preserves immediate policy and accepted authority:** Extension tests prove immediate passive projection, one runtime-only acceptance for repeated pending Stops, current shared adoption with unchanged semantic/provenance bytes, and lifecycle derivation after an intervening same-instance passive patch. Operation cancellation keeps mode off and fences writes; selection/shutdown/accepted Start withdraw obsolete work without later mutation, while rejected Start leaves Stop pending. Publication faults roll back config/runtime without installing shared adoption; native checkpoint faults after acceptance do not roll back or retry writes. Native “real Pi stop keeps local mode off while awaiting a partial foreign publication without private leakage” holds an independent writer for over two seconds, then requires current Global/CWD plus local Session in passive provider input. Telegram controls acknowledge early, await results, escape late errors and suppress revoked/navigated/disposed views; legacy synchronous controls remain compatible.
36
- 30. **Awaited Start activates current authority without stale rollback:** Runtime witnesses preserve semantics, provenance, revisions, step and aligned history across old mode/unfinished-work combinations; expired/single-use capabilities, partial private authority, unauthorized absent-root creation, noncooperating private-byte replacement after capture, rollback and no-op acceptance are checked. Extension witnesses prove coalescing, no early policy/cache/checkpoint changes, post-wait bootstrap/private-step derivation, Stop/session/tree/shutdown cancellation, physical-owner revalidation and no rollback/replayed checkpoint after acceptance. A completed Start failure loses Telegram presentation authority when selection changes during callback acknowledgement. Native “real Pi start keeps local mode off while awaiting a partial foreign publication without private leakage” waits over two seconds behind an independent partial writer, then verifies current Global/CWD and local Session in the next provider input. 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. Idle/no-signal waits and the separate initial-attachment/fork recovery paths are not certified by that Abort witness.
35
+ 29. **Awaited Stop preserves immediate policy and accepted authority:** Extension tests cover all inactive-choice pairs: immediate Passive projection or complete Off withdrawal, one runtime-only acceptance of the latest pending choice, current shared adoption with unchanged semantic/provenance bytes, and lifecycle derivation after an intervening same-instance passive patch. Operation cancellation keeps the selected inactive mode and fences writes; selection/shutdown/accepted Start withdraw obsolete work without later mutation, while rejected Start leaves Stop pending. Publication faults roll back config/runtime without installing shared adoption; native checkpoint faults after acceptance do not roll back or retry writes. Native “real Pi off keeps local mode off while awaiting a partial foreign publication without private leakage” holds an independent writer for over two seconds, proves accepted shared/local memory through inspection and verifies that Off injects no shared-memory values or handoff into the next provider request. Telegram controls acknowledge early, await results, escape late errors and suppress revoked/navigated/disposed views; legacy synchronous controls remain compatible.
36
+ 30. **Awaited Start activates current authority without stale rollback:** Runtime witnesses preserve semantics, provenance, revisions, step and aligned history across old mode/unfinished-work combinations; expired/single-use capabilities, partial private authority, unauthorized absent-root creation, noncooperating private-byte replacement after capture, rollback and no-op acceptance are checked. Extension witnesses prove coalescing, no early policy/cache/checkpoint changes, post-wait bootstrap/private-step derivation, Stop/session/tree/shutdown cancellation, physical-owner revalidation and no rollback/replayed checkpoint after acceptance. A completed Start failure loses Telegram presentation authority when selection changes during callback acknowledgement. Native “real Pi active keeps local mode off while awaiting a partial foreign publication without private leakage” waits over two seconds behind an independent partial writer, then verifies current Global/CWD and local Session in the next provider input. 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. Idle/no-signal waits and the separate initial-attachment/fork recovery paths are not certified by that Abort witness.
37
37
  31. **Awaited retained restoration selects and accepts one coherent cohort:** Runtime restore matrices cover limits 0/1/12, historical/head artifact provenance and contradictory lineage. An independent partial publisher holds exclusion for over two seconds: cancellation preserves cache/files, successful restoration retains historical local Session over current shared values, and all five foreign-private files remain unchanged. Pointer mutation after admission cannot retarget selection; lifecycle policy is checked after waiting. 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. No current-head/empty fallback, invented history or unaccepted cache installation is permitted. Native caller cutover evidence is item 35.
38
38
  32. **Awaited exact-source fork preserves parent and child authority:** Runtime restore/fork matrices cover limits 0/1/12, provenance and contradictory lineage. An independent partial writer held over two seconds proves responsive cancellation, pinned source identity/checkpoint, current shared adoption and historical private copying without parent/foreign-private changes. Source expiry during waiting and competing child acceptances prove post-wait checks. Every occupied child file, unsupported legacy evidence, invalid/missing parent authority and parent/child byte races refuse publication. Fault injection proves rollback/retry; expired/single-use capabilities and post-acceptance checkpoint failure cannot replace accepted child memory. Child lifecycle resets step and unfinished specification while retaining selected mode/bootstrap; later child writes leave the parent unchanged. Shared unknown metadata and unrelated provenance survive. Native fork caller evidence is item 35.
39
39
  33. **Awaited current-memory recovery stays read-only:** Awaited loader matrices at limits 0/7 preserve current same-session values, step, revisions and bootstrap beside independently advanced shared streams without inheriting foreign private memory or unfinished specifications. No composed history is invented and no canonical files change, even when the in-memory view folds wider tails. Recovered caches cannot authorize lifecycle/patch publication. An independent partial writer held over two seconds proves cancelable coherent capture; injected cancellation during capture prevents cache installation. Missing roots/private authority remain absent, malformed/partial/identity/provenance errors retain the prior cache and bytes. Native failed-Stop wiring evidence is item 35.
40
40
  34. **Lifecycle fixtures await completion without trapping withdrawal:** Direct startup/tree fixture calls await their handlers before inspecting completed state. Preparation, response, Start, Stop and Telegram inspection cancellation families dispatch replacement selection separately, prove the obsolete operation withdraws while storage remains held, then release exclusion and join the replacement. Canonical-byte and stale trace/notice assertions remain; UI stability is measured after legitimate replacement completion. Item 35 records the resulting native cutover.
41
- 35. **Native branch restoration awaits one owned lifetime:** Extension witnesses hold exclusion across startup, tree, auto-start and failed-Stop reload: mode stays passive, private reads/patches report the pending selection, and files/checkpoints stay unchanged until acceptance. Joined Starts stay inert; bootstrap derived after waiting shares the single runtime write. Replacement selection/shutdown withdraw obsolete restoration while storage remains held. Stop changes the pending acceptance's policy without revoking its memory operation; mode separation is covered by items 37–38. Failed-Stop reload stays read-only and fenced; post-acceptance checkpoint failure warns without rollback or replay. Native tree/fork witnesses hold a publisher, then require selected private memory, unchanged parent-private files and matching next-provider input. The initial cutover probes, except their shutdown case, also failed against pre-cutover synchronous orchestration.
41
+ 35. **Native branch restoration awaits one owned lifetime:** Extension witnesses hold exclusion across startup, tree, auto-start and failed-Stop reload: mode stays in the selected inactive policy, private reads/patches report the pending selection, and files/checkpoints stay unchanged until acceptance. Joined Starts stay inert; bootstrap derived after waiting shares the single runtime write. Replacement selection/shutdown withdraw obsolete restoration while storage remains held. Stop changes the pending acceptance's policy without revoking its memory operation; mode separation is covered by items 37–38. Failed-Stop reload stays read-only and fenced; post-acceptance checkpoint failure warns without rollback or replay. Native tree/fork witnesses hold a publisher, then require selected private memory, unchanged parent-private files and matching next-provider input. The initial cutover probes, except their shutdown case, also failed against pre-cutover synchronous orchestration.
42
42
  36. **Recovery joins, draining and cache installation retain separate owners:** Start cancellation returns while independently owned restoration still waits; physical identity stays pinned across that join, so a changed owner cannot be activated. Recovery-domain tests preserve other joiners and observe late owner failures even after pre-cancellation. Shutdown waits for both current and superseded restoration operations, including delayed reader completion. Passive reads remain detached when physical CWD changes, and late native cancellation prevents both passive and private recovery cache installation. A private patch accepted between passive capture and attachment completion retains its newer cache and canonical bytes. These extension/domain witnesses supplement the native cutover probes rather than claiming universal idle Abort support.
43
43
  37. **Fork memory creation is independent of active/passive policy:** The extension native-fork/Start-retry × warm/cold × retained/expired matrix holds exclusion while Stop selects passive policy. The copy must remain pending rather than be cancelled, including when Stop withdraws its Start waiter. After release, retained source memory is accepted once with disabled policy, passive patching changes child-owned memory without enabling the mode, and native trace reopening through `SessionManager.open` preserves that child state. Expired source history refuses canonical publication and substitute checkpoints. These fixtures replace the former tests that codified Stop cancelling copying; the separate public SDK control/next-provider witness is item 40; installed UI reachability remains unverified.
44
- 38. **Stop cannot manufacture a restoration failure:** Held-store retained-boundary and auto-start fixtures require repeated Stop to return promptly without cancelling memory acceptance, adding an error fence or publishing early. Release accepts the selected/initial memory with passive policy, permits passive patches and retains them across reload. Stop→Start while waiting activates only after memory acceptance. A separate Start-owned attachment witness withdraws the Start waiter without cancelling restoration. The native SDK tree witness invokes `/state-flow-stop` during awaited `navigateTree`, then verifies selected private memory, passive tool availability and a successful next-provider patch; selected conversation remains visible and later-branch private memory stays absent. This public SDK route is not installed Telegram/TUI reachability certification.
44
+ 38. **Stop cannot manufacture a restoration failure:** Held-store retained-boundary and auto-start fixtures require repeated Stop to return promptly without cancelling memory acceptance, adding an error fence or publishing early. Release accepts the selected/initial memory with passive policy, permits passive patches and retains them across reload. Stop→Start while waiting activates only after memory acceptance. A separate Start-owned attachment witness withdraws the Start waiter without cancelling restoration. The native SDK tree witness invokes `/state-flow-passive` during awaited `navigateTree`, then verifies selected private memory, passive tool availability and a successful next-provider patch; selected conversation remains visible and later-branch private memory stays absent. This public SDK route is not installed Telegram/TUI reachability certification.
45
45
  39. **Native Skill compilation reconciles an independent writer without private leakage:** The Global/CWD × duplicate/competing/invalid matrix runs real Pi acquisition and compiler tool calls while a separate process publishes between the model's source read and its patch. Identical compiler output leaves shared checkpoint/tail/provenance bytes, scope revision and runtime step unchanged. Different output replaces the complete artifact and matching source-hash/compiler evidence, preserves independent peer fields, and advances the affected revision once. The next provider sees adopted shared state and local private memory, never the peer's private sentinel; all five peer-private files remain unchanged. An invalid compilation combined with a Session mutation rejects without changing any captured canonical file or accepting the accompanying Session field. The peer uses the runtime publication API, not a second provider; these ordered interleavings supplement the separate held-writer cancellation tests.
46
- 40. **A public SDK host can control a child while fork binding awaits memory:** The fixture observes the public `createAgentSession` result before awaiting `bindExtensions`, without private SDK hooks or direct calls to State Flow command handlers. During a held-store `runtime.fork`, it calls the child's public `prompt('/state-flow-stop')`; an optional subsequent Start waits for memory acceptance. Stop returns while the fork remains pending. After release, the child has a distinct identity, selected private memory and the requested passive/active policy. Its next provider sees selected rather than later-parent private state, successfully patches child memory and leaves all parent-private files unchanged. This certifies the embedding route on the tested SDK, not whether the installed CLI or Telegram exposes that child before its runtime replacement completes.
46
+ 40. **A public SDK host can control a child while fork binding awaits memory:** The fixture observes the public `createAgentSession` result before awaiting `bindExtensions`, without private SDK hooks or direct calls to State Flow command handlers. During a held-store `runtime.fork`, it calls the child's public `prompt('/state-flow-passive')`; an optional subsequent Start waits for memory acceptance. Stop returns while the fork remains pending. After release, the child has a distinct identity, selected private memory and the requested passive/active policy. Its next provider sees selected rather than later-parent private state, successfully patches child memory and leaves all parent-private files unchanged. This certifies the embedding route on the tested SDK, not whether the installed CLI or Telegram exposes that child before its runtime replacement completes.
47
47
  41. **Automatic history does not hydrate lazy memory:** Context tests cover large writes, replacements and deletions in Global/CWD/Session, mixed hot/lazy cohorts, empty scoped patches/transitions and omission of an empty window. Visible records retain their identities, order and original positions; artifact evidence is still hidden. Native SDK active/bootstrap/reload/Stop→Start witnesses keep lazy bodies out of State Flow-owned automatic blocks while retained canonical files still contain them. Current tool trajectory and unfinished bootstrap retain previously communicated bodies. Semantic files remain byte-identical through projection/preparation, and no hydration or repair inference is added. The four native mode witnesses fail against the unfiltered projection in an isolated source copy.
48
48
  42. **Hints do not create a recovery task:** Query tests preserve single-value hint conditions, current-only reference-owner lookup, no body disclosure and existing keys/patch/batch/unavailable-history behavior. Active/passive native witnesses compare exact canonical bytes and checkpoint counts around hints and reads, and require the exact scripted tool and provider-call counts. A task that needs no old detail performs no historical read; a task that needs it explicitly reads the exact retained Global/CWD/Session values without separate permission or restoring deleted data. Protocol and both Skill tests enforce this permission and boundary. Native provider assertions have completion sentinels outside the provider callbacks so a swallowed scripted provider error cannot produce a false pass. These are runtime/contract witnesses, not a claim about every model's discretionary behavior.
49
+ 43. **Session mode has one owner:** `tests/config.test.ts` and `tests/snapshot.test.ts` cover enum round trips, read-only legacy decoding, invalid/mixed session policies and pre-runtime mode retention without semantic initialization. Native global-default tests prove later defaults affect only new sessions. Extension inactive-choice matrices prove coalescing, no semantic revision and last-choice wins. Held-store “fenced reload preserves …” cases cover all four inactive pairs, unchanged canonical bytes, retained write fences, immediate/final tools/context/status and a subsequent reload. 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.
49
50
 
50
51
  ## Additional preservation boundaries
51
52
 
52
53
  - `tests/continuation.test.ts` independently advances global/CWD at limits 0/7, then proves read-only eligibility agrees with actual restore and preserves the session layer, including shared-only transitions. `tests/temporal.test.ts` covers sparse/inherited session lineage, conflicting checkpoint/tail identities and parents, future patches, and immutable inputs. The runtime restore/fork contradiction witnesses preserve source/target files rather than accepting a new origin over mixed session files. The native “real Pi refuses contradictory session files without passive substitution and retries the repaired selection” witness retains shared access, fences private access and publication, permits local Stop without a substitute checkpoint, and succeeds after exact-source repair. These are synthetic integrity tests, not evidence of spontaneous cross-session leakage.
53
- - `tests/extension.test.ts` distinguishes pre-runtime Stop from accepted-runtime Stop across passive configurations: global-only and shared storage remain unchanged, repeated Stop/reload retain the disabled marker, and subsequent Start/passive patch establishes a retained session boundary. Malformed/incomplete scope files remain unavailable; Stop does not repair CWD-only storage, while explicit Start may initialize its wholly absent global scope. The native “real Pi Stop preserves a global-only passive branch through reload, patch, and Start” witness checks the same lifecycle without Git. `tests/invariants.test.ts` rejects the retired Skill converter in both package and domain exports; existing Skill/transition witnesses preserve real source hashing, hashing failure, and retired-field rejection.
54
+ - `tests/extension.test.ts` distinguishes pre-runtime Stop from accepted-runtime Stop in inactive modes: global-only and shared storage remain unchanged, repeated selection/reload retain the native `{mode}` marker, and subsequent Start/passive patch establishes a retained session boundary. Malformed/incomplete scope files remain unavailable; Stop does not repair CWD-only storage, while explicit Start may initialize its wholly absent global scope. The native “real Pi Stop preserves a global-only passive branch through reload, patch, and Start” witness checks the same lifecycle without Git. `tests/invariants.test.ts` rejects the retired Skill converter in both package and domain exports; existing Skill/transition witnesses preserve real source hashing, hashing failure, and retired-field rejection.
54
55
  - `tests/durable.test.ts` and `tests/storage.test.ts` cover canonical-format rejection, owned regular files, raw-byte rollback, prepared-output receipts, stale/omitted-scope CAS, literal paths, malformed cohorts, and shared-writer exclusion.
55
56
  - `tests/git.test.ts` proves settled backup preserves unrelated staged/index-only/worktree data, already-staged owned deletions, Git ignore/filter policy, literal paths, and opaque bytes. Controlled Git pauses before/after snapshot capture allow an independent canonical writer to advance and create a new scope; the commit must match exactly one captured cohort, never mixed live bytes. Every observed Git command runs outside the backup's canonical lock. Namespace/type witnesses exclude unrelated traversal and refuse non-regular sources. No-op/unowned-only initial backups skip; Git/index failures preserve canonical acceptance and caller data. `tests/episode.test.ts` proves one diagnostic-only attempt at `agent_before_settle`, without answer changes or an automatic retry.
56
57
  - `tests/integration.test.ts` native new/resume/fork witnesses preserve canonical files and retained boundaries. Fork witnesses cover selected private state over current shared layers, fresh child ownership, reload/resume, disabled-source fencing, identity/CWD refusal, retry, and expired-boundary refusal. `tests/runtime.test.ts` restore/fork provenance witnesses preserve current-head, untouched-path, and shared evidence while discarding evidence for later-changed private artifacts, including change-away-and-back. The test-only provenance reader is checked against nonempty canonical `meta.json` evidence in every scope before and after reload; native restore/fork tests verify missing-evidence invalidation, explicit recompilation, parent preservation, and provenance across reload.
@@ -62,7 +63,7 @@ This is a maintained property-to-test map for the current canonical-file contrac
62
63
  - `tests/integration.test.ts` — “real Pi boundary continuation keeps accepted State Flow memory” exercises actual companion `turn_end` and `agent_before_settle` draft entries and continuation. Each next provider input has one freshly rebased head after accepted completion and matching-projection updates after a continued patch, the accepted response and current tool declarations. There is only one `before_agent_start`, no restored specification in runtime checkpoints or model projection, exactly one requested continuation and correct final response/step. The pure “projects accepted memory without resurrecting a completed specification for boundary continuation” witness preserves source state, omits lazy bodies, and keeps available context when both specification and native capture are absent.
63
64
  - `tests/integration.test.ts` — “real Pi context edits remain canonical through tools, tree selection and reload” proves native user-content replacement, assistant/custom-message omission and live tool-result replacement reach provider input without resurrecting raw history. Selecting an unedited branch restores its native view without overwriting accepted semantic files; selecting the edited branch and reloading preserves its edits and independent memory. Raw JSONL stays append-only.
64
65
  - `tests/integration.test.ts` — “real Pi structured prompt composes with context hooks” covers active, passive, disabled and explicit foreign-force modes. Conversation hooks exclude systems; full-system hooks receive them; companion before-run and per-request sections plus actual tool declarations survive. User specifications remain outside system authority. Stop/Start on subsequent user requests removes/reinstates the owned section once.
65
- - `tests/integration.test.ts` — “real Pi preserves native run identity across mode toggles” covers initially enabled, mid-tool Start and repeated Start/Stop with passive bootstrap on/off. Actual provider inputs retain original user/read evidence but not the preceding disabled request; persisted Stop markers name the observed native user, and fixture reload preserves trajectory, frozen state and raw trace prefix. `tests/compaction.test.ts` — “native session boundaries invalidate observed run capture without projection reacquisition” pairs session-start/tree resets with an admitted unchanged-run control. Run identity remains native rather than guessed; an independent optional Stop-marker flag preserves uncompiled bootstrap context without changing the captured anchor.
66
+ - `tests/integration.test.ts` — “real Pi preserves native run identity across mode toggles” covers initially enabled, mid-tool Start and repeated Start/Stop with explicit Active/Passive/Off selections. Actual provider inputs retain original user/read evidence but not the preceding disabled request; persisted Stop markers name the observed native user, and fixture reload preserves trajectory, frozen state and raw trace prefix. `tests/compaction.test.ts` — “native session boundaries invalidate observed run capture without projection reacquisition” pairs session-start/tree resets with an admitted unchanged-run control. Run identity remains native rather than guessed; an independent optional Stop-marker flag preserves uncompiled bootstrap context without changing the captured anchor.
66
67
  - `tests/integration.test.ts` — “real Pi refreshes protocol within the same run” covers mid-read Stop, passive Stop, mid-read Start and accepted-boundary Stop/continuation. The next provider request has current protocol/tools, foreign context and tool evidence, no elevated specification and only one user-run preparation; response reconciliation follows the actual mode and earlier native system frames remain intact. `tests/context.test.ts` — “refreshes only owned system protocol without mutating native frames” covers old/replaced/deleted sections, foreign content/tools, conversation identity/order, frozen inputs, absent-frame non-synthesis and unchanged-delta no-ops.
67
68
  - `tests/integration.test.ts` — “real Pi recovery omits failed attempts without accepting them” checks retry/length/overflow through actual SDK dispatch: durable omission edits, raw trace preservation, unchanged accepted response/step until successful recovery, native split-turn summaries and fixture reload. “real Pi edited-context accounting discards stale provider usage” checks reduced native usage after replacement and one subsequent inference without phantom compaction.
68
69
  - `tests/integration.test.ts` — “real Pi settled dispatch preserves deferred companion work” covers low pressure, real owned compaction and explicit compaction refusal. The native completion/error callback finishes before settled dispatch returns; all companion observers precede exactly one deferred request, which sees accepted memory and reconciles the expected response/step. The admitted case verifies an actual State Flow-owned compaction rather than relying only on a token estimate.
@@ -75,7 +76,7 @@ This is a maintained property-to-test map for the current canonical-file contrac
75
76
  - Runtime/Skill guidance names the reported artifact owner. Registered-Skill unit and native witnesses use Pi's public command source metadata to map user/project/temporary Skills to global/CWD/session, ignore unregistered `SKILL.md` reads, skip matching hashes, permit unrelated patches while compilation remains optional, retain strict attempted-output validation, and publish source-hash provenance to the exact reported owner.
76
77
  - `tests/transition.test.ts` rejects authored provenance fields and field deletions in every scope through both staging entrypoints, without requiring a preceding read; legacy semantic edits and whole-artifact deletion remain valid. The native “real Pi rejects no-read provenance forgery atomically and accepts a corrected model patch” witness proves whole-cohort rejection and recovery, while existing artifact/Skill tests preserve runtime-owned compilation evidence and legacy decoding.
77
78
  - `tests/storage.test.ts` covers exact file-cohort references, file CAS/rollback, and shared writer exclusion. The asynchronous transaction witnesses pause an independent writer between tail and metadata renames for longer than the old wait budget: the waiting process remains responsive and captures the complete accepted receipt only after release. Local waiters, cancellation before acquisition/publication, interrupted/malformed/empty locks, root/lifetime binding, active recursive refusal, deferred work after context expiry, rollback and replaced-owner preservation are separately checked. The current-head and response witnesses above additionally prove awaited model patch/finalization integration; runtime startup/recovery and exact restoration/fork cutover, including Start's initial attachment and unaccepted-fork paths, are covered by items 35–40. 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. `tests/runtime.test.ts` and native Pi lifecycle tests cover retained-boundary restart, immediate barriers, finalized response, config-only stop, and unavailable-reference provenance. Canonical files supply current state and bounded hot history; arbitrary cold revision recovery is unsupported.
78
- - `tests/runtime.test.ts` and native integration cover retained-boundary restoration and fork after lowering `historyLimit` to 0/1: current shared values/provenance and selected private state survive folding, parent-private fork files remain unchanged, out-of-window selections fail closed, and later increases do not reconstruct discarded history. `tests/config.test.ts` covers optional agent configuration, path precedence/expansion, invalid input, load-time caching and read-only behavior. Session tests and native Pi distinguish configured new-session auto-start from branch-local resume/tree/stop. `tests/extension.test.ts` proves registered artifacts are reconciled only at enabled inference boundaries. The global default is manual; CWD materialization alone no longer grants automatic activation.
79
+ - `tests/runtime.test.ts` and native integration cover retained-boundary restoration and fork after lowering `historyLimit` to 0/1: current shared values/provenance and selected private state survive folding, parent-private fork files remain unchanged, out-of-window selections fail closed, and later increases do not reconstruct discarded history. `tests/config.test.ts` covers optional agent configuration, path precedence/expansion, invalid input, load-time caching and read-only behavior. Session tests and native Pi distinguish configured new-session auto-start from branch-local resume/tree/stop. `tests/extension.test.ts` proves registered artifacts are reconciled only at enabled inference boundaries. The global default is Off without a configured mode; CWD materialization alone never grants Active mode.
79
80
 
80
81
  ## Validation and limits
81
82
 
@@ -9,36 +9,36 @@ For the concept and installation, start with the [README](../README.md). This gu
9
9
  State Flow has three distinct model-facing states. **Active versus passive changes the agent's workflow, not the existence of disk memory.**
10
10
 
11
11
  - **Active:** Both `read_state` and `patch_state` are available, subject to host restrictions and valid memory authority. Prompts require the agent to consolidate future-relevant results into state before ending an iteration. The final meaningful semantic patch preserves decisions, outcomes and continuation needed after the completed conversation is removed from model projection. The next iteration starts from accepted state and its new input, not the previous iteration's completed reasoning. Native trace remains inspectable; a clean model context does not mean deleting Pi history.
12
- - **Passive:** Both memory tools remain available with the default passive configuration. Existing state is projected into context, and the agent may read or patch it as useful. Ordinary conversation continuity remains: State Flow does not impose the active iteration-ending context reset or the same mandatory consolidation pressure. Accepted patches still reach the same canonical store with the same validation and ownership guarantees.
13
- - **Configured off:** Neither memory tool is exposed to the model, and State Flow injects no bootstrap/state context. This is distinct from passive mode, and does not mean deleting stored memory. With the current configuration, this means an inactive branch plus `passiveTools: false` and `passiveBootstrap: false`. `autoStart: false` only disables automatic activation of new sessions; it does not disable passive memory or override an already active resumed branch.
12
+ - **Passive:** Both memory tools are available. Existing state is projected into context, and the agent may read or patch it as useful. Ordinary conversation continuity remains: State Flow does not impose the active iteration-ending context reset or the same mandatory consolidation pressure. Accepted patches still reach the same canonical store with the same validation and ownership guarantees.
13
+ - **Off:** Neither memory tool is exposed to the model, and State Flow injects no protocol, bootstrap/state context or frozen passive handoff. Stored memory and the native conversation trace are not deleted.
14
14
 
15
- The two passive settings are independent: turning off only tools or only projection produces a deliberately partial integration, not the fully off state. Host restrictions and genuine unavailable/corrupt-memory fences are separate from these mode definitions.
15
+ One session-owned `mode` selects these behaviors; there are no independent passive-tool/projection switches. Host restrictions and genuine unavailable/corrupt-memory fences remain separate from mode selection.
16
16
 
17
17
  **Completion is semantic, not ceremonial.** In active mode, necessary final state changes must be accepted before relying on state-only continuation. This does not require an empty `patch_state` when memory is already current, an extra model turn, or a special finalization tool. Each `patch_state` remains an inference barrier, not automatically the end of an iteration; the runtime separately persists the accepted ordinary answer as Session `response` and completes the run.
18
18
 
19
19
  Here, “bootstrap from state” means constructing model context from durable memory. The implementation's `meta.bootstrap` is narrower: the one transition run that retains an existing conversation while active mode is first enabled and that conversation is compiled into state. It is not a flag that must be re-entered on every active iteration. Native compaction is also separate from model-context projection; its safety checks and usage threshold still apply.
20
20
 
21
- Start/Stop change active/passive behavior and respect the configured passive capabilities. They do not choose a different storage algorithm or cancel creation of a fork's private memory. A fork receives its own initial Session state from the selected parent boundary, then lives independently in either mode. See [fork support](#fork-support-and-limits).
21
+ Active, Passive and Off select the current session's workflow and model-facing access. They do not choose a different storage algorithm or cancel creation of a fork's private memory. A fork receives its own initial Session state from the selected parent boundary, then lives independently in its selected mode. See [fork support](#fork-support-and-limits).
22
22
 
23
23
  ### Lifecycle operations
24
24
 
25
- `/state-flow-start` enables the current Pi branch over validated current same-session memory, initializing absent storage when safe. No remote is required. Starting mid-conversation retains Pi's active context for one complete bootstrap run, during which the agent must compile future-relevant information into state. Repeating Start while already active leaves the in-progress run unchanged. On an attached branch, current-memory activation waits asynchronously for a coherent canonical cohort; pending repeats share the wait. Until acceptance, existing passive context, tools and any Stop fence remain in effect. Stop or selection can withdraw obsolete activation; an error after acceptance does not undo enabled memory.
25
+ `/state-flow-active` activates the current Pi branch over validated current same-session memory, initializing absent storage when safe. No remote is required. Starting mid-conversation retains Pi's active context for one complete bootstrap run, during which the agent must compile future-relevant information into state. Repeating Active while already active leaves the in-progress run unchanged. On an attached branch, current-memory activation waits asynchronously for a coherent canonical cohort; pending repeats share the wait. Until acceptance, the existing inactive mode and any write fence remain in effect. Passive, Off or branch selection can withdraw obsolete activation; an error after acceptance does not undo accepted memory.
26
26
 
27
- - **New session:** Passive durable memory is available by default without starting an episode. `autoStart` promotes genuinely new sessions into active State Flow; an active new session has its own empty session layer and inherits global/CWD state, never another session's private continuation.
28
- - **Resume:** Restores the selected session's stored enablement, state, and lineage. Agent-level `autoStart` does not override a resumed branch.
27
+ - **New session:** Adopts global `mode`, defaulting to Off. An inactive default is recorded once in Pi as `{mode:"off"}` or `{mode:"passive"}` without creating semantic storage. An Active default initializes a distinct empty Session layer over global/CWD memory, never another session's private continuation.
28
+ - **Resume:** Restores the selected session's retained mode, state and lineage. Later global default changes do not override it.
29
29
  - **Tree navigation:** Restores the selected retained private boundary over live shared scopes without checking out or resetting the shared store.
30
30
  - **Abort inference:** Stops generation or an outstanding response-publication wait while already accepted patches remain durable for continued work and corrected direction in the same session. Cancellation before response acceptance keeps the previous response and unfinished run; cancellation after acceptance never rolls it back. It does not require immediate remote replication.
31
31
  - **Native boundary continuation:** A companion may continue through Pi's `turn_end` or `agent_before_settle` boundary without a new user prompt. State Flow keeps projecting current memory and accepted response across those requests and subsequent patches; it does not restore the completed specification or request another turn itself.
32
- - **Stop:** Ends active episode semantics and returns to the configured passive bootstrap/tool combination. For a proven pre-runtime branch, it records only the existing disabled checkpoint in Pi, without creating canonical files or publishing the passive view; later Start or passive patch remains available. For an accepted runtime, it adopts unrelated shared-state changes without semantic/provenance writes or step changes. Same-session conflicts refuse canonical publication but do not prevent local disablement. Its frozen handoff uses the accepted view. It does not change passive or automatic-start policy.
33
- - **If Stop cannot persist:** Active mode still turns off. The last accepted cache remains readable and all available native conversation is retained. Pi's native session records the local Stop and a write fence, without a replacement semantic checkpoint. Tree/reload/resume stay passive and load validated current same-session memory read-only; they never replay an older selection over another writer. Unavailable or corrupt memory stays unavailable. Repeated Stop does not retry or clear the fence. Explicit Start revalidates current memory and clears the fence only after canonical acceptance. This fallback requires Pi's native trace to remain writable; it does not repair storage. The canonical config may still say enabled, but the native failed-Stop policy overrides it on this branch.
34
- - **Continue after Stop:** The same physical session retains a frozen state handoff, any interrupted current request and tool trajectory (including late results), and post-stop conversation. Outside an unfinished bootstrap, a proven active boundary excludes completed earlier conversation; when native split-turn compaction removed the original request anchor, Stop instead preserves the available summary and tools without reconstructing discarded raw input. An unfinished bootstrap keeps all available native context, or the earlier passive boundary it received; repeated Start/Stop cannot move that boundary past uncompiled conversation. An interrupted run retains its captured anchor even after Pi becomes idle, falling back to all available context when that anchor is unknown. Other extensions' custom context survives. Only Stop after a completed idle run retains just later conversation plus foreign custom context. Reload/resume/tree preserve this projection; new/forked physical sessions do not inherit it. Mid-tool Start and repeated Start/Stop retain the first user event already observed while disabled, so subsequent Stop does not mistake that busy run for idle. Active restart uses the retained projection for one bootstrap run.
32
+ - **Passive or Off:** `/state-flow-passive` enables both memory tools and projection; `/state-flow-off` removes both tools and all State Flow model context immediately. A proven pre-runtime branch records only `{mode}` in Pi, without creating canonical files or publishing its cached view. Accepted runtimes persist mode and adopt unrelated shared drift without semantic/provenance writes or revision/step changes. Repeated selections are inert; pending inactive choices share one acceptance of the latest choice. Global defaults and other sessions remain unchanged.
33
+ - **If an inactive choice cannot persist:** The selected Passive/Off policy stays applied. Accepted memory and native conversation remain intact; Off still exposes no State Flow context or tools. Pi records the selected mode and a write fence, not a replacement semantic checkpoint. Tree/reload/resume read validated current same-session memory without publishing or restoring an older selection. Newer mode choices survive an in-flight read-only recovery. Repeating the same choice is inert; changing inactive mode updates only native policy and keeps the fence. Explicit Active clears the fence only after canonical acceptance. This fallback requires a writable Pi trace and never repairs storage; native fenced policy overrides an older canonical config.
34
+ - **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 post-stop conversation. Outside an unfinished bootstrap, a proven active boundary excludes completed earlier conversation; when native split-turn compaction removed the original request anchor, Stop instead preserves the available summary and tools without reconstructing discarded raw input. An unfinished bootstrap keeps all available native context, or the earlier passive boundary it received; repeated Start/Stop cannot move that boundary past uncompiled conversation. An interrupted run retains its captured anchor even after Pi becomes idle, falling back to all available context when that anchor is unknown. Other extensions' custom context survives. Only Stop after a completed idle run retains just later conversation plus foreign custom context. Reload/resume/tree preserve this projection; new/forked physical sessions do not inherit it. Mid-tool Start and repeated Start/Stop retain the first user event already observed while disabled, so subsequent Stop does not mistake that busy run for idle. Active restart uses the retained projection for one bootstrap run. Off retains this boundary for a later Passive/Active selection but never projects it.
35
35
  - **Completed-history compaction:** After an accepted run settles without queued input, State Flow asks Pi for a native compaction boundary only when public context usage reaches 24,000 tokens. No extra model summary is requested; Pi keeps the complete latest run—from its original request through steering, tools, foreign context and final answer—in active history and retains the complete append-only JSONL/tree. State Flow uses the native first-user anchor, independent of image-normalization hints or later steering; images and earlier tool results remain available to the model. Uncertain projection retains available context without changing that anchor. A missing or ambiguous native anchor skips compaction instead of choosing the last steering message. On resume, native `buildContextEntries()` and TUI rendering omit the older completed prefix. Unknown or smaller usage skips the request, and custom Pi retention settings may still decline it benignly. Foreign custom context in the removed prefix, bootstrap/abort/error, Stop and pending input prevent State Flow-owned shortening; ordinary manual/threshold/overflow compaction remains native and may preserve unfinished work not yet patched into memory.
36
36
 
37
37
  State Flow does not undo tool effects. After interruption or returning to an older branch, check the relevant workspace or external system before repeating consequential operations. Restored memory is not restored reality.
38
38
 
39
39
  ### Fork support and limits
40
40
 
41
- Native fork replacement copies the source session checkpoint, retained patch tail and matching provenance into the new session's own storage. Global/CWD values and provenance stay current; applying a smaller `historyLimit` may fold shared tails under CAS. An earlier fork selection copies that point's private state, not the parent's later private work. Parent-private data/history remain intact; selected enablement is retained, so a stopped source does not become enabled automatically.
41
+ Native fork replacement copies the source session checkpoint, retained patch tail and matching provenance into the new session's own storage. Global/CWD values and provenance stay current; applying a smaller `historyLimit` may fold shared tails under CAS. An earlier fork selection copies that point's private state, not the parent's later private work. Parent-private data/history remain intact; the selected mode is retained, so an inactive source does not become Active automatically.
42
42
 
43
43
  The child starts at step zero and a new temporal origin. Its copied tail obeys the configured retention limit, but pre-origin records are not additional aligned causal boundaries addressable through `effective[n]` or scoped paths. The child's own transitions build its hot window; owned checkpoints support normal reload/resume. Parent Stop projection is not inherited, including after child reload.
44
44
 
@@ -52,9 +52,7 @@ Optional global `config.json` at the root of the State Flow repository, normally
52
52
 
53
53
  ```json
54
54
  {
55
- "autoStart": false,
56
- "passiveBootstrap": true,
57
- "passiveTools": true,
55
+ "mode": "off",
58
56
  "logging": false,
59
57
  "showSuccessfulPatches": true,
60
58
  "historyLimit": 7
@@ -62,35 +60,38 @@ Optional global `config.json` at the root of the State Flow repository, normally
62
60
  ```
63
61
 
64
62
  The canonical store is `state-flow/` beneath the agent directory. Keeping configuration inside that repository removes the separate agent-level `state-flow.json`; SDK embeddings may still provide an explicit repository override.
65
- - `autoStart`: Defaults to `false`. When `true`, genuinely new sessions use the same initialization as explicit Start, including fresh CWDs.
66
- - `passiveBootstrap`: Defaults to `true`. Projects existing effective durable memory into ordinary model context without creating scopes, publishing, or starting an episode.
67
- - `passiveTools`: Defaults to `true`. Exposes `read_state` and `patch_state` outside active episodes. Reads remain side-effect free; the first explicit patch may initialize absent canonical storage but never converts predecessor formats or enables an episode or State Flow compaction.
68
- - `logging`: Defaults to `false`. When enabled, records rejected patches, preparation failures and accepted-answer reconciliation failures locally at `tmp/state-flow/logs.jsonl` beneath the agent directory. Asynchronous Git push failures are recorded there even when this setting is off.
63
+ - `mode`: `"active"`, `"passive"` or `"off"`; defaults to `"off"`. Supplies the default only for genuinely new sessions. Active initializes missing storage when safe; Passive reads existing memory without publishing, and its first explicit patch may initialize absent storage without starting an episode or compaction. Off exposes neither memory tools nor State Flow context.
64
+ - `logging`: Defaults to `false`. When enabled, records rejected patch executions, active barrier blocks, preparation failures and accepted-answer reconciliation failures locally at `tmp/state-flow/logs.jsonl` beneath the agent directory. Asynchronous Git push failures are recorded there even when this setting is off.
69
65
  - `showSuccessfulPatches`: Defaults to `true`. In interactive Pi, successful `patch_state` rows show only the applied pretty-printed JSON arguments, with blank lines between adjacent memory sections; set it to `false` to keep only the compact summary. Rejected calls still use ordinary error rendering; State Flow adds no private validation turn.
70
66
  - `historyLimit`: Defaults to `7` and accepts integers from `0` through `100`. It counts accepted semantic transitions, **not elapsed time or conversation length**. It bounds materialized-history and scope patch-history offsets. Lowering it on reload/restore/fork folds excess tails forward without losing current state; selected boundaries outside the new window are unavailable. Zero retains only current checkpoints. Raising the limit affects only future retention and cannot reconstruct discarded history.
71
67
 
68
+ Session `config.json` uses the same `mode` key for its concrete choice; commands and Telegram change that session only. Before canonical runtime acceptance, Pi's native `{mode}` checkpoint owns the choice instead of a manufactured storage pair. Edit global defaults manually or through an authorized agent, not `patch_state`. Legacy flag decoding is read-only; see [mode compatibility](compatibility.md#mode-configuration-compatibility).
69
+
70
+ **Passive model-facing footprint:** When selected, Passive declares both memory tools even with no canonical store; its system-prompt section and projected memory message appear only after a validated memory view is loaded. New sessions default to Off, which exposes none of these State Flow model-facing surfaces. With unavailable memory the tools may still reject reads or writes; declared tools do not prove usable storage.
71
+
72
+ A source-bound UTF-8 byte probe of the 0.22.0 tree (`3242d762`, isolated `tests/harness.ts` and `tests/storage-fixture.ts`, default config, empty native transcript, `before_agent_start("Probe")` then `context`) measured the two `{name,description,parameters}` tool definitions as **1,728 JSON bytes**. A wholly absent store added **0 protocol and 0 projected-message bytes**. A validated empty Global state (`{}`) added **959 protocol bytes** and **321 serialized message bytes**; `global.working={sample:"x"}` added the same **959** plus **351 message bytes**. These component sizes include the projection marker in the message but exclude native prompt/tool wrappers, conversation, provider tokenization and variable user memory; they are not token-cost or cache-hit claims.
73
+
72
74
  Settings are read once at extension load. After editing, use `/reload` or restart Pi. A missing file uses defaults without creating a configuration file; malformed JSON, unknown keys, or invalid values fail loading rather than silently selecting another store.
73
75
 
74
76
  `PI_CODING_AGENT_DIR` changes both the default State Flow repository and its global configuration location. State Flow has no source-directory or Knowledge-root configuration. SDK repository overrides are documented under [embedding](architecture.md#embedding); an overridden repository owns its own root `config.json`.
75
77
 
76
78
  ### Diagnostic logging and privacy
77
79
 
78
- Rejected-call records may contain exact attempted arguments and useful draft text, plus the error category and tool/call identity. Asynchronous push failures retain the available redacted Git error there regardless of `logging`; interactive warnings stay short and appear once per failure streak, then reset on success. If logging the push failure is unavailable, one warning exposes the available detail instead. Successful patches are not logged; reasoning bodies are excluded. Logs are not semantic state, scope metadata, Pi checkpoints, or publication input. If the log path overlaps a custom state repository, capture fails closed instead of committing it. A logging failure changes no accepted state and produces at most one local warning.
80
+ Rejected `patch_state` execution records may contain exact attempted arguments and useful draft text, plus the error category and tool/call identity. The `barrier-block` category instead records only the blocked tool name, call id, reason and batch tool names (never sibling arguments or reasoning); Passive has no patch barrier, and logging off records no barrier blocks. Asynchronous push failures retain the available redacted Git error there regardless of `logging`; interactive warnings stay short and appear once per failure streak, then reset on success. If logging the push failure is unavailable, one warning exposes the available detail instead. Successful patches are not logged; reasoning bodies are excluded. Logs are not semantic state, scope metadata, Pi checkpoints, or publication input. If the log path overlaps a custom state repository, capture fails closed instead of committing it. A logging failure changes no accepted state and produces at most one local warning.
79
81
 
80
- Logs remain local unless you move them; rotation/deletion is operator-owned. State Flow-authored errors and warnings display as one compact line: long operands are elided with `…` before prose so the operation, offending scope, target basename/suffix and actionable reason remain visible. Nested causes travel as text because Pi tool results need not retain `Error.cause`. Enabled diagnostic records keep the full target and rejected input for investigation. An explicit Start retry reports its final failure once rather than repeating its startup warning. Tool failures still keep the required blank line beneath their heading. Treat logs and state files as private. Removing a secret from current state does not erase older offsets, Git history, native sessions, or remote copies.
82
+ Logs remain local unless you move them; rotation/deletion is operator-owned. State Flow-authored errors and warnings display as one compact line: flatten nested/aggregate causes into transportable text rather than relying on `Error.cause`. Elide long operands with `…` before shortening prose so the operation, exact offending scope, target basename/suffix and actionable reason remain visible; do not split Unicode pairs or mistake prose apostrophes for quoted paths. Enabled diagnostic records keep the full target and rejected input for investigation. An explicit Start retry reports its final failure once rather than repeating its startup warning. Tool failures still keep the required blank line beneath their heading. Treat logs and state files as private. Removing a secret from current state does not erase older offsets, Git history, native sessions, or remote copies.
81
83
 
82
84
  ## Status and controls
83
85
 
84
86
  `/state-flow-status` separates runtime configuration/metadata from semantic state. It reports:
85
87
 
86
- - Selected CWD/session keys, internal step, independent scope revisions, temporal head, recovery failures, and available hot history.
87
- - Per-scope retained patch tails and artifact counts, plus one JSON representation of effective global → CWD → session memory. Individual scope JSON is available through `read_state`, not duplicated in status.
88
- - Already-known runtime hints or pending artifact invalidations; status does not discover or validate sources.
89
- - Memory-bearing scopes. Promotion-shaped values receive no special interpretation.
88
+ - Selected CWD/session keys, internal step, effective `g#c#s#` scope-revision vector, and available hot-history depth.
89
+ - Known recovery or publication failures, actual artifact counts when nonzero, and pending invalidations. Status does not discover or validate sources.
90
+ - 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`.
90
91
 
91
- Tail counts are not history depth: inherited records may predate the active origin. 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.
92
+ Status omits the already-visible mode and 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.
92
93
 
93
- The terminal indicator is `state-flow G15/C8/S31` only in active mode. Global, CWD and Session own independent semantic revisions; one atomic transition advances each materially changed scope once, including session-only response reconciliation. Effective has no scalar counter and uses the `G#/C#/S#` revision vector. When `pi-telegram` is available, its main-menu section shows that vector only while active and `State Flow: off` while passive. Requested owner-scope Rich snapshots show `#revision`; Effective shows the vector. During a failed-Stop write fence, inspection uses the accepted cache without a potentially conflicting refresh. Otherwise, Telegram inspection waits cancelably to load or refresh one coherent shared view, even when passive model tools are disabled. It does not initialize, publish, or advance storage. Data and displayed revisions belong to the same observation; absent/invalid memory stays unavailable. Stop, session/tree changes and shutdown cancel obsolete observations. The button acknowledges immediately, and a late failure appears in the menu instead of an expired callback popup. Start requested during a run waits for settlement; Stop currently applies immediately. The adapter is optional and the Pi commands remain available without it. Open implementation work is tracked in [BACKLOG.md](../BACKLOG.md).
94
+ The terminal indicator is accent `state-flow` plus dim `active` or `passive`; Off hides it. Global, CWD and Session own independent semantic revisions; one atomic transition advances each materially changed scope once, including session-only response reconciliation. Effective has no scalar counter and uses the compact lowercase `g#c#s#` revision vector (for example, `g15c8s31`), without slashes or spaces between counters. That vector appears in `/state-flow-status` and Telegram's Effective inspection, not the compact indicators. When `pi-telegram` is available, its main-menu section shows `State Flow: active`, `State Flow: passive` or `State Flow: off`. Off exposes neither tool nor State Flow model context. Requested owner-scope Rich snapshots show `#revision`; Effective shows the vector. During a failed-Stop write fence, inspection uses the accepted cache without a potentially conflicting refresh. Otherwise, Telegram inspection waits cancelably to load or refresh one coherent shared view, even when passive model tools are disabled. It does not initialize, publish, or advance storage. Data and displayed revisions belong to the same observation; absent/invalid memory stays unavailable. Stop, session/tree changes and shutdown cancel obsolete observations. The button acknowledges immediately, and a late failure appears in the menu instead of an expired callback popup. The submenu heading displays the current value in monospace. The bold Mode heading uses a long dash, description ending in a colon, and a blank line before its settings-style list. Each line uses a monospaced minus and lowercase monospaced mode value, then a plain colon and description. The descriptions progress from regular chat with no memory (Off, the new-session default), to ordinary chat with memory tools and an available combined memory view (Passive), to the same memory access with completed answers followed by memory-first continuation (Active); they do not claim a new physical Pi session or disable native compaction. The bold Inspect memory heading follows the same long-dash-description-colon and blank-line pattern. Its four lines use the same monospaced minus/value and plain colon format for `global`, `cwd`, `session` and `effective`, describing individual scopes and their combined view. Inspection works in Off even though its memory does not reach the agent. A horizontal radio row presents `Off | Passive | Active`: the selected option uses 🟡, 🟣 or 🟢 respectively, and each inactive option uses ⚫️. Four direct Global/CWD/Session/Effective buttons follow without another chooser. Ordinary successful controls add no redundant mode receipt; diagnostic outcomes remain visible. Telegram Active requested during a run waits for settlement; Passive and Off apply immediately. All controls use the same lifecycle owners as the terminal commands. The adapter is optional and the Pi commands remain available without it. Open implementation work is tracked in [BACKLOG.md](../BACKLOG.md).
94
95
 
95
96
  ## Storage and recovery
96
97
 
@@ -105,11 +106,13 @@ Each scope materializes an anchored semantic-only `checkpoint.json` plus semanti
105
106
 
106
107
  ### Missing, partial, and malformed storage
107
108
 
109
+ Missing documented fields inside a valid checkpoint or patch are supported. Current and historical semantic views include only known fields present in the selected scope or overlay; absent fields and empty responses are omitted. Higher scopes contribute only present values. Unknown top-level fields are ignored when reading checkpoints/patches and are not emitted on subsequent writes; nested data within known planes remains intact. An explicit `read_state` value query for an absent documented top-level field returns `null`, including empty/absent `session.response`. Reading and Start do not normalize files, advance revisions or require a migration. An empty semantic object is different from a missing file or missing ownership metadata.
110
+
108
111
  A checkpoint and tail are one semantic pair. If both live files for a global or CWD scope disappear, State Flow treats that complete absence as current empty shared reality. An authored `patch_state` applies to that empty basis under exclusion; normal file-cohort CAS creates the accepted pair without resurrecting cold values or orphaned compilation evidence. Raw precomputed replay still refuses a removed selected target rather than replaying stale normalized changes.
109
112
 
110
113
  Exactly one surviving pair member is corruption and fails closed. Present malformed JSON, incomplete predecessor envelopes, semantic/metadata boundary mismatches, identity contradictions, and partial session runtime evidence also remain fail-closed and are not replaced. A missing or expired private retained boundary is unavailable; State Flow does not substitute Git history or newer private files.
111
114
 
112
- After a selected-boundary failure, configured passive access may still expose current global/CWD memory, but it never grants access to the unavailable historical session layer or permission to publish an empty replacement. Historical session reads and every `patch_state` refuse without changing canonical files or appending substitute checkpoints. Stop remains available and records the native policy/write fence described above; a subsequent reload may expose validated current memory read-only, not the unavailable selected history. Status distinguishes a write fence from unavailable materialization.
115
+ After a selected-boundary failure, Passive may still expose current global/CWD memory, but it never grants access to the unavailable historical session layer or permission to publish an empty replacement. Historical session reads and every `patch_state` refuse without changing canonical files or appending substitute checkpoints. Passive/Off selection remains available and records the native policy/write fence described above; a subsequent reload may expose validated current memory read-only, not the unavailable selected history. Status distinguishes a write fence from unavailable materialization.
113
116
 
114
117
  **Explicit Start uses current memory, not unavailable history.** It independently validates the current same-session canonical cohort, preserving private memory, artifact provenance, revisions, step and available aligned history. Expired active/passive pointers and unfinished runtime work no longer block activation. A pre-runtime selection also keeps current accepted same-session memory rather than resetting it. 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. Independently advanced shared scopes may require a new temporal origin; unavailable history is never invented. Exact-cohort CAS rejects a concurrent writer, and incomplete/corrupt storage remains untouched. An unaccepted native fork still retries its exact source rather than inventing child memory. When evidence is missing, repair it, select a retained boundary, or open a genuinely new Pi session.
115
118
 
@@ -125,7 +128,7 @@ After an accepted turn has reconciled its response, Pi 0.87's final actionable `
125
128
 
126
129
  An SDK `repositoryRoot` override or a different `PI_CODING_AGENT_DIR` selects a location; it does not relocate existing state or retained history. Copy the complete canonical store while all writers are quiescent, or use a genuinely new Pi session for an independent store. Copying only current checkpoints without their tails and metadata cannot preserve retained boundaries.
127
130
 
128
- Starting with 0.17, State Flow accepts only its canonical checkpoint/tail, temporal metadata, and separate session config/runtime contract; that boundary still applies to current versions. A canonical 0.17 scope written before independent revisions remains readable: its initial counter uses only the retained semantic tail and is persisted in metadata version 2 on the next owned write, without inventing folded ancestry. Version 1 remains readable; older writers refuse version 2 through the existing provenance-version fence, so cooperating instances should upgrade together. Predecessor checkpoint envelopes, combined session metadata, pre-intents checkpoints, `state.json`, hashed layouts, and semantic Pi checkpoint envelopes fail as unsupported without rewriting existing bytes. State Flow does not provide an in-place converter; external conversion or a fresh store is operator-owned.
131
+ Starting with 0.17, State Flow accepts only its canonical checkpoint/tail, temporal metadata, and separate session config/runtime contract; that boundary still applies to current versions. A canonical 0.17 scope written before independent revisions remains readable: its initial counter uses only the retained semantic tail and is persisted in metadata version 2 on the next owned write, without inventing folded ancestry. Version 1 remains readable; older writers refuse version 2 through the existing provenance-version fence, so cooperating instances should upgrade together. Predecessor checkpoint envelopes, combined session metadata, `state.json`, hashed layouts, and semantic Pi checkpoint envelopes fail as unsupported without rewriting existing bytes. Canonical semantic objects lacking fields introduced later, such as `intents` or `lazy`, are valid sparse state and do not cross this format boundary. State Flow does not provide an in-place converter; external conversion or a fresh store is operator-owned.
129
132
 
130
133
  ### Conflicts and interrupted publication
131
134
 
@@ -135,7 +138,7 @@ Final-answer reconciliation also waits cancelably, then saves the response and c
135
138
 
136
139
  Run preparation and missing-artifact maintenance wait cancelably before the first enabled inference, accepting current shared memory and lifecycle together. If preparation fails, State Flow aborts that native operation rather than sending a rejected or stale draft to the provider; previously accepted memory remains available. Cancellation can leave the new request without a specification checkpoint, so its native conversation is conservatively preserved through idle Stop/reload. Boundary continuation never replays a completed specification.
137
140
 
138
- Telegram shared inspection also awaits exclusion read-only. Backup capture also uses the awaited API, with the no-signal settlement exception described above. Accepted-runtime Stop switches local policy and passive projection immediately, then awaits runtime-only persistence; pending repeats share that operation. Selection/shutdown or a successful Start cancel obsolete Stop work. An available host operation signal can cancel persistence without re-enabling mode; idle commands do not necessarily have that signal. Current-head Start similarly waits before enabling mode, with Stop/selection/shutdown cancellation and any available native operation signal. Startup, tree, auto-start, fork and failed-Stop reload restoration, including Start's initial attachment and fork retry, also await exclusion; until acceptance, mode stays passive and private memory reports the pending selection. Interrupted, malformed or unreadable locks are never stolen. Reconcile the owner rather than deleting locks or state directories merely because an operation is slow. File-cohort exclusion, exact prepared bytes and compare-and-swap checks are not kernel-atomic multi-file transactions against nonparticipating writers.
141
+ Telegram shared inspection also awaits exclusion read-only. Backup capture also uses the awaited API, with the no-signal settlement exception described above. Accepted-runtime Passive/Off selection changes local tools/context immediately, then awaits runtime-only persistence; pending inactive choices share one acceptance of the latest mode. Selection/shutdown or a successful Start cancel obsolete Stop work. An available host operation signal can cancel persistence without restoring an older mode; idle commands do not necessarily have that signal. Current-head Start similarly waits before enabling mode, with Stop/selection/shutdown cancellation and any available native operation signal. Startup, tree, auto-start, fork and failed-Stop reload restoration, including Start's initial attachment and fork retry, also await exclusion; until acceptance, mode stays in the selected inactive policy and private memory reports the pending selection. Off remains Off; later inactive choices survive read-only recovery without cancelling it. Interrupted, malformed or unreadable locks are never stolen. Reconcile the owner rather than deleting locks or state directories merely because an operation is slow. File-cohort exclusion, exact prepared bytes and compare-and-swap checks are not kernel-atomic multi-file transactions against nonparticipating writers.
139
142
 
140
143
  Fatal process termination can leave an incomplete canonical file cohort. Before repair, quiesce all store writers and preserve the complete store plus selected Pi retained-boundary references. Reconcile exact files against the last complete checkpoint/tail/metadata cohort; no automatic crash repair or power-loss durability is promised. Git backup has no semantic recovery authority.
141
144
 
@@ -110,12 +110,13 @@ export {
110
110
  export {
111
111
  emptyState,
112
112
  isMaterializedState,
113
+ isSemanticState,
113
114
  isStateDocument,
114
115
  overlayStates,
115
116
  projectStateForModel,
116
117
  updateMaterializedArtifacts,
117
118
  type AtomicScopePatches, type MaterializedState, type ScopedPatch,
118
- type ScopedStates, type ScopePatch, type SemanticTransition,
119
+ type ScopedStates, type ScopedSemanticStates, type ScopePatch, type SemanticState, type SemanticTransition,
119
120
  type StateDocument,
120
121
  type StatePatch,
121
122
  type StateScope,
@@ -142,5 +143,5 @@ export {
142
143
  type StateFlowTelegramSnapshot,
143
144
  type StateFlowTelegramView
144
145
  } from "./lib/telegram.ts";
145
- export { advanceTemporalState, readTemporalState, temporalScopeRevisions, type ScopeRevisions, type TemporalState } from "./lib/temporal.ts";
146
+ export { advanceTemporalState, readTemporalState, readTemporalView, temporalScopeRevisions, type ScopeRevisions, type TemporalState } from "./lib/temporal.ts";
146
147
  export { parseStateReadPath, readStatePath, type StateReadQuery, type StateReadResult } from "./lib/query.ts";