@llblab/pi-kit 0.38.1 → 0.38.3

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 (43) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +3 -3
  3. package/node_modules/@llblab/pi-claude-usage/AGENTS.md +3 -2
  4. package/node_modules/@llblab/pi-claude-usage/CHANGELOG.md +5 -0
  5. package/node_modules/@llblab/pi-claude-usage/README.md +14 -5
  6. package/node_modules/@llblab/pi-claude-usage/lib/model-limit.ts +54 -0
  7. package/node_modules/@llblab/pi-claude-usage/lib/status.ts +17 -5
  8. package/node_modules/@llblab/pi-claude-usage/lib/usage-store.ts +21 -1
  9. package/node_modules/@llblab/pi-claude-usage/package.json +1 -1
  10. package/node_modules/@llblab/pi-state-flow/AGENTS.md +1 -1
  11. package/node_modules/@llblab/pi-state-flow/BACKLOG.md +11 -673
  12. package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +18 -0
  13. package/node_modules/@llblab/pi-state-flow/README.md +8 -8
  14. package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +3 -6
  15. package/node_modules/@llblab/pi-state-flow/dist/lib/model-interface.js +2 -3
  16. package/node_modules/@llblab/pi-state-flow/dist/lib/semantic-module.d.ts +1 -1
  17. package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.js +2 -6
  18. package/node_modules/@llblab/pi-state-flow/dist/package.json +2 -1
  19. package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-guide/SKILL.md +5 -5
  20. package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-memory/SKILL.md +1 -1
  21. package/node_modules/@llblab/pi-state-flow/docs/README.md +7 -7
  22. package/node_modules/@llblab/pi-state-flow/docs/architecture.md +11 -15
  23. package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +12 -10
  24. package/node_modules/@llblab/pi-state-flow/docs/fork-contract.md +18 -16
  25. package/node_modules/@llblab/pi-state-flow/docs/lazy-state.md +13 -15
  26. package/node_modules/@llblab/pi-state-flow/docs/protocol-composition-decision.md +2 -2
  27. package/node_modules/@llblab/pi-state-flow/docs/public-module-contract.md +16 -6
  28. package/node_modules/@llblab/pi-state-flow/docs/scope-selection-contract.md +25 -23
  29. package/node_modules/@llblab/pi-state-flow/docs/semantic-compatibility-decision.md +14 -12
  30. package/node_modules/@llblab/pi-state-flow/docs/semantic-extensibility-decision.md +2 -2
  31. package/node_modules/@llblab/pi-state-flow/docs/semantic-handoff-contract.md +133 -15
  32. package/node_modules/@llblab/pi-state-flow/docs/semantic-memory-evaluation.md +5 -5
  33. package/node_modules/@llblab/pi-state-flow/docs/semantic-module-contract.md +5 -5
  34. package/node_modules/@llblab/pi-state-flow/docs/single-scope-interface-contract.md +2 -2
  35. package/node_modules/@llblab/pi-state-flow/docs/usage.md +33 -23
  36. package/node_modules/@llblab/pi-state-flow/lib/extension.ts +3 -7
  37. package/node_modules/@llblab/pi-state-flow/lib/model-interface.ts +2 -3
  38. package/node_modules/@llblab/pi-state-flow/lib/semantic-module.ts +1 -1
  39. package/node_modules/@llblab/pi-state-flow/lib/telegram.ts +2 -6
  40. package/node_modules/@llblab/pi-state-flow/package.json +2 -1
  41. package/node_modules/@llblab/pi-state-flow/skills/state-flow-guide/SKILL.md +5 -5
  42. package/node_modules/@llblab/pi-state-flow/skills/state-flow-memory/SKILL.md +1 -1
  43. package/package.json +3 -3
@@ -2,11 +2,11 @@
2
2
 
3
3
  ## Status and authority
4
4
 
5
- **M1 semantic contract — locally implemented names and guidance, not a live-model quality claim.** Runtime fields, tools, ownership and callbacks now use `intents`, `strategy`, and `tactics`. Declared legacy `contract`/`working` data is translated under the [migration contract](semantic-compatibility-decision.md). Configurable scopes, flattening and module decisions remain in the [evolution backlog](../BACKLOG.md), which alone owns remaining tasks. The original M0 preservation evidence below remains bound to its old-name baseline.
5
+ **Current semantic contract, shipped in 0.27.0; no live-model quality claim.** Runtime fields, tools, ownership and callbacks use `intents`, `strategy`, and `tactics`. Declared legacy `contract`/`working` data translates under the [migration contract](semantic-compatibility-decision.md). Scope selection and flat tools are delivered under their [scope](scope-selection-contract.md) and [model-interface](single-scope-interface-contract.md) contracts; internal/public modules have their own indexed boundaries. [BACKLOG.md](../BACKLOG.md) owns only outstanding work. The original M0 preservation evidence below remains bound to its old-name baseline.
6
6
 
7
- This contract makes the semantic handoff reviewable before implementation. It distinguishes model responsibilities from deterministic acceptance. It does not claim that any unconstrained model already follows these rules, or that new names improve task performance.
7
+ This contract defines the semantic handoff responsibilities. It distinguishes model responsibilities from deterministic acceptance. It does not claim that any unconstrained model already follows these rules, or that new names improve task performance.
8
8
 
9
- Baseline for the evidence below: package 0.26.5, source commit `4494fee9da8258cdf5f02c42672a0eb9866a512a`, repository-local matching Pi SDK 1.0.0. No source or test changes were needed for this slice.
9
+ Historical M0 baseline for the source-bound evidence below: package 0.26.5, source commit `4494fee9da8258cdf5f02c42672a0eb9866a512a`, repository-local matching Pi SDK 1.0.0. No source or test changes were needed for this slice.
10
10
 
11
11
  ## Purpose and reconstruction boundary
12
12
 
@@ -104,7 +104,7 @@ This does not confer dependency, hydration, existence, execution, completion, or
104
104
  - Lazy content can itself be temporary; no semantic plane is an automatic safe haven from ownership cleanup.
105
105
  - Consequential survivors can be saved at an unowned appropriate path in the same atomic patch. This is model-authored reconciliation, not runtime promotion, archiving, or movement between scopes.
106
106
 
107
- The current reference grammar is explicitly scoped. Single-scope normalization is M3 work, not permission for M0 to change how unscoped stored references acquire ownership.
107
+ Canonical stored ownership references remain explicitly scoped. With exactly one wanted owner, the implemented [model boundary](single-scope-interface-contract.md) anchors eligible relative structured references to that captured owner before ownership/cascade processing, and projects them relatively on output. This translation grants no acquisition or publication authority.
108
108
 
109
109
  ## Patch, mode, and trust constraints
110
110
 
@@ -115,13 +115,13 @@ This contract inherits [model-tool semantics](architecture.md#model-tools); it d
115
115
  - No materialized semantic nulls, model-authored response/config/provenance, or empty acknowledgement-only scope patches.
116
116
  - One atomic cohort produces explicit accepted changes. No-op repeats produce no new semantic transition. An Active patch remains an inference barrier; Passive does not gain a new barrier by implication.
117
117
  - Active preserves necessary handoff memory before completed prior trajectory leaves normal projection. Passive can use the same semantic distinctions on demand without mandatory consolidation or a State Flow iteration reset. Off exposes no State Flow model context or tools.
118
- - Global, CWD, and Session can all carry the three core semantic functions. Later overlay precedence is composition, never evidence of greater truth or instruction authority. Configurable participation is not implemented by this contract.
118
+ - Global, CWD, and Session can all carry the three core semantic functions. Later overlay precedence is composition, never evidence of greater truth or instruction authority. The [scope contract](scope-selection-contract.md) owns configurable participation, independently of these semantic meanings.
119
119
  - References and state values are data. Package-reviewed trusted protocol may explain the planes, but ordinary memory, artifact compilations, or lazy values cannot alter system instructions.
120
120
  - Runtime publication, source provenance, response capture, native lifecycle ownership, and frozen-head reconciliation retain their established independent owners. The semantic relationship is not a module callback or hidden event network.
121
121
 
122
122
  ## Acceptance map
123
123
 
124
- The IDs below name contracts/oracles, not new runtime record types. Existing tests witness the old-name preservation mechanism. New-name native and model-behavior acceptance belongs to later milestones; this table is not a claim those tests already exist.
124
+ The IDs below name contracts/oracles, not new runtime record types. The table retains the original M0 evidence plan: its milestone/future references describe that checkpoint, not pending implementation. Current deterministic renamed/native witnesses are recorded in the [migration](semantic-compatibility-decision.md#source-bound-m1-validation), [scope](scope-selection-contract.md#m2-functional-acceptance-boundary) and [model-interface](single-scope-interface-contract.md#deterministic-m3-checkpoint) contracts. Live-model semantic acceptance remains unrun.
125
125
 
126
126
  | ID | Obligation and falsification scenario | Evidence owner |
127
127
  | --- | --- | --- |
@@ -133,9 +133,128 @@ The IDs below name contracts/oracles, not new runtime record types. Existing tes
133
133
  | SH-6 | Preserve sparse state, no-stored-null rules, detachment, explicit accepted cascade deletions, and exact retained replay. Fails if staging changes inputs, creates stored empty defaults, or replay needs to derive ownership again. | `tests/state.test.ts`, `tests/transition.test.ts`, `tests/temporal.test.ts`; future M1 codec/migration oracle. |
134
134
  | SH-7 | Preserve the frozen-prefix, trust, scope, response, and provenance boundaries while using the new semantic guidance. Fails if a memory patch changes system rules, relocates source ownership, or introduces a finalization inference. | Current `tests/protocol.test.ts`, `tests/context.test.ts`, response/Skill/native test families; M1–M4 integration checkpoints. |
135
135
 
136
+ ### Offline-bundle patch corpus
137
+
138
+ The following are **M1 model-patch examples**, using the implemented target dialect and explicit Session ownership with the default three-owner selection. A sole-owner selection instead uses the flat interface described in the [model-interface contract](single-scope-interface-contract.md). Field names inside planes are illustrative domain data, not a required schema. The scenario is a release bundle that must remain usable offline; no external release is executed by these examples.
139
+
140
+ **1. Open a chosen outcome linked to its temporary operational context.**
141
+
142
+ ```json
143
+ {
144
+ "session": {
145
+ "intents": {
146
+ "release": {
147
+ "outcome": "Prepare an offline-verifiable release bundle",
148
+ "context": { "$ref": "session.tactics.release" }
149
+ }
150
+ },
151
+ "tactics": {
152
+ "release": { "progress": "Bundle prepared; offline validation pending" }
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ **2. Preserve a hierarchical accepted strategy, including binding requirements and rejected alternatives.**
159
+
160
+ ```json
161
+ {
162
+ "session": {
163
+ "strategy": {
164
+ "release": {
165
+ "acceptance": "Accepted approach for this release",
166
+ "requirement": "User requires offline verification without credentials",
167
+ "phases": {
168
+ "prepare": { "approach": "Bundle dependencies and a verifier" },
169
+ "validate": {
170
+ "after": "prepare",
171
+ "approach": "Run the bundled verifier in network isolation"
172
+ }
173
+ },
174
+ "decision": "Use bundled verifier v1",
175
+ "rationale": "It is already packaged and expected to be self-contained",
176
+ "rejected": {
177
+ "online_only": "Cannot satisfy the offline requirement"
178
+ },
179
+ "assumption": "Verifier v1 never requires network access",
180
+ "reconsider_if": "A network-isolated validation attempts a connection"
181
+ }
182
+ }
183
+ }
184
+ }
185
+ ```
186
+
187
+ **3. Record actual progress and validation evidence, not a transcript.**
188
+
189
+ ```json
190
+ {
191
+ "session": {
192
+ "tactics": {
193
+ "release": {
194
+ "progress": "Preparation complete; validation blocked",
195
+ "validation": {
196
+ "check": "Network-isolated bundle verification",
197
+ "result": "Failed",
198
+ "evidence": "Verifier v1 attempted to fetch its trust index"
199
+ },
200
+ "uncertainty": "Whether an embedded trust index is sufficient",
201
+ "next": "Inspect the verifier's offline-index interface"
202
+ }
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ **4. After inspection establishes the supported alternative, revise strategy with reasons.** The failure invalidates the assumption, not the user's offline requirement. Updating the existing `rejected` object merges rather than discarding `online_only`.
209
+
210
+ ```json
211
+ {
212
+ "session": {
213
+ "strategy": {
214
+ "release": {
215
+ "decision": "Bundle an embedded trust index with verifier v1",
216
+ "rationale": "The supported local-index option removes the observed fetch",
217
+ "rejected": {
218
+ "default_v1": "Network-isolated validation proved its default index is remote"
219
+ },
220
+ "assumption": "The bundled index covers every bundle dependency",
221
+ "reconsider_if": "An index-coverage or network-isolation check fails",
222
+ "phases": {
223
+ "prepare": { "approach": "Bundle dependencies, verifier, and trust index" }
224
+ }
225
+ }
226
+ },
227
+ "tactics": {
228
+ "release": {
229
+ "observation": "Exact-source inspection confirmed a supported local-index option",
230
+ "uncertainty": null,
231
+ "next": "Rebuild the bundle; rerun coverage and isolation checks"
232
+ }
233
+ }
234
+ }
235
+ }
236
+ ```
237
+
238
+ **5. Only after both checks pass, close the intent and retain the durable conclusion.** In this example the intent owns only `session.tactics.release`, not `session.strategy.release`: acceptance records the tactical deletion while the unowned strategy fields receive an ordinary merge and survive. If the intent also owned strategy.release, cleanup would clear it first and the patch would need to explicitly rewrite every consequence that must remain. Empty `intents`/`tactics` planes disappear if they have no other entries.
239
+
240
+ ```json
241
+ {
242
+ "session": {
243
+ "strategy": {
244
+ "release": {
245
+ "conclusion": "Coverage and isolation checks passed with the embedded index"
246
+ }
247
+ },
248
+ "intents": { "release": null }
249
+ }
250
+ }
251
+ ```
252
+
253
+ These conclusions survive intent closure in the same canonical owner; that does not make Session memory cross-session Global knowledge. A proven change of applicability still needs an explicit verified move, never an automatic promotion.
254
+
136
255
  ### Five-example review exercise and answer key
137
256
 
138
- The five JSON patches in [BACKLOG §5.2](../BACKLOG.md#52-coherent-target-examples) form one sequential example, not five unrelated snapshots. A reviewer should be able to reconstruct the following without the original design conversation:
257
+ The five JSON patches in the [offline-bundle corpus above](#offline-bundle-patch-corpus), relocated from the published v0.27.1 backlog, form one sequential example, not five unrelated snapshots. A reviewer should be able to reconstruct the following without the original design conversation:
139
258
 
140
259
  1. **Open outcome:** Prepare an offline-verifiable release bundle. The intent owns `session.tactics.release` through a structured reference. No claim of final validation success exists.
141
260
  2. **Accepted strategy:** Offline verification without credentials remains the user's binding requirement. Preparation precedes network-isolated validation. Bundled verifier v1 is the accepted approach; its self-containment is an assumption. Online-only verification was rejected because it cannot satisfy the requirement.
@@ -149,7 +268,7 @@ The fifth precondition is a semantic claim supplied by the scenario. A determini
149
268
 
150
269
  M0.1 checked the example against existing mechanisms without implementing the rename:
151
270
 
152
- - Extracted the five JSON patches from the linked backlog section.
271
+ - Extracted the five JSON patches from the then-current backlog section (the corpus is now retained above).
153
272
  - Mapped only the scope-root plane names `strategy → contract`, `tactics → working`, and corresponding scoped structured-reference plane segments. Did not rewrite arbitrary prose/domain keys, change source files, or persist a converter.
154
273
  - Staged and committed each mapped patch entirely in memory with `stageAtomicScopePatches` / `commitScopedTransition`, no acquired sources and no run finalization; replayed the actual accepted records with `advanceTemporalState`.
155
274
  - Asserted staging detachment, unchanged Global/CWD, binding-requirement retention, both rejection reasons, surviving phase dependency, retained failed-check evidence after revision, deletion of only resolved uncertainty, and absence of authored response.
@@ -162,13 +281,12 @@ Historical focused-source command (not validation of the current cascade contrac
162
281
  node --experimental-strip-types --test tests/state.test.ts tests/ownership.test.ts tests/transition.test.ts tests/temporal.test.ts tests/protocol.test.ts
163
282
  ```
164
283
 
165
- Result for the source identity above: **76 passed, 0 failed**. These tests cover current old-name semantics; they neither certify an unimplemented rename nor substitute for M0.4 real-model baseline evidence. The in-memory example probe did not exercise disk CAS, migration, provider schemas, new selection policy, or flat-reference conversion.
284
+ Result for the source identity above: **76 passed, 0 failed**. These tests covered the then-current old-name semantics; that historical result neither certified the later rename nor substitutes for M0.4 real-model baseline evidence. The in-memory example probe did not exercise disk CAS, migration, provider schemas, new selection policy, or flat-reference conversion.
285
+
286
+ ## Historical handoff and current limits
166
287
 
167
- ## Remaining boundaries
288
+ The original M0.1 handoff required M0.2 compatibility decisions and M0.3 selection/private/response/fork decisions before their dependent implementation. Those obligations were subsequently met under the linked migration and scope contracts; flat paths and internal/public modules also shipped in 0.27.0. They are not unresolved prerequisites.
168
289
 
169
- The semantic meanings and preservation obligations above are the M0.1 handoff. The [canonical backlog](../BACKLOG.md#12-ordered-implementation-backlog) owns outstanding work:
290
+ Real-model evaluation remains separate and unrun; the [evaluation contract](semantic-memory-evaluation.md) owns its corpus, rubric and execution gate, while [BACKLOG.md](../BACKLOG.md) owns remaining action. Dynamic loading, background scheduling and new cognitive planes were not delivered by these milestones.
170
291
 
171
- - M0.2 must settle the historical representation, collision/dialect fence, and public-API compatibility contract before M1 changes codecs.
172
- - M0.3 must settle selection metadata, disabled-stream authority, response-without-Session, and fork policy before M2.
173
- - M0.4 must obtain source/model-bound behavioral observations; no such evaluation was performed in this slice.
174
- - Schema adaptation, flat paths, module loading/hooks, and later milestone implementation remain excluded from M0.1. Nothing in this document enables them implicitly.
292
+ The superseded development roadmap is preserved at [the published v0.27.1 source](https://github.com/llblab/pi-state-flow/blob/f9128d9eaa2b94133d992f51f80f16aec0d43653/BACKLOG.md). Its baseline observations, execution instructions and review statuses are historical evidence, not current normative policy. The corpus above and the indexed owning contracts retain the useful semantic rationale and acceptance counterexamples without keeping completed queues active.
@@ -2,11 +2,11 @@
2
2
 
3
3
  ## Status and evidence boundary
4
4
 
5
- **Deferred post-implementation comparison — no live baseline executed.** Following the owner's 2026-10-24 implementation-first direction, this trial no longer gates M1–M5 implementation. Preserve the baseline source and fixed corpus for later comparison, disclose any model/provider drift, and never relabel calibration as model behavior. This run sheet specifies one small reproducible linked-task trial and its oracles. The opt-in [runner](../benchmarks/semantic-memory.mjs) now implements the isolated fixture/measurement mechanics and offline scripted calibration; it is not a live model result or evidence that the proposed semantic names improve quality. [BACKLOG.md](../BACKLOG.md#13-evaluation-and-acceptance-strategy) owns remaining execution and acceptance work.
5
+ **Deferred post-implementation comparison — no live baseline executed.** Following the owner's 2026-10-24 implementation-first direction, this trial no longer gates M1–M5 implementation. Preserve the baseline source and fixed corpus for later comparison, disclose any model/provider drift, and never relabel calibration as model behavior. This run sheet specifies one small reproducible linked-task trial and its oracles. The opt-in [runner](../benchmarks/semantic-memory.mjs) now implements the isolated fixture/measurement mechanics and offline scripted calibration; it is not a live model result or evidence that the proposed semantic names improve quality. [BACKLOG.md](../BACKLOG.md#external-validation-and-evaluation) owns remaining execution and acceptance work.
6
6
 
7
7
  The existing [performance workloads](performance.md) and [benchmark guide](../benchmarks/README.md) are synthetic transport/performance evidence. The current [semantic handoff evidence](semantic-handoff-contract.md#source-bound-validation-evidence) is an old-name in-memory preservation probe. Neither is a replacement for the model observations defined here.
8
8
 
9
- ### Local preflight result
9
+ ### Historical M0 local preflight result
10
10
 
11
11
  The preparation inspected only SDK/tool metadata and repository source, without live canonical-store access:
12
12
 
@@ -37,7 +37,7 @@ This is 12 user inputs, not necessarily 12 model requests: normal tool turns and
37
37
 
38
38
  Use the same pinned physical model/provider and reasoning level for all three conditions. Do not silently switch providers when one fails. A provider alias is not an immutable model snapshot: report any actual snapshot identity the provider exposes, or record that it is unavailable. Do not fabricate immutable version provenance from the catalogue name.
39
39
 
40
- The preserved M0 baseline source uses old semantic names with all three scopes. The current runner/calibration now follows the unreleased M1 Strategy/Tactics API; that does not retroactively produce an old-version live baseline. Later comparisons must bind each condition to its actual source/schema digest. Configurable scopes, flat references and module protocols remain future conditions until implemented.
40
+ The preserved M0 baseline source uses old semantic names with all three scopes. The current runner/calibration follows the Strategy/Tactics API released in 0.27.0; that does not retroactively produce an old-version live baseline. Later comparisons must bind each condition to its actual source/schema digest. Seven-selection and flat-interface mechanics are implemented, but their real-model comparison is unrun. The runner's initial all-three conditions are not a substitute for that separate comparison.
41
41
 
42
42
  ## Isolation and native host setup
43
43
 
@@ -137,7 +137,7 @@ Score each applicable semantic obligation as **met / violated / not exercised /
137
137
  - **Closure and survivors:** An actually completed commitment closes; durable conclusions survive. Record actual ownership usage separately from its correctness.
138
138
  - **Rediscovery/churn:** Repeated reads, repeated tests, no-op patches, needless full-plan replacement, and semantic growth are observations. A necessary revalidation after artifact change is not needless repetition.
139
139
 
140
- Flattened one-scope operation and disabled-owner writes cannot be scored against the preserved4494fee/0.26.5 baseline as if implemented there; their installed target mechanics are covered by the later M2/M3 checkpoints, not by this historical baseline. Reserve those cases for M3's comparison, with actual schemas and excluded-owner byte hashes. M4 adds only a protocol-composition comparison once M1–M3 are stable.
140
+ Flattened one-scope operation and disabled-owner writes cannot be scored against the preserved4494fee/0.26.5 baseline as if implemented there; their installed target mechanics are covered by the later M2/M3 checkpoints, not by this historical baseline. Reserve those cases for M3's comparison, with actual schemas and excluded-owner byte hashes. The historical roadmap also proposed a protocol-composition comparison. M4 ultimately retained existing renderers without changing protocol output, so that decision creates no new experimental treatment or requirement to invent one. Any later cognitive-benefit claim needs separately authorized comparable conditions.
141
141
 
142
142
  ## Compact report shape and interpretation
143
143
 
@@ -163,4 +163,4 @@ Calibration on the M0 source/SDK stack exercised four native user runs per condi
163
163
 
164
164
  These observations validate harness mechanics only. They are not behavioral rubric scores, live token charges, physical network-isolation proof, or provider cache measurements. The raw public usage fields in faux reports must not be interpreted as live-provider cost evidence.
165
165
 
166
- After functional implementation and deterministic validation, M0.4b requires the authorized credential-capable route and bounded execution settings stated above. Execute comparable baseline/target real-model conditions where reproducible, review the semantic rubric, and retain the compact source-bound report. The canonical backlog retains this deferred remainder; missing model observations do not block changing runtime names or prompts. Do not treat calibration or missing baseline observations as completed model evidence or an agent-quality improvement.
166
+ After functional implementation and deterministic validation, M0.4b requires the authorized credential-capable route and bounded execution settings stated above. Execute comparable baseline/target real-model conditions where reproducible, review the semantic rubric, and retain the compact source-bound report. The canonical backlog retains this deferred remainder separately from 0.27.2 release-local cleanup; missing model observations do not reopen completed runtime implementation. Do not treat calibration or missing baseline observations as completed model evidence or an agent-quality improvement.
@@ -2,9 +2,9 @@
2
2
 
3
3
  ## Status and boundary
4
4
 
5
- The internal implementation has supported-Node validation and bounded independent acceptance. The contract and executors are implemented in `lib/semantic-module.ts`; the existing six planes use static bindings in `lib/planes.ts`. This delivered boundary is package-owned composition, not a public plugin ABI, discovery mechanism or external loader. No new native option, stored root, storage version, `immutable/content` disk envelope or tool grammar was introduced by this cohort. The earlier [M4](protocol-composition-decision.md) and [M5](semantic-extensibility-decision.md) retain/defer decisions describe their original evidence. The user's subsequent public-registration request is separate open work in [BACKLOG](../BACKLOG.md#12-ordered-implementation-backlog), not functionality supplied by this internal contract.
5
+ The internal contract and executors in `lib/semantic-module.ts`, with six static plane bindings in `lib/planes.ts`, shipped in **0.27.0**. This boundary is package-owned composition, not a discovery mechanism or external loader. Its original cohort introduced no stored root, storage version, `immutable/content` disk envelope or tool grammar. The earlier [M4](protocol-composition-decision.md) and [M5](semantic-extensibility-decision.md) retain/defer decisions remain historical evidence. Subsequent explicitly authorized work also shipped the [public module registration boundary](public-module-contract.md), including metadata v4 external roots, using the same evaluators and acceptance engine rather than a second semantic engine.
6
6
 
7
- A module participates in context construction. Its identity is not permission to acquire memory, register a stored plane or publish state. The generic contract is not restricted to the six existing names; the current storage/tool binding deliberately is. [BACKLOG](../BACKLOG.md#12-ordered-implementation-backlog) alone owns unfinished public-registration work.
7
+ A module participates in context construction. Its identity is not permission to acquire memory, register a stored plane or publish state. The internal generic contract is not restricted to the six existing names; `lib/planes.ts` binds only the six built-ins. External root admission, native-host registration and retained descriptors belong to the public contract, not these static bindings.
8
8
 
9
9
  ## The five-member contract
10
10
 
@@ -48,7 +48,7 @@ Selection is not authority to replace arbitrary context. The host still owns adm
48
48
 
49
49
  `produceModuleContent(module, content, input, signal, checkCurrent)` captures inputs, awaits the producer and admits a detached candidate. The host's original-currency assertion and cancellation run before work and after completion/validation. `checkCurrent` is a throwing revalidator (`() => void`), not a boolean predicate; the host must throw when its original basis is obsolete. Cancellation returns without waiting for a producer that ignores its signal; late completion cannot escape as an accepted result. Returned data cannot alias the original input, producer result or the validator's retained argument. This is data isolation, not a JavaScript effects sandbox.
50
50
 
51
- The function never installs state, increments revisions, grants a scope or calls a publisher. A future host adapter must bind its captured conversation/content/model/owner/selection basis to the existing synchronous acceptance check. Starting a fresh transaction and borrowing its current token does not make an old candidate current. Reject/recompute policy must be explicit.
51
+ The function never installs state, increments revisions, grants a scope or calls a publisher. A host adapter must bind its captured conversation/content/model/owner/selection basis to the existing synchronous acceptance check; the public integration does so under its own contract. Starting a fresh transaction and borrowing its current token does not make an old candidate current. Reject/recompute policy must be explicit.
52
52
 
53
53
  Inference, source acquisition and asynchronous production stay outside canonical exclusion. Constructor-injected inference is enough for the contract; no model client, credentials, agent loop, scheduler or actual background inference is added here. A readonly signature cannot prevent ambient JavaScript effects in trusted package code.
54
54
 
@@ -75,10 +75,10 @@ The local dependency direction is `state/context/model-interface/transition -> p
75
75
 
76
76
  The contract witnesses exercise a stateless exact recent-window module and an immutable archive producer with constructor-injected fake inference. They prove mode-aware contribution transport, preserved source identities, asynchronous candidate isolation, cancellation and obsolete-completion rejection. They are not dummy production planes and are not described as a working archive.
77
77
 
78
- Not implemented by this boundary: new stored planes/codecs, archive node retention/version history, a selected-model inference adapter, background jobs, automatic raw-context replacement, public loading/registration or a stored envelope migration. Those require their actual storage/lifecycle/authority decisions rather than adding unused hooks now. A future module can use the contract without acquiring those permissions by identity alone.
78
+ The internal boundary itself does not register external roots or define codecs; the separately delivered public contract owns those responsibilities. Production archives, a selected-model inference adapter, background jobs, dynamic loading and stored envelope migration remain unimplemented. Native conversation selection is admitted only under the public host contract, not by an arbitrary callback's identity.
79
79
 
80
80
  ## Verification
81
81
 
82
82
  `tests/semantic-module.test.ts` owns contract/input/contribution/producer properties; `tests/planes.test.ts` owns real bindings, immutability and navigation/projection. `tests/context.test.ts` owns user-data transport and exact native-message/tool-identity materialization. Existing state/context/model-interface/transition and native SDK tests retain the prior semantic, publication and lifecycle witnesses.
83
83
 
84
- A finite before/after certificate captures all seven selections' Active/bootstrap/Passive protocols, representative sparse/hot/model/context values and intent-cascade output. Equality is useful default-output evidence, not exhaustive AST/runtime equivalence or model-quality proof. Full supported-Node validation, generated-build parity, package inventory, DAG/context checks and independent post-implementation review are separate acceptance evidence; current results belong in canonical remaining work until actually complete.
84
+ A finite before/after certificate captures all seven selections' Active/bootstrap/Passive protocols, representative sparse/hot/model/context values and intent-cascade output. Equality is useful default-output evidence, not exhaustive AST/runtime equivalence or model-quality proof. Supported-Node validation, generated-build parity, package inventory, DAG/context checks and bounded independent internal-contract review were recorded during 0.27.0 development. Those records retain their original scope; later public activation was audited inline, not independently approved. Release CI does not establish live-model quality or installed-client compatibility; see [compatibility](compatibility.md).
@@ -2,9 +2,9 @@
2
2
 
3
3
  ## Status and boundary
4
4
 
5
- M2 participation/control is complete within the [functional scope boundary](scope-selection-contract.md#m2-functional-acceptance-boundary). M3.1's installed-SDK/local-provider serialization decision is independently **VERIFIED / APPROVE** within the mechanical boundary below. **Native patch roots now follow captured wanted arity:** five flat planes for one owner, explicit owner dictionaries for multiple owners. Both real tools consume the accepted translator only after M2 admission. Native mutation binding and the [deterministic FUNCTIONAL M3 checkpoint](#deterministic-m3-checkpoint) are independently **VERIFIED / APPROVE** within their stated evidence boundaries, not live-model quality. The SDK capability probes themselves publish no memory and confer no private acquisition. The native-read slice below is independently **VERIFIED / APPROVE** within its bounded evidence; neither that historical slice nor accepted mutation binding alone is whole-M3 model-surface acceptance. [BACKLOG.md](../BACKLOG.md#12-ordered-implementation-backlog) alone owns deferred real-model evidence and subsequent M4/M5 decisions.
5
+ M2 participation/control is complete within the [functional scope boundary](scope-selection-contract.md#m2-functional-acceptance-boundary). M3.1's installed-SDK/local-provider serialization decision is independently **VERIFIED / APPROVE** within the mechanical boundary below. **Native patch roots follow captured wanted arity:** five built-in writable planes plus compatible registered mutable external roots, flat for one owner or in explicit owner dictionaries for multiple owners. Public external-root admission is owned by the [public module contract](public-module-contract.md). Both real tools consume the accepted translator only after M2 admission. Native mutation binding and the [deterministic FUNCTIONAL M3 checkpoint](#deterministic-m3-checkpoint) are independently **VERIFIED / APPROVE** within their stated evidence boundaries, not live-model quality. The SDK capability probes themselves publish no memory and confer no private acquisition. The native-read slice below is independently **VERIFIED / APPROVE** within its bounded evidence; neither that historical slice nor accepted mutation binding alone is whole-M3 model-surface acceptance. M4/M5's historical decisions and later internal/public module work also shipped in 0.27.0; [BACKLOG.md](../BACKLOG.md) owns only outstanding work, including separately gated real-model evidence.
6
6
 
7
- The task is to remove mandatory scope knowledge from ordinary single-owner model operations without losing canonical ownership, history, cancellation or multi-owner atomicity. Mode, owner participation and model presentation remain separate. A flat declaration is not an authoring grant.
7
+ The task is to remove mandatory scope knowledge from ordinary single-owner model operations without losing canonical ownership, history, cancellation or multi-owner atomicity. Mode, owner participation and model presentation remain separate. A flat declaration is not an authoring grant. The implementation-slice sections below retain their original then-current gates, counts and verdicts; statements about later M3 slices being pending describe those historical checkpoints, not the current released interface.
8
8
 
9
9
  ## Schema decision
10
10
 
@@ -27,7 +27,7 @@ One session-owned `mode` selects these behaviors; there are no separate passive-
27
27
  - an extra model turn;
28
28
  - a special finalization tool.
29
29
 
30
- Each `patch_state` is 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.
30
+ In Active mode, `patch_state` is an inference barrier, not automatically the end of an iteration; Passive has no such barrier. The runtime separately completes the run and captures the accepted ordinary answer only in Active participating Session. With Session excluded, completion is lifecycle-only unless another semantic change is accepted; no answer is backfilled or relocated.
31
31
 
32
32
  **Two meanings of “bootstrap”:**
33
33
 
@@ -51,31 +51,39 @@ Active, Passive and Off select the session's workflow and model-facing access, n
51
51
 
52
52
  All three mode commands accept optional exact owner tokens, in any order: `/state-flow-active session`, `/state-flow-passive cwd global`, `/state-flow-off cwd session`. Any nonempty unique subset of `global cwd session` is valid; autocomplete offers only unused matching tokens and replaces the full argument prefix. Blank/whitespace-only arguments preserve the captured choice. Unknown/duplicate names, flags and comma-separated forms fail before policy or mode changes. Commands never edit global defaults. Off scope changes record native policy only, without reading or initializing canonical memory. Active explicitly owns acquisition where independently permitted; Passive observation alone cannot acquire missing Session or borrow pending fork permission.
53
53
 
54
- Selection is not materialization: all three scopes are selected by default, but a pre-runtime Passive session can have no private Session cohort yet. Read-only observation exposes existing shared owners without inventing empty Session state. An explicit read of a selected owner missing from that read view reports `selected, unavailable`, not `excluded`; an actually excluded owner is rejected by the selection guard. A legitimate first Session patch on an eligible non-fork branch can acquire private memory through normal atomic acceptance. Do not send an empty patch just to initialize it or bypass pending-fork authority.
54
+ All seven nonempty owner sets are supported: `global`, `cwd`, `session`, `global cwd`, `global session`, `cwd session`, and `global cwd session`. Omission of global `scopes` defaults to all three; changing a current selection never moves or migrates data between owners.
55
+
56
+ Selection is not materialization:
57
+
58
+ - **Wanted:** The owner is selected by captured policy; wanted arity chooses flat versus explicit-owner grammar.
59
+ - **Available:** A validated read view exists for that owner. A pre-runtime Passive session can observe shared owners while wanted Session remains unacquired.
60
+ - **Excluded:** The owner is outside the wanted policy. Model reads/writes reject it rather than widening selection.
61
+
62
+ In the 0.27.1 diagnostic, an explicit read of wanted but unavailable Session reports `State Flow session: selected, unavailable`, not exclusion. Reads never invent or acquire private memory, and a mixed available/unavailable batch returns no partial values. A legitimate first Session patch on an eligible non-fork branch can acquire private memory through normal atomic acceptance. Do not send an empty patch to initialize it or bypass pending-fork authority.
55
63
 
56
64
  How each lifecycle event behaves:
57
65
 
58
- - **New session:** Adopts the global `mode`, defaulting to Off.
59
- - An inactive default is recorded once in Pi as `{mode:"off"}` or `{mode:"passive"}`, without creating semantic storage.
60
- - An Active default initializes a distinct empty Session layer over global/CWD memory, never another session's private continuation.
66
+ - **New session:** Captures global `mode` and `scopes`, defaulting to Off and all three owners.
67
+ - An inactive default is recorded once in an owner-bound native v2 policy record containing `{mode, scopes}`, without creating semantic storage.
68
+ - An Active default accepts the selected owners; if Session participates it initializes a distinct private layer, never another session's continuation. Shared-only choices create no hidden Session semantics.
61
69
  - **Resume:** Keeps the selected session's mode; later global default changes do not override it.
62
70
  - Passive/Active attach the current same-session memory and its retained history.
63
71
  - Off attaches native policy only, without probing semantic files or emitting recovery warnings.
64
- - **Tree navigation:** Restores the selected branch's mode, but never rewinds memory: State Flow does not depend on the Pi step. Passive/Active keep the current JSON state of every scope, which changes only through accepted patches. Off defers acquisition until a mode is explicitly selected.
65
- - **Fork:** The child copies its parent's current memory into its own session layer, independent of the step it forked from.
72
+ - **Tree navigation:** Restores the selected branch's mode, but never rewinds memory: State Flow does not depend on the Pi step. Passive/Active acquire the current JSON state of the selected owners under their existing authority, never an old semantic revision. Off defers acquisition until a mode is explicitly selected.
73
+ - **Fork:** The child inherits its parent's captured policy. With Session selected, admitted acquisition copies parent-current private memory into a fresh child owner, independent of the native step. Off or Session-excluded forks defer private copying; later admitted Session acquisition copies the parent's then-current state once.
66
74
  - **Abort inference:** Stops generation or an outstanding response-publication wait. Already accepted patches stay durable, so work and corrected direction can continue in the same session.
67
75
  - Cancellation before response acceptance keeps the previous response and the unfinished run.
68
76
  - Cancellation after acceptance never rolls it back.
69
77
  - Abort does not require immediate remote replication.
70
78
  - **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 the accepted response across those requests and later patches. It does not restore the completed specification or request another turn itself.
71
79
  - **Passive:** `/state-flow-passive` enables both memory tools and projection.
72
- - A proven pre-runtime branch records only `{mode}` in Pi and loads shared memory read-only.
80
+ - A proven pre-runtime branch records native v2 `{mode, scopes}` policy in Pi and observes only selected existing shared memory read-only.
73
81
  - Accepted runtimes persist Passive and adopt unrelated shared drift without semantic/provenance writes or revision/step changes.
74
82
  - Pending repeats share one acceptance.
75
83
  - **Off:** `/state-flow-off` removes memory tools and context, and immediately clears semantic caches.
76
84
  - It cancels owned restoration/fork, activation, preparation, response, patch and Passive-persistence waits.
77
85
  - It saves only native policy and continuation/fork bookmarks. Existing canonical bytes, including the old stored runtime mode, stay untouched even when malformed or busy.
78
- - Repeated Off is inert. Already accepted data is preserved, and a later explicit Passive/Active reacquires memory.
86
+ - Repeated mode-only Off with the same captured choice is inert; explicit different scopes change native policy only. Already accepted data is preserved, and a later explicit Passive/Active reacquires memory.
79
87
  - Global defaults and other sessions remain unchanged.
80
88
  - **If Passive cannot persist:** Off itself never attempts canonical persistence; this fallback concerns Passive.
81
89
  - The selected Passive policy stays applied. Accepted memory and the native conversation stay intact.
@@ -107,10 +115,11 @@ State Flow does not undo tool effects. After an interruption or a return to an o
107
115
 
108
116
  ### Fork support and limits
109
117
 
110
- **What a fork copies.** Memory-enabled native fork replacement copies the parent's **current** session checkpoint, retained patch tail and matching provenance into the new session's own storage, independent of the Pi step it forked from.
118
+ **What a fork copies.** When Session participates and private acquisition is admitted, native fork replacement copies the parent's **current** Session stream and matching provenance into the child's own storage, independent of the Pi step it forked from.
111
119
 
112
- - Off records only a child-owned pending-fork policy. Header/store reads and copying wait until an explicit Passive/Active, including after a cold reload.
113
- - Global/CWD values and provenance stay current. Applying a smaller `historyLimit` may fold shared tails under CAS.
120
+ - Off records only child-owned native pending-fork policy; parent-header/store reads and copying wait for admitted Passive/Active acquisition, including after cold reload.
121
+ - With Session excluded, enabled modes accept selected shared owners plus child lifecycle metadata without reading/copying parent-private memory. Later explicit Session acquisition requires that child's deferred-copy proof and an absent private target; an acquired child never recopies.
122
+ - Selected Global/CWD values and provenance stay current. Applying a smaller `historyLimit` may fold selected shared tails under CAS; excluded semantic files stay unchanged.
114
123
  - Parent-private data and history stay intact. The selected mode is kept, so an inactive source does not become Active automatically.
115
124
 
116
125
  **The child's own history.** The child starts at step zero with a new temporal origin.
@@ -119,12 +128,12 @@ State Flow does not undo tool effects. After an interruption or a return to an o
119
128
  - The child's own transitions build its hot window, and owned checkpoints support normal reload/resume.
120
129
  - Parent Stop projection is not inherited, including after a child reload.
121
130
 
122
- **Requirements for the initial copy:** a native fork start event, a regular canonical direct-parent session file, matching CWD/identity, a readable temporal source and an unused child namespace. Missing or unsafe evidence or a CAS conflict leaves the copy unavailable rather than importing unrelated private state. Explicit Start can retry an unaccepted copy in the same loaded fork once the cause is corrected.
131
+ **Requirements for the initial copy:** a native fork start event, a regular canonical direct-parent session file, matching CWD/identity, a readable current temporal source and an unoccupied child semantic target. A lifecycle-only child must additionally prove its own deferred-copy authority before private acquisition. Missing or unsafe evidence or a CAS conflict leaves the copy unavailable rather than importing unrelated private state. Explicit Start can retry an unaccepted copy in the same loaded fork once the cause is corrected.
123
132
 
124
133
  **Limits:**
125
134
 
126
135
  - Selecting a copied parent step through the child's `/tree` keeps current child-owned memory; it neither rewinds nor recopies parent data.
127
- - Cold recovery before the first child checkpoint requires an Off-deferred pending-fork marker. Otherwise, it and startup paths lacking the fork event remain unsupported.
136
+ - Cold recovery before first private acceptance requires child-owned pending-fork authority; an accepted shared-only child also retains its matching deferred lifecycle proof. Missing files alone and startup paths without valid fork authority cannot authorize copying.
128
137
  - In-memory parent locators and cross-CWD imports remain unsupported.
129
138
  - File-only copying requires an exact still-available source cohort.
130
139
 
@@ -137,6 +146,7 @@ An optional global `config.json` lives at the root of the State Flow repository,
137
146
  ```json
138
147
  {
139
148
  "mode": "off",
149
+ "scopes": ["global", "cwd", "session"],
140
150
  "logging": false,
141
151
  "showSuccessfulPatches": true,
142
152
  "historyLimit": 7
@@ -226,9 +236,9 @@ When `pi-telegram` is available, its main-menu section shows `State Flow: active
226
236
  - The submenu heading shows the current value in monospace.
227
237
  - The bold Mode heading uses a long dash, a description ending in a colon, and a blank line before its settings-style list. Each line has a monospaced minus and lowercase monospaced mode value, then a plain colon and description.
228
238
  - 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 disabled native compaction.
229
- - A Participating scopes line shows the captured current choice, initially from global defaults; later default edits do not replace an existing session choice. Mode/help text describes only that set and states when excluded Session means new answers are delivered without storage.
239
+ - The captured participating owners are named by the Inspect participating memory list below, not a separate line; later default edits do not replace an existing session choice. Mode/help text describes only that set.
230
240
  - The bold Inspect participating memory heading follows the same long-dash, description, colon and blank-line pattern. Only selected owners get a monospaced description and direct button; this is not a scope chooser.
231
- - With one selected owner, its state is also effective and no separate Effective button appears. With two or three, Effective shows the validated available overlay of those selected owners only, in Global→CWD→Session order. Excluded owners do not contribute or gain an inspection action.
241
+ - With one selected owner there is no separate effective state: the agent reads that owner directly, so neither an Effective line nor button appears. With two or three, Effective shows the validated available overlay of those selected owners only, in Global→CWD→Session order. Excluded owners do not contribute or gain an inspection action. The Effective description is a fixed sentence, not an owner enumeration: the list above already names the selected owners.
232
242
 
233
243
  **Memory inspection:**
234
244
 
@@ -273,9 +283,9 @@ See the [storage contract](architecture.md#storage-and-identity) for the exact l
273
283
  **Missing fields are fine.** Missing documented fields inside a valid checkpoint or patch are supported.
274
284
 
275
285
  - 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.
276
- - Unknown top-level fields are ignored when reading checkpoints/patches and are not emitted on later writes; nested data within known planes stays intact.
286
+ - Built-in fields and metadata v4-declared external roots are known semantic content. Declared external values/history survive missing or incompatible definitions; unrelated unknown roots remain outside the supported semantic view. Retired target-format roots explicitly reject rather than being silently ignored. Nested data within admitted planes stays intact.
277
287
  - An explicit `read_state` value query for an absent documented top-level field returns `null`, including an empty or absent `session.response`.
278
- - Reading and Start do not normalize files, advance revisions or require a migration.
288
+ - Read-only inspection never normalizes or converts files. Start does not fill missing planes or create a semantic revision merely for normalization; independently authorized acceptance may perform the supported backed-up format conversion described below.
279
289
  - An empty semantic object is different from a missing file or missing ownership metadata.
280
290
 
281
291
  **Wholly absent shared files.** A checkpoint and its tail are one semantic pair. If both live files of 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, and 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.
@@ -342,11 +352,11 @@ Commit or push failure is diagnostic-only; repeated push failures warn once per
342
352
  **Supported formats.** State Flow accepts only canonical checkpoint/tail files, temporal metadata and the separate session config/runtime contract.
343
353
 
344
354
  - Scope metadata versions 1/2 remain readable through explicit `contract → strategy`, `working → tactics` translation before field filtering. Current/historical tools expose only the target dialect; retired root writes reject rather than becoming aliases. Legacy missing revisions credit only retained tail records.
345
- - New writes use scope metadata version 3. On an owned semantic acceptance, legacy cohorts convert with unchanged semantic revisions/causal identities, under the existing lock/CAS and rollback checks. Ordinary inspection and runtime-only mode persistence do not convert files. Upgrade/quiesce all writers before enabling the new code: already-deployed low-level readers cannot be universally fenced by a format number.
355
+ - Core-only writes use scope metadata v3; retained external-module descriptors select v4. Both use Strategy/Tactics. On owned semantic acceptance, supported legacy/descriptor upgrades use the same backup, lock/CAS and rollback checks without advancing revisions/causal identities for representation alone. Ordinary inspection and runtime-only mode persistence do not convert files. Upgrade/quiesce all writers before enabling the new code: already-deployed low-level readers cannot be universally fenced by a format number.
346
356
  - Unsupported checkpoint envelopes, combined session metadata, `state.json`, hashed layouts and semantic Pi checkpoint envelopes fail as unsupported, without rewriting existing bytes.
347
357
  - Canonical semantic objects lacking optional fields, such as `intents` or `lazy`, are valid sparse state and do not cross this boundary.
348
- - Before any v1/v2-to-v3 canonical publication, the storage owner writes and verifies an exact-byte JSON backup at `<parent-of-store>/<store-name>-migration-backups/<sha256>.json` (created with directory mode 0700, file mode 0600 on the verified platform; existing non-private paths reject). It lists converted scopes and updated paths alongside the transaction's owned file basis, relative paths, identities, Base64 originals and explicit missing entries, including required Session config/runtime. It never discovers unrelated projects/sessions or source bodies. The returned publication exposes `migrationBackup`; completed backups survive rollback and exact retries reuse them. Backup failure blocks canonical writes.
349
- - This backup is recovery evidence outside canonical authority, not a Git commit, journal, automatic fallback or power-loss guarantee. Quiesce writers and request a reviewed complete-cohort recovery before downgrade/restoration; do not overwrite intervening foreign data or restore just one file. Retain backups privately. State Flow 0.x retains legacy conversion and retired-root reservations; the temporary support window ends at State Flow 1.0.0, with unsupported versions still explicitly rejected. The prepared0.27.0 candidate keeps its converter/reservations unchanged; no automatic removal, release or working-store migration follows. See the [settled support policy](semantic-compatibility-decision.md#implementation-direction-and-reserved-names).
358
+ - Before a supported legacy or explicit metadata upgrade is canonically published, the storage owner writes and verifies an exact-byte JSON backup at `<parent-of-store>/<store-name>-migration-backups/<sha256>.json` (created with directory mode 0700, file mode 0600 on the verified platform; existing non-private paths reject). It lists converted scopes and updated paths alongside the transaction's owned file basis, relative paths, identities, Base64 originals and explicit missing entries, including required Session config/runtime. It never discovers unrelated projects/sessions or source bodies. The returned publication exposes `migrationBackup`; completed backups survive rollback and exact retries reuse them. Backup failure blocks canonical writes.
359
+ - This backup is recovery evidence outside canonical authority, not a Git commit, journal, automatic fallback or power-loss guarantee. Quiesce writers and request a reviewed complete-cohort recovery before downgrade/restoration; do not overwrite intervening foreign data or restore just one file. Retain backups privately. State Flow 0.x retains legacy conversion and retired-root reservations; the temporary support window ends at State Flow 1.0.0, with unsupported versions still explicitly rejected. Released 0.27.0/0.27.1 retain their converter/reservations, and 0.27.2 preserves that policy; no automatic removal, release or working-store operation follows from consolidation. See the [settled support policy](semantic-compatibility-decision.md#implementation-direction-and-reserved-names).
350
360
 
351
361
  ### Conflicts and interrupted publication
352
362
 
@@ -359,7 +369,7 @@ Commit or push failure is diagnostic-only; repeated push failures warn once per
359
369
 
360
370
  Do not repeat external actions while memory publication waits.
361
371
 
362
- **Final answers.** Final-answer reconciliation also waits cancelably, then saves the response and the completed-run lifecycle together over current shared memory. Stop, session/tree changes, shutdown and a superseding answer cancel obsolete waits without modifying newer work. A failed or canceled publication leaves the prior response and unfinished run intact; it never requests a repair inference.
372
+ **Final answers.** Active final-answer reconciliation waits cancelably, then completes the run over current selected memory and saves the response only when Session participates. Session-excluded completion does not write a hidden private/shared answer. Stop, session/tree changes, shutdown and a superseding answer cancel obsolete waits without modifying newer work. A failed or canceled publication leaves the prior response and unfinished run intact; it never requests a repair inference.
363
373
 
364
374
  **Run preparation.** 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 stays 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.
365
375
 
@@ -420,7 +430,7 @@ The agent should use sufficient materialized knowledge before rereading files. I
420
430
 
421
431
  **Artifact maintenance:**
422
432
 
423
- - It inspects only exact paths already registered in global, CWD or session state, using `size + mtimeNs`, without directory traversal or generic content hashing.
433
+ - It inspects only exact registered paths owned by selected scopes, using `size + mtimeNs`, without directory traversal or generic content hashing. Excluded owners receive no automatic source maintenance or relocation.
424
434
  - Proven-missing paths are pruned from their exact owning scopes. Unavailable, relative, directory and symlink paths are preserved.
425
435
  - Changed sources keep their artifact value and receive a runtime-only model `hint` until a stable read and same-path compilation update the hidden provenance.
426
436
  - Model patches cannot author or delete runtime provenance or hints.
@@ -243,16 +243,12 @@ export default function stateFlowExtension(pi: ExtensionAPI, options: StateFlowE
243
243
  owner: ctx.sessionManager.getSessionId(), mode: snapshot.config.mode, scopes: nativeScopeSelection(ctx), ...value }));
244
244
  }
245
245
 
246
- function assertNativeMemoryScopes(scopes: readonly StateScope[]): void {
247
- captureScopeSelection(scopes);
248
- }
249
-
250
246
  function branchPolicy(ctx: ExtensionContext, reason?: unknown, memoryRequired = true) {
251
247
  const branch = ctx.sessionManager.getBranch();
252
248
  const policy = prepareSelectedBranchPolicy(branch, { owner: ctx.sessionManager.getSessionId(), markerEntryType: PASSIVE_STOP_ENTRY_TYPE,
253
249
  defaults: { mode: isNewSession(reason, branch) ? config.mode : config.inactiveMode, scopes: config.scopes },
254
250
  inactiveMode: config.inactiveMode, fork: reason === "fork" });
255
- if (memoryRequired) assertNativeMemoryScopes(policy.scopes);
251
+ if (memoryRequired) captureScopeSelection(policy.scopes);
256
252
  return policy;
257
253
  }
258
254
 
@@ -577,7 +573,7 @@ export default function stateFlowExtension(pi: ExtensionAPI, options: StateFlowE
577
573
  // Freeze admitted policy before accepting any selected memory.
578
574
  // Policy-only capture grants no acquisition or semantic-boundary authority.
579
575
  if (nativePolicy.requiresCapture) pi.appendEntry(PASSIVE_STOP_ENTRY_TYPE, nativePolicy.capture);
580
- if (nativePolicy.mode !== "off") assertNativeMemoryScopes(nativePolicy.scopes);
576
+ if (nativePolicy.mode !== "off") captureScopeSelection(nativePolicy.scopes);
581
577
  } catch (error) {
582
578
  runtime = undefined;
583
579
  branchStartsWithoutRuntime = false;
@@ -1245,7 +1241,7 @@ export default function stateFlowExtension(pi: ExtensionAPI, options: StateFlowE
1245
1241
  return { ok: false, message: active ? "State Flow activation was superseded" : "State Flow mode change was superseded", signal: pending.signal };
1246
1242
  };
1247
1243
  try {
1248
- assertNativeMemoryScopes(wanted);
1244
+ captureScopeSelection(wanted);
1249
1245
  const activation = createRuntime(ctx);
1250
1246
  const deferred = deferredBranch;
1251
1247
  if (deferred) {
@@ -8,7 +8,6 @@ import type { AtomicScopePatches, StateScope } from "./state.ts";
8
8
 
9
9
  import { MODEL_PLANE_NAMES } from "./planes.ts";
10
10
 
11
- const PATCH_PLANES = MODEL_PLANE_NAMES;
12
11
  const SEMANTIC_ROOT = /^(?:intents|strategy|tactics|artifacts|response|lazy|x_[a-z][a-z0-9_]*)(?=\.|\[|$)/;
13
12
  const PATCH_PATH = /^(?:effective|global|cwd|session)\.patches(?:\[\d+\])?$/;
14
13
 
@@ -57,7 +56,7 @@ function admitKeys(value: JsonObject, selected: ScopeSelection, external: readon
57
56
  const keys = Object.keys(value);
58
57
  if (!keys.length) throw new Error("Model patch requires at least one supplied branch");
59
58
  if (selected.length === 1) {
60
- if (keys.some(key => !PATCH_PLANES.includes(key) && !external.includes(key))) throw new Error("Single-owner model patches require flat semantic planes");
59
+ if (keys.some(key => !MODEL_PLANE_NAMES.includes(key) && !external.includes(key))) throw new Error("Single-owner model patches require flat semantic planes");
61
60
  } else for (const key of keys) {
62
61
  if (!selected.includes(key as StateScope)) throw new Error(`Multi-owner model patches require participating explicit owners; does not accept field ${key}`);
63
62
  }
@@ -66,7 +65,7 @@ function admitKeys(value: JsonObject, selected: ScopeSelection, external: readon
66
65
  function planePatch(value: unknown, external: readonly string[]): asserts value is JsonObject {
67
66
  if (!isObject(value) || !Object.keys(value).length) throw new Error("Model scope patch must be a nonempty object");
68
67
  for (const key of Object.keys(value)) {
69
- if (!PATCH_PLANES.includes(key) && !external.includes(key)) throw new Error(`Model patch does not accept semantic plane ${key}`);
68
+ if (!MODEL_PLANE_NAMES.includes(key) && !external.includes(key)) throw new Error(`Model patch does not accept semantic plane ${key}`);
70
69
  if (!isObject(value[key])) throw new Error(`Model patch plane ${key} must be a JSON object`);
71
70
  }
72
71
  }
@@ -40,7 +40,7 @@ export interface StateFlowModuleInput<Input extends JsonValue = JsonValue> {
40
40
  assertCurrent(): void;
41
41
  }
42
42
 
43
- /** Candidate public v1 contract; durable activation requires matching retained metadata. */
43
+ /** Published public v1 contract; retained descriptors govern durable compatibility. */
44
44
  export interface StateFlowModule<Content extends JsonObject = JsonObject, Input extends JsonValue = JsonValue> {
45
45
  readonly immutable: boolean;
46
46
  readonly id: string;
@@ -179,7 +179,6 @@ export function buildStateFlowSectionView(
179
179
  if (index % 2 === 0) inspectionRows.push([]);
180
180
  inspectionRows.at(-1)!.push({ text: STATE_FLOW_SCOPE_LABELS[scope], callback_data: callbackData("inspect", scope) });
181
181
  }
182
- const named = scopes.map(scope => `<code>${scope}</code>`).join(" → ");
183
182
  const modes: StateFlowTelegramButton[] = STATE_FLOW_MODES.map((mode) => ({
184
183
  text: `${mode === snapshot.mode ? STATE_FLOW_SELECTED_MARKERS[mode] : "⚫️"} ${STATE_FLOW_MODE_LABELS[mode]}`,
185
184
  callback_data: callbackData(mode),
@@ -198,15 +197,12 @@ export function buildStateFlowSectionView(
198
197
  `<code>-</code> <code>passive</code>: regular chat with memory tools; available memory from the selected ${scopes.length === 1 ? "scope" : "scopes"} enters the agent's context.`,
199
198
  "<code>-</code> <code>active</code>: same memory access; each completed answer closes a cycle, and the next request starts from saved state, not the full chat.",
200
199
  "",
201
- `<b>Participating scopes:</b> ${named}`,
202
- ...(!scopes.includes("session") ? ["New answers are delivered, not stored: Session is excluded."] : []),
203
- "",
204
200
  "<b>Inspect participating memory</b> — view available stored state even in Off:",
205
201
  "",
206
202
  ...scopes.map(scope => `<code>-</code> <code>${scope}</code>: ${STATE_FLOW_SCOPE_DESCRIPTIONS[scope]}`),
207
203
  ...(scopes.length > 1
208
- ? [`<code>-</code> <code>effective</code>: validated available ${named} overlay; excluded scopes do not contribute.`]
209
- : ["This single scope is also the agent's effective state; no separate overlay is needed."]),
204
+ ? ["<code>-</code> <code>effective</code>: merged state of the selected scopes in order from the general to the specific."]
205
+ : []),
210
206
  ].join("\n"),
211
207
  parseMode: "html",
212
208
  replyMarkup: { inline_keyboard: [