@llblab/pi-kit 0.38.2 → 0.38.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +3 -3
- package/node_modules/@llblab/pi-codex-usage/AGENTS.md +2 -2
- package/node_modules/@llblab/pi-codex-usage/CHANGELOG.md +6 -0
- package/node_modules/@llblab/pi-codex-usage/README.md +9 -5
- package/node_modules/@llblab/pi-codex-usage/lib/query.ts +229 -50
- package/node_modules/@llblab/pi-codex-usage/lib/usage.ts +9 -1
- package/node_modules/@llblab/pi-codex-usage/package.json +1 -1
- package/node_modules/@llblab/pi-state-flow/AGENTS.md +1 -1
- package/node_modules/@llblab/pi-state-flow/BACKLOG.md +11 -673
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +18 -0
- package/node_modules/@llblab/pi-state-flow/README.md +8 -8
- package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +3 -6
- package/node_modules/@llblab/pi-state-flow/dist/lib/model-interface.js +2 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/semantic-module.d.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.js +2 -6
- package/node_modules/@llblab/pi-state-flow/dist/package.json +2 -1
- package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-guide/SKILL.md +5 -5
- package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-memory/SKILL.md +1 -1
- package/node_modules/@llblab/pi-state-flow/docs/README.md +7 -7
- package/node_modules/@llblab/pi-state-flow/docs/architecture.md +11 -15
- package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +12 -10
- package/node_modules/@llblab/pi-state-flow/docs/fork-contract.md +18 -16
- package/node_modules/@llblab/pi-state-flow/docs/lazy-state.md +13 -15
- package/node_modules/@llblab/pi-state-flow/docs/protocol-composition-decision.md +2 -2
- package/node_modules/@llblab/pi-state-flow/docs/public-module-contract.md +16 -6
- package/node_modules/@llblab/pi-state-flow/docs/scope-selection-contract.md +25 -23
- package/node_modules/@llblab/pi-state-flow/docs/semantic-compatibility-decision.md +14 -12
- package/node_modules/@llblab/pi-state-flow/docs/semantic-extensibility-decision.md +2 -2
- package/node_modules/@llblab/pi-state-flow/docs/semantic-handoff-contract.md +133 -15
- package/node_modules/@llblab/pi-state-flow/docs/semantic-memory-evaluation.md +5 -5
- package/node_modules/@llblab/pi-state-flow/docs/semantic-module-contract.md +5 -5
- package/node_modules/@llblab/pi-state-flow/docs/single-scope-interface-contract.md +2 -2
- package/node_modules/@llblab/pi-state-flow/docs/usage.md +33 -23
- package/node_modules/@llblab/pi-state-flow/lib/extension.ts +3 -7
- package/node_modules/@llblab/pi-state-flow/lib/model-interface.ts +2 -3
- package/node_modules/@llblab/pi-state-flow/lib/semantic-module.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/lib/telegram.ts +2 -6
- package/node_modules/@llblab/pi-state-flow/package.json +2 -1
- package/node_modules/@llblab/pi-state-flow/skills/state-flow-guide/SKILL.md +5 -5
- package/node_modules/@llblab/pi-state-flow/skills/state-flow-memory/SKILL.md +1 -1
- package/package.json +3 -3
|
@@ -4,6 +4,24 @@
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.27.4: TypeScript Declaration Hotfix
|
|
8
|
+
|
|
9
|
+
- `Package type discovery`: Adds the top-level `types` entry pointing to `dist/index.d.ts` so TypeScript consumers and tools that do not read conditional exports can discover the built declarations. Existing conditional type exports remain unchanged. The tracked distribution manifest is rebuilt with matching metadata.
|
|
10
|
+
|
|
11
|
+
## 0.27.3: Minimal Telegram inspection menu
|
|
12
|
+
|
|
13
|
+
- `Single participating-owner list`: Removes the duplicated Participating scopes summary and the Session-exclusion notice from the Telegram section. The Inspect participating memory list and its buttons are now the only statement of participating owners, so no line can disagree with the available actions.
|
|
14
|
+
- `Selection-independent Effective line`: Replaces the generated `global → cwd → session` enumeration and its three-owner variant with one fixed sentence about overlay order. A single selected owner shows only that owner, without an Effective line, button or explanatory tail.
|
|
15
|
+
|
|
16
|
+
## 0.27.2: Consistency & Simplification
|
|
17
|
+
|
|
18
|
+
- `Documentation reconciliation`: Correct current release/public-module status to the published 0.27.0/0.27.1 behavior, including metadata v4 retention and external-root tools/context/producers. Distinguish the six-plane internal seam from public registration and mark M4/M5 deferrals as historical without upgrading their review verdicts. No production behavior or compatibility policy changed.
|
|
19
|
+
- `Current work and history`: Replace the completed evolution roadmap with an outstanding-work backlog. Retain the exact five-patch offline-bundle corpus in its semantic contract, keep historical decisions and acceptance evidence traceable, and separate unrun live-model and installed-client gates from consolidation work.
|
|
20
|
+
- `Operator and read contracts`: Reconcile wanted/available/excluded scopes, v2 policy records, v3/v4 storage, Session-excluded completion and deferred native forks. Correct the lazy `keys` example to structural-only metadata and guard it with an executable documentation regression. Replace duplicated architecture checkpoint narratives with existing contract references; clarify synchronous context and cancelable module production.
|
|
21
|
+
- `Implementation simplification`: Remove the obsolete native scope-validation wrapper and a private plane-name alias, reusing existing owners directly. All three validation calls retain their original conditions and positions; public signatures, storage admission, publication and cancellation fences are unchanged. Active/bootstrap/Passive protocol renderings remain byte-identical across all seven selections.
|
|
22
|
+
- `Packaged guidance`: Align Skills with explicit scope-command arguments, wanted-but-unavailable reads, single-owner relative cascade/deletion paths and the existing registered-mutable external-root boundary. Missing or incompatible definitions never permit discarding retained data or bypassing authoring restrictions.
|
|
23
|
+
- `Compatibility`: No configuration, public API semantics or storage format changes. Legacy conversion and retired-root reservations remain supported throughout State Flow 0.x. Existing publication, source-provenance and cancellation guarantees are unchanged; deterministic validation does not establish live-model quality, installed-client compatibility or stronger storage durability.
|
|
24
|
+
|
|
7
25
|
## 0.27.1: Selected Scope Read Diagnostics
|
|
8
26
|
|
|
9
27
|
- `Read availability`: Explicit reads now distinguish a selected owner with no available read view from an excluded owner. In pre-runtime Passive sessions, an unacquired Session no longer incorrectly reports itself excluded. Reads still do not create private memory, widen the selection or return partial multi-path results; normal accepted writes retain their acquisition rules.
|
|
@@ -88,7 +88,7 @@ New sessions default to **Off**. Choose Passive for ordinary conversation with m
|
|
|
88
88
|
- Choosing Passive or Active later acquires memory.
|
|
89
89
|
- Stored memory and Pi's native trace stay intact.
|
|
90
90
|
|
|
91
|
-
Modes select agent behavior;
|
|
91
|
+
Modes select agent behavior, not different storage algorithms. Off defers memory acquisition; selected-scope policy independently determines whether a fork may copy private Session memory. Final consolidation needs no empty ceremonial patch, and context projection does not delete native history. See [mode semantics and bootstrap terminology](docs/usage.md#active-passive-and-configured-off).
|
|
92
92
|
|
|
93
93
|
## State model
|
|
94
94
|
|
|
@@ -100,7 +100,7 @@ Memory has three ownership scopes:
|
|
|
100
100
|
- `cwd`: Knowledge shared by sessions in the same working directory.
|
|
101
101
|
- `session`: State belonging to the current session and its selected branch.
|
|
102
102
|
|
|
103
|
-
Participation is configured with a nonempty `scopes` array in [global configuration](docs/usage.md#configuration); omission selects all three. Each native branch captures that choice once, and forks inherit it. All seven nonempty selections use the same runtime. The existing mode commands accept optional whitespace-separated owners, for example `/state-flow-active session`, `/state-flow-passive cwd global`, or `/state-flow-off cwd`. Blank/mode-only commands and Telegram controls preserve the captured choice. Duplicate/unknown tokens reject before changing policy; Off records a new choice without canonical memory I/O. No settings chooser is required. Excluded owners receive no automatic memory contribution or semantic writes; new answers are stored only when Active and Session participates. Mode-only Telegram buttons retain that choice; explicit operator inspection is separate from model participation. See the [functional boundary and legacy proof dependencies](docs/scope-selection-contract.md#m2-functional-acceptance-boundary).
|
|
103
|
+
Participation is configured with a nonempty `scopes` array in [global configuration](docs/usage.md#configuration); omission selects all three. Wanted means selected by captured policy, available means a validated read view exists, and excluded means outside that policy; [usage](docs/usage.md#lifecycle-operations) owns the distinctions and the `selected, unavailable` read diagnostic. Selection never moves data between owners. Each native branch captures that choice once, and forks inherit it. All seven nonempty selections use the same runtime. The existing mode commands accept optional whitespace-separated owners, for example `/state-flow-active session`, `/state-flow-passive cwd global`, or `/state-flow-off cwd`. Blank/mode-only commands and Telegram controls preserve the captured choice. Duplicate/unknown tokens reject before changing policy; Off records a new choice without canonical memory I/O. No settings chooser is required. Excluded owners receive no automatic memory contribution or semantic writes; new answers are stored only when Active and Session participates. Mode-only Telegram buttons retain that choice; explicit operator inspection is separate from model participation. See the [functional boundary and legacy proof dependencies](docs/scope-selection-contract.md#m2-functional-acceptance-boundary).
|
|
104
104
|
|
|
105
105
|
Participating owners compose recursively in **global → CWD → session** order:
|
|
106
106
|
|
|
@@ -125,8 +125,8 @@ Runtime views provide these documented planes:
|
|
|
125
125
|
Every plane is optional on disk:
|
|
126
126
|
|
|
127
127
|
- Stored checkpoints and patches may omit any documented plane, including `intents`, `lazy` or `response`.
|
|
128
|
-
- Current and historical views assemble
|
|
129
|
-
-
|
|
128
|
+
- Current and historical views assemble present built-in fields and metadata v4-declared external roots from the selected scopes; absent fields are not filled in. Empty `response` counts as absent.
|
|
129
|
+
- Declared external roots and retained history survive missing or incompatible definitions under the [public module contract](docs/public-module-contract.md). Unrelated unknown roots are not supported semantic fields. Retired `contract`/`working` roots explicitly reject in the target format; nested ordinary keys remain unrestricted.
|
|
130
130
|
- Reading or starting never rewrites data just to normalize it, and a missing field is not a storage-format error.
|
|
131
131
|
|
|
132
132
|
These planes organize ordinary JSON; there is no project-specific schema. The model updates every plane except `response`, which is runtime-owned.
|
|
@@ -220,8 +220,8 @@ The default store is `~/.pi/agent/state-flow/`, independent of registered source
|
|
|
220
220
|
**Resume, tree navigation and forks:**
|
|
221
221
|
|
|
222
222
|
- **State Flow does not depend on the Pi step.** Memory is the current JSON state of each scope and changes only through accepted `patch_state` calls and run lifecycle. Resume and tree navigation restore the branch's mode, never an older memory revision; Off defers acquisition. Past values stay readable through `read_state` offsets within retained history.
|
|
223
|
-
- A new session gets its own
|
|
224
|
-
- Supported native forks copy
|
|
223
|
+
- A new session gets its own private layer only when Session acquisition is admitted; shared-only selections create no hidden private semantics.
|
|
224
|
+
- Supported native forks inherit captured policy and copy parent-**current** Session memory into a fresh child owner when admitted, without changing parent-private data. Off or Session-excluded forks defer private acquisition; an acquired child never recopies.
|
|
225
225
|
- Explicit Active or Passive accepts the validated current memory of that same session; modes stay stable.
|
|
226
226
|
- Missing, malformed or contradictory current files, unsafe fork copying and concurrent writes remain fenced and are never replaced by empty or foreign memory.
|
|
227
227
|
|
|
@@ -239,7 +239,7 @@ How mode changes interact with storage:
|
|
|
239
239
|
- Explicit Off inspection may read current stored values through a disposable validated reader. It does not activate memory, install cache or change pending fork acquisition. Missing private authority stays unavailable.
|
|
240
240
|
- Active waits for a coherent capture and acceptance; another mode or selection can withdraw its wait.
|
|
241
241
|
|
|
242
|
-
|
|
242
|
+
Core-only scope metadata v3 and external-module metadata v4 use `strategy` and `tactics`; v4 also retains declared external objects/descriptors independently of definition lifetimes. Supported v1/v2 cohorts read through declared translation; owned acceptance may convert supported formats only after a verified exact-byte backup outside canonical authority. Upgrade/quiesce all writers first; unsupported layouts are not repaired. See the [format and backup boundary](docs/usage.md#moving-a-store-and-supported-formats) before upgrading or moving a store.
|
|
243
243
|
|
|
244
244
|
## Operational boundaries
|
|
245
245
|
|
|
@@ -258,7 +258,7 @@ Treat state, diagnostic logs and backups as private data. Revalidate consequenti
|
|
|
258
258
|
- [Acceptance map](docs/temporal-acceptance.md) — Properties tied to concrete tests.
|
|
259
259
|
- [Documentation index](docs/README.md) — All maintained guides.
|
|
260
260
|
|
|
261
|
-
The six built-in planes use an [internal semantic-module contract](docs/semantic-module-contract.md) for authoring policy
|
|
261
|
+
The six built-in planes use an [internal semantic-module contract](docs/semantic-module-contract.md) for authoring policy, mode-aware context and isolated producer evaluation. Since 0.27.0, the published [`@llblab/pi-state-flow/modules` entry](docs/public-module-contract.md) also supports trusted companion-extension registration, retained metadata v4 external roots, existing read/patch tools, Active/Passive context and atomic Active producer replacements. Pi remains the loader; callbacks are trusted JavaScript, not sandboxed plugins or autonomous background reasoning. The public contract owns registration, retention and currentness requirements; [compatibility](docs/compatibility.md) separates deterministic integration evidence from installed-client and live-model claims.
|
|
262
262
|
|
|
263
263
|
For development, run `npm install` and `npm run validate`. `npm run benchmark` is opt-in and separate from the normal suite; see `benchmarks/README.md` in a source checkout.
|
|
264
264
|
|
|
@@ -171,16 +171,13 @@ export default function stateFlowExtension(pi, options = {}) {
|
|
|
171
171
|
pi.appendEntry(PASSIVE_STOP_ENTRY_TYPE, captureSelectedNativeMarker({ version: 2,
|
|
172
172
|
owner: ctx.sessionManager.getSessionId(), mode: snapshot.config.mode, scopes: nativeScopeSelection(ctx), ...value }));
|
|
173
173
|
}
|
|
174
|
-
function assertNativeMemoryScopes(scopes) {
|
|
175
|
-
captureScopeSelection(scopes);
|
|
176
|
-
}
|
|
177
174
|
function branchPolicy(ctx, reason, memoryRequired = true) {
|
|
178
175
|
const branch = ctx.sessionManager.getBranch();
|
|
179
176
|
const policy = prepareSelectedBranchPolicy(branch, { owner: ctx.sessionManager.getSessionId(), markerEntryType: PASSIVE_STOP_ENTRY_TYPE,
|
|
180
177
|
defaults: { mode: isNewSession(reason, branch) ? config.mode : config.inactiveMode, scopes: config.scopes },
|
|
181
178
|
inactiveMode: config.inactiveMode, fork: reason === "fork" });
|
|
182
179
|
if (memoryRequired)
|
|
183
|
-
|
|
180
|
+
captureScopeSelection(policy.scopes);
|
|
184
181
|
return policy;
|
|
185
182
|
}
|
|
186
183
|
/** Failure-only denial evidence, never policy admission: inspect own known-epoch headers without getters or memory I/O. */
|
|
@@ -525,7 +522,7 @@ export default function stateFlowExtension(pi, options = {}) {
|
|
|
525
522
|
if (nativePolicy.requiresCapture)
|
|
526
523
|
pi.appendEntry(PASSIVE_STOP_ENTRY_TYPE, nativePolicy.capture);
|
|
527
524
|
if (nativePolicy.mode !== "off")
|
|
528
|
-
|
|
525
|
+
captureScopeSelection(nativePolicy.scopes);
|
|
529
526
|
}
|
|
530
527
|
catch (error) {
|
|
531
528
|
runtime = undefined;
|
|
@@ -1285,7 +1282,7 @@ export default function stateFlowExtension(pi, options = {}) {
|
|
|
1285
1282
|
return { ok: false, message: active ? "State Flow activation was superseded" : "State Flow mode change was superseded", signal: pending.signal };
|
|
1286
1283
|
};
|
|
1287
1284
|
try {
|
|
1288
|
-
|
|
1285
|
+
captureScopeSelection(wanted);
|
|
1289
1286
|
const activation = createRuntime(ctx);
|
|
1290
1287
|
const deferred = deferredBranch;
|
|
1291
1288
|
if (deferred) {
|
|
@@ -5,7 +5,6 @@ import { DEFAULT_HISTORY_LIMIT } from "./history.js";
|
|
|
5
5
|
import { parseStateReadPath, parseValuePath } from "./query.js";
|
|
6
6
|
import { captureScopeSelection } from "./selection.js";
|
|
7
7
|
import { MODEL_PLANE_NAMES } from "./planes.js";
|
|
8
|
-
const PATCH_PLANES = MODEL_PLANE_NAMES;
|
|
9
8
|
const SEMANTIC_ROOT = /^(?:intents|strategy|tactics|artifacts|response|lazy|x_[a-z][a-z0-9_]*)(?=\.|\[|$)/;
|
|
10
9
|
const PATCH_PATH = /^(?:effective|global|cwd|session)\.patches(?:\[\d+\])?$/;
|
|
11
10
|
function dense(value) {
|
|
@@ -66,7 +65,7 @@ function admitKeys(value, selected, external) {
|
|
|
66
65
|
if (!keys.length)
|
|
67
66
|
throw new Error("Model patch requires at least one supplied branch");
|
|
68
67
|
if (selected.length === 1) {
|
|
69
|
-
if (keys.some(key => !
|
|
68
|
+
if (keys.some(key => !MODEL_PLANE_NAMES.includes(key) && !external.includes(key)))
|
|
70
69
|
throw new Error("Single-owner model patches require flat semantic planes");
|
|
71
70
|
}
|
|
72
71
|
else
|
|
@@ -79,7 +78,7 @@ function planePatch(value, external) {
|
|
|
79
78
|
if (!isObject(value) || !Object.keys(value).length)
|
|
80
79
|
throw new Error("Model scope patch must be a nonempty object");
|
|
81
80
|
for (const key of Object.keys(value)) {
|
|
82
|
-
if (!
|
|
81
|
+
if (!MODEL_PLANE_NAMES.includes(key) && !external.includes(key))
|
|
83
82
|
throw new Error(`Model patch does not accept semantic plane ${key}`);
|
|
84
83
|
if (!isObject(value[key]))
|
|
85
84
|
throw new Error(`Model patch plane ${key} must be a JSON object`);
|
|
@@ -35,7 +35,7 @@ export interface StateFlowModuleInput<Input extends JsonValue = JsonValue> {
|
|
|
35
35
|
/** Verify only the captured source; throw if obsolete. No acquisition or async work. */
|
|
36
36
|
assertCurrent(): void;
|
|
37
37
|
}
|
|
38
|
-
/**
|
|
38
|
+
/** Published public v1 contract; retained descriptors govern durable compatibility. */
|
|
39
39
|
export interface StateFlowModule<Content extends JsonObject = JsonObject, Input extends JsonValue = JsonValue> {
|
|
40
40
|
readonly immutable: boolean;
|
|
41
41
|
readonly id: string;
|
|
@@ -57,7 +57,6 @@ export function buildStateFlowSectionView(snapshot, callbackData) {
|
|
|
57
57
|
inspectionRows.push([]);
|
|
58
58
|
inspectionRows.at(-1).push({ text: STATE_FLOW_SCOPE_LABELS[scope], callback_data: callbackData("inspect", scope) });
|
|
59
59
|
}
|
|
60
|
-
const named = scopes.map(scope => `<code>${scope}</code>`).join(" → ");
|
|
61
60
|
const modes = STATE_FLOW_MODES.map((mode) => ({
|
|
62
61
|
text: `${mode === snapshot.mode ? STATE_FLOW_SELECTED_MARKERS[mode] : "⚫️"} ${STATE_FLOW_MODE_LABELS[mode]}`,
|
|
63
62
|
callback_data: callbackData(mode),
|
|
@@ -76,15 +75,12 @@ export function buildStateFlowSectionView(snapshot, callbackData) {
|
|
|
76
75
|
`<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.`,
|
|
77
76
|
"<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.",
|
|
78
77
|
"",
|
|
79
|
-
`<b>Participating scopes:</b> ${named}`,
|
|
80
|
-
...(!scopes.includes("session") ? ["New answers are delivered, not stored: Session is excluded."] : []),
|
|
81
|
-
"",
|
|
82
78
|
"<b>Inspect participating memory</b> — view available stored state even in Off:",
|
|
83
79
|
"",
|
|
84
80
|
...scopes.map(scope => `<code>-</code> <code>${scope}</code>: ${STATE_FLOW_SCOPE_DESCRIPTIONS[scope]}`),
|
|
85
81
|
...(scopes.length > 1
|
|
86
|
-
? [
|
|
87
|
-
: [
|
|
82
|
+
? ["<code>-</code> <code>effective</code>: merged state of the selected scopes in order from the general to the specific."]
|
|
83
|
+
: []),
|
|
88
84
|
].join("\n"),
|
|
89
85
|
parseMode: "html",
|
|
90
86
|
replyMarkup: { inline_keyboard: [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llblab/pi-state-flow",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Incremental scoped state/context/memory compiler for Pi, inspired by SKILL.state",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"url": "https://github.com/llblab/pi-state-flow/issues"
|
|
19
19
|
},
|
|
20
20
|
"type": "module",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
21
22
|
"files": [
|
|
22
23
|
"index.ts",
|
|
23
24
|
"api",
|
|
@@ -15,7 +15,7 @@ State Flow's on-demand operational reference. Resolve the usage question or iden
|
|
|
15
15
|
|
|
16
16
|
Passive tools access memory without starting an episode. Missing tools or storage are blockers, not permission to enable an episode or bypass storage; explanation alone remains possible.
|
|
17
17
|
|
|
18
|
-
Operator commands: `/state-flow-status` inspects; `/state-flow-active` selects state-driven episodes; `/state-flow-passive` selects ordinary conversation with both memory tools and existing-state projection; `/state-flow-off` removes both tools and all State Flow context, including frozen handoffs, without deleting memory.
|
|
18
|
+
Operator commands: `/state-flow-status` inspects; `/state-flow-active` selects state-driven episodes; `/state-flow-passive` selects ordinary conversation with both memory tools and existing-state projection; `/state-flow-off` removes both tools and all State Flow context, including frozen handoffs, without deleting memory. Mode-only commands and Telegram preserve captured scopes. The existing mode commands also accept optional exact owner arguments to change the current branch's selection; duplicate/unknown owners reject before policy changes and Off remains memory-inert. Global `mode` defaults to Off for new sessions and never overrides retained choices. Do not change mode or scopes without operator authorization.
|
|
19
19
|
|
|
20
20
|
## Map
|
|
21
21
|
|
|
@@ -34,7 +34,7 @@ A proposal is not a commitment. Preserve an accepted plan's phases, dependencies
|
|
|
34
34
|
|
|
35
35
|
## Read
|
|
36
36
|
|
|
37
|
-
Reuse sufficient visible state. The memory head and its recent transitions are frozen at projection start. Apply later `state_updates` only when their `projection` matches the head's `State Flow projection:` ID; older native results remain historical. Effective update paths are key/index arrays whose values replace that path, while `deleted: true` means absence. The optional `cascaded` array lists
|
|
37
|
+
Reuse sufficient visible state. The memory head and its recent transitions are frozen at projection start. Apply later `state_updates` only when their `projection` matches the head's `State Flow projection:` ID; older native results remain historical. Effective update paths are key/index arrays whose values replace that path, while `deleted: true` means absence. The optional `cascaded` array lists paths cleared in the intermediate ownership phase, relative for one WANTED owner and owner-scoped for multiple WANTED owners, even if later authored writes recreate them, including nested lazy keys; it contains no values, is never elided, and does not mean the effective path is absent if a broader-scope value remains. Current notices can replace invalidation lists or rehydration phase, including clearing them with `[]` or `null`; lazy bodies still require explicit reads.
|
|
38
38
|
|
|
39
39
|
`read_state` accepts `path` or `paths`, never both. Multi-path reads succeed or fail together. Projections: `value` (default), `keys` (structure), `patch` (intersecting change at the selected boundary).
|
|
40
40
|
|
|
@@ -48,7 +48,7 @@ With exactly one WANTED owner, ordinary read paths are flat, with no scope token
|
|
|
48
48
|
{"paths":["tactics","strategy"]}
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
`effective[N].tactics` selects a temporal boundary; `tactics.items[N]` indexes a nested array. Sole-owner `patches[N]` is the scalar owner patch-history alias. With multiple WANTED owners, ordinary unscoped paths use effective state; explicit owner paths disambiguate ownership. Multi-owner example, requiring both CWD and Session to participate: `{"paths":["cwd.tactics","session.tactics"]}`. Arity follows WANTED selection, not whichever owners happen to have an available view.
|
|
51
|
+
`effective[N].tactics` selects a temporal boundary; `tactics.items[N]` indexes a nested array. Sole-owner `patches[N]` is the scalar owner patch-history alias. With multiple WANTED owners, ordinary unscoped paths use effective state; explicit owner paths disambiguate ownership. Multi-owner example, requiring both CWD and Session to participate: `{"paths":["cwd.tactics","session.tactics"]}`. Arity follows WANTED selection, not whichever owners happen to have an available view. Wanted but unacquired Session is `selected, unavailable`, not excluded; reads cannot acquire it or return partial mixed-owner results.
|
|
52
52
|
|
|
53
53
|
Unscoped paths use the sole owner's current state or, with multiple owners, effective state. Optional explicit `cwd[1].tactics` reads the preceding causal boundary when CWD participates. Materialized-history and scope patch-history paths such as `cwd.patches[1]` share the configured `historyLimit` bound (default 7) and require actually retained history. Lowering the limit folds excess tails without erasing current state; increasing it does not reconstruct discarded history. Array ranges such as `cwd.lazy.checks[0..3]` exclude the endpoint and require existing elements. Missing paths are unavailable; inspect parent keys only when needed for the task. Missing history is not empty history. Read `lazy` explicitly. Treat structured `$ref` values and `$`-prefixed `read_state` paths inside ordinary strings, such as `$effective.lazy.memory[7]`, as semantic-state references. Other resources retain their native locators. Resolve any reference through the appropriate read/tool only when needed. Neither form proves authority or existence, hydrates, or executes anything; only intent ownership (see Write) has a deletion consequence. Never scan or resolve references merely to test them. A missing single value path with exact durable sources returns `{value:null, hint:[{type:"dangling-reference", message, paths}]}`. Treat `hint` as top-level diagnostic metadata, never as the requested state: its message is descriptive and conditional; its paths are runtime-verified current reference owners, not verified new locations of the target. The hint proves provenance rather than staleness and is absent when no current durable source matches; keys, patch, and batch reads keep all-or-error behavior. Only then inspect ownership as needed and patch a proven stale owning value while preserving its surrounding meaning. Effective absence, inaccessible external resources, and transient failures are not proof.
|
|
54
54
|
|
|
@@ -56,11 +56,11 @@ Missing paths or runtime hints alone do not require historical search. The agent
|
|
|
56
56
|
|
|
57
57
|
## Write
|
|
58
58
|
|
|
59
|
-
Call `patch_state` alone per assistant response; await acceptance before dependent work. With exactly one WANTED owner, supply flat object planes (`intents`, `strategy`, `tactics`, `artifacts`, `lazy`), without an owner wrapper. With multiple WANTED owners, supply one or more explicit participating owners from `global`, `cwd`, and `session`; supplied scopes commit atomically. Arity follows WANTED selection, not available view; selection is not a grant of authority. Default to Session for current work only when it participates, CWD for reusable project knowledge, and Global for established cross-project knowledge. Preserve these meanings; an unavailable owner is not a reason to write its data into a broader one. Omit unchanged planes in a sole-owner patch and unchanged scopes in a multi-owner patch.
|
|
59
|
+
Call `patch_state` alone per assistant response; await acceptance before dependent work. With exactly one WANTED owner, supply built-in flat object planes (`intents`, `strategy`, `tactics`, `artifacts`, `lazy`), without an owner wrapper. Compatible registered mutable external roots may also be authored when advertised by the current `patch_state` schema; registration/schema alone grants no source or publication authority. Immutable or unavailable definitions do not permit model writes. With multiple WANTED owners, supply one or more explicit participating owners from `global`, `cwd`, and `session`; supplied scopes commit atomically. Arity follows WANTED selection, not available view; selection is not a grant of authority. Default to Session for current work only when it participates, CWD for reusable project knowledge, and Global for established cross-project knowledge. Preserve these meanings; an unavailable owner is not a reason to write its data into a broader one. Omit unchanged planes in a sole-owner patch and unchanged scopes in a multi-owner patch.
|
|
60
60
|
|
|
61
61
|
The runtime waits cancelably for publication ownership, then applies authored Global/CWD operations to current canonical values. Untouched fields survive; overlapping targets follow successful acceptance order. Correct repeats succeed as `State already current.` without another semantic revision. Do not repeat external actions during a memory wait, or rebuild an entire scope from an older snapshot. Session ownership/history fences remain private, not a universal merge.
|
|
62
62
|
|
|
63
|
-
When present, semantic planes `intents`, `strategy`, `tactics`, `artifacts`, and `lazy` are objects; nested lazy values may contain ordinary JSON without stored nulls. Stored checkpoints and patches may omit any documented plane. Current and historical views assemble only known fields present in the selected scopes. Absent fields and empty responses are omitted from views.
|
|
63
|
+
When present, semantic planes `intents`, `strategy`, `tactics`, `artifacts`, and `lazy` are objects; nested lazy values may contain ordinary JSON without stored nulls. Stored checkpoints and patches may omit any documented plane. Current and historical views assemble only known fields present in the selected scopes. Absent fields and empty responses are omitted from views. Known content includes metadata-declared external roots; missing or incompatible definitions never authorize discarding that retained data. Only the current admitted authoring grammar is writable. Nested data within known planes remains intact. Explicit value reads of an absent documented top-level field return `null`. Authored `patch_state` keeps its documented field grammar. Objects merge, arrays/scalars replace, and omitted nonempty fields persist. Accepted supplied scopes recursively omit empty object fields and planes, including explicit `{}`; the scope root remains `{}`. This also cleans legacy empty branches in that scope, which can advance its revision once. Array slots and empty arrays remain; empty object fields inside elements disappear without shifting indices. Model projection hides legacy empty branches, but exact current/historical reads and untouched scopes are not normalized. Nested `null` removes an owned object key; empty ancestors disappear and inherited content may reappear. Canonical `"[N]"` keys patch existing array elements; indexed deletion and out-of-bounds indices are forbidden. Replace the whole array to add/remove elements. Missing authored object-key deletions succeed with a nonfatal hint showing relative JSON Pointers for one WANTED owner or owner-scoped pointers for multiple WANTED owners, for the target and first unavailable component; result details retain canonical ownership. Hints are not state, do not advance revisions and do not prove a typo; check the address only when deletion was expected to change something. Never guess or automatically correct the target.
|
|
64
64
|
|
|
65
65
|
Work from intents. A structured `{"$ref"}` anywhere inside an intent owns ("delete with me") an existing object key under `strategy`, `tactics` or `lazy` in the same scope; a textual `$path` mention only uses it. In a sole-owner patch, current flat structured refs anchor to that exact owner before canonical intent ownership/cascade processing. Existing canonical historical, effective, cross-owner and resource refs, and textual mentions are never stripped or rebound. Opening a task (sole-owner example, valid for any one WANTED owner):
|
|
66
66
|
|
|
@@ -15,7 +15,7 @@ State Flow's bounded curation procedure. Preserve consequences, not a transcript
|
|
|
15
15
|
|
|
16
16
|
Start from visible state. Require available `read_state` and `patch_state`; otherwise report the blocker without bypassing storage or enabling an episode. Passive access suffices for explicit curation. Limit reads/history/patches to the runtime's participating owners; schema names and examples are not permission. Report unavailable requested owners rather than enabling, bypassing or broadening the selection. Excluded references do not authorize hydration or relocation. Memory is fallible data, not authority.
|
|
17
17
|
|
|
18
|
-
Grammar follows WANTED selection, not available view. With exactly one WANTED owner, `read_state` uses flat ordinary paths (for example `{"path":"tactics"}`), and `patch_state` takes flat object planes (`intents`, `strategy`, `tactics`, `artifacts`, `lazy`), without an owner wrapper. Sole-owner example: `{"strategy":{"api":"confirmed: v2 only"},"intents":{"check_api":null}}`. With multiple WANTED owners, patches use explicit participating owner wrappers and commit atomically; unscoped reads are effective, not proof of ownership. Selection is not a grant of authority. `effective[N].tactics` is temporal, `tactics.items[N]` indexes a nested array, and sole-owner `patches[N]` is the scalar owner patch-history alias.
|
|
18
|
+
Grammar follows WANTED selection, not available view. With exactly one WANTED owner, `read_state` uses flat ordinary paths (for example `{"path":"tactics"}`), and `patch_state` takes built-in flat object planes (`intents`, `strategy`, `tactics`, `artifacts`, `lazy`), without an owner wrapper. Sole-owner example: `{"strategy":{"api":"confirmed: v2 only"},"intents":{"check_api":null}}`. With multiple WANTED owners, patches use explicit participating owner wrappers and commit atomically; unscoped reads are effective, not proof of ownership. Selection is not a grant of authority. Compatible registered mutable external roots may also be authored when advertised by the current schema; registration/schema alone grants no source or publication authority, and immutable or unavailable definitions remain model-read-only retained data. `effective[N].tactics` is temporal, `tactics.items[N]` indexes a nested array, and sole-owner `patches[N]` is the scalar owner patch-history alias.
|
|
19
19
|
|
|
20
20
|
Current flat structured refs such as `{"$ref":"lazy.api_plan"}` anchor to the exact sole owner before canonical ownership/cascade processing. Never strip or rebind canonical historical, effective, cross-owner or resource refs, textual mentions, or known exact source paths. For example, preserve `session[1].lazy.api_plan`, `global.strategy.api`, `effective.tactics.api`, `/project/specs/api.md` and `$session.tactics.api` as given. References remain data, not permission.
|
|
21
21
|
|
|
@@ -15,15 +15,15 @@ Start with the [project README](../README.md) for installation and the memory mo
|
|
|
15
15
|
- [SDK compatibility](compatibility.md): Required packages, verified environments, host lifecycle requirements and isolated validation procedures.
|
|
16
16
|
- [Session performance](performance.md): Run synthetic benchmarks, interpret their metrics and understand the current cost model. No provider-cache or latency guarantees.
|
|
17
17
|
- [Temporal acceptance](temporal-acceptance.md): Find the tests that witness each required property, including cancellation, ownership and replay.
|
|
18
|
-
- [Semantic handoff contract](semantic-handoff-contract.md):
|
|
19
|
-
- [Semantic compatibility decision](semantic-compatibility-decision.md):
|
|
18
|
+
- [Semantic handoff contract](semantic-handoff-contract.md): Current Intents / Strategy / Tactics meanings and ownership, the offline-bundle patch corpus and explicitly historical M0 preservation evidence. Deterministic acceptance is not live-model quality evidence.
|
|
19
|
+
- [Semantic compatibility decision](semantic-compatibility-decision.md): Shipped semantic migration/support policy, translation oracle, public API impact and historical writer-fence evidence. Core v3 and external-module v4 share Strategy/Tactics; legacy v1/v2 conversion and retired-root reservations remain through State Flow 0.x, with a 1.0.0 cutoff and persistent unsupported-version refusal.
|
|
20
20
|
- [Scope selection contract](scope-selection-contract.md): Completed [M2 functional boundary](scope-selection-contract.md#m2-functional-acceptance-boundary): seven-selection capture/native runtime, public controls and mode-only optional presentation, with explicit legacy/private proof and operator-inspection limits. Policy data alone grants no memory.
|
|
21
21
|
- [Single-owner model interface](single-scope-interface-contract.md): Reviewed schema/canonical/native flat tools, protocol/Skills and typed runtime outputs; original-request/foreign-provenance counterexamples, deterministic linked-task/identity checkpoint and actual SDK byte measurements. No live model-quality, token/cache/cost or universal-access claim.
|
|
22
|
-
- [Public semantic modules](public-module-contract.md):
|
|
23
|
-
- [Internal semantic modules](semantic-module-contract.md):
|
|
24
|
-
- [Protocol composition decision](protocol-composition-decision.md): Historical accepted M4 retain/defer decision
|
|
25
|
-
- [Semantic extensibility decision](semantic-extensibility-decision.md): Historical accepted M5 no-new-API
|
|
26
|
-
- [Semantic memory evaluation](semantic-memory-evaluation.md): Fixed linked-task trial, controlled fixture, independent rubric, isolation/measurement contract
|
|
22
|
+
- [Public semantic modules](public-module-contract.md): Published `./modules` API since 0.27.0: native-host registration, trusted callbacks, metadata v4 retention, external-root tools, Active/Passive context and atomic Active producers. Owns public integration and currentness boundaries, not dynamic loading or sandboxing.
|
|
23
|
+
- [Internal semantic modules](semantic-module-contract.md): Five-member package-owned contract, six built-in bindings, main-agent immutability and detached context/producer evaluation. Public registration uses the same evaluators under the separate public host contract.
|
|
24
|
+
- [Protocol composition decision](protocol-composition-decision.md): Historical accepted M4 retain/defer decision, producer/trust ownership and original review evidence. Later internal/public module work superseded only its bounded no-extraction disposition.
|
|
25
|
+
- [Semantic extensibility decision](semantic-extensibility-decision.md): Historical accepted M5 no-new-API decision and atomic-validation countercase. Later explicitly authorized internal/public module work shipped in 0.27.0; no dynamic loader, sandbox, production archive or quality claim follows.
|
|
26
|
+
- [Semantic memory evaluation](semantic-memory-evaluation.md): Fixed linked-task trial, controlled fixture, independent rubric, isolation/measurement contract and historical credential-safe preflight. Functional implementation has shipped; live-model comparison remains separately authorization-gated and unrun.
|
|
27
27
|
|
|
28
28
|
## Development policy
|
|
29
29
|
|
|
@@ -15,9 +15,11 @@ The extension owns durable memory while enabled. The native bridge admits all se
|
|
|
15
15
|
- `selection`: pure immutable nonempty owner selections and command-token parsing. Value capture grants no mode, lifecycle authority, I/O or storage participation by itself; see the [selection boundary](scope-selection-contract.md#internal-value-boundary-and-lifecycle-encoding-direction).
|
|
16
16
|
- `temporal`, `history`: causal boundaries, checkpoint/tail folding and hot history. Internal [selected temporal algebra](scope-selection-contract.md#selected-temporal-value-algebra) retains only participating streams and metadata-only excluded-step witnesses; algebra alone grants no native storage/runtime admission.
|
|
17
17
|
- `migration`: temporary pure legacy-to-target conversion, root-name guards, reference translation and serialized preflight. `durable` consumes it before known-field filtering; `storage` alone owns backup and guarded conversion publication. It does not own I/O or lifecycle; see the [migration boundary](semantic-compatibility-decision.md#serialized-owner-cohort-preflight).
|
|
18
|
-
- `durable`, `storage`, `git`:
|
|
19
|
-
- `snapshot`, `session`, `runtime`, `recovery`, `episode`:
|
|
18
|
+
- `durable`, `storage`, `git`: canonical codecs and identity, exact file-cohort CAS/exclusion/guarded rollback, and optional settled-turn backup (`SettledTurnBackup`). Selected admission separates semantic bodies from required private/layout evidence; origin/current/fork publication remains explicitly authorized. The [scope contract](scope-selection-contract.md#m2-functional-acceptance-boundary) owns selected/private proof and its historical implementation checkpoints; the storage and backup sections below own transaction/durability limits.
|
|
19
|
+
- `snapshot`, `session`, `runtime`, `recovery`, `episode`: branch/run lifecycle, captured v2 policy, revocable native request receipts and accepted/read-only runtime views. Policy candidates and observation grant no private acquisition or publication. The same selection lifetime binds requests, context, tools and answers across all seven choices; current-memory attachment, private deferral and legacy dependencies follow the [scope contract](scope-selection-contract.md).
|
|
20
20
|
- `transition`, `ownership`, `context`: inference barriers, turn resolution, intent-ownership cascades, passive projection, and response reconciliation. Internal [selected semantic staging/commit](scope-selection-contract.md#selected-semantic-staging-and-commit) reuses the same engine without disabled owners; native response/policy composition uses the same seven-selection bridge. Session-excluded completion finalizes lifecycle without a semantic response transition or hidden private owner.
|
|
21
|
+
- `semantic-module`, `planes`: detached internal context/producer evaluation and the six static built-in bindings; see the [internal contract](semantic-module-contract.md). They do not publish or acquire memory.
|
|
22
|
+
- `module-registry`: revocable native-host registration/catalog lifetimes for the published `./modules` entry. The [public contract](public-module-contract.md) owns trusted callback admission, retained external identities and runtime currentness; a catalog is not publication authority.
|
|
21
23
|
- `query`: current/historical value projection and shared semantic-locator syntax; parsing alone resolves no target and confers no authority.
|
|
22
24
|
- `model-interface`: Detached flat/canonical locator/ref and typed target/pointer presentation, consuming existing query/selection/JSON contracts, never storage/native authority. Actual native sole-flat/multi-explicit read/patch callers use it after original M2 admission. Arity-only schema refresh and fresh SDK definitions preserve old wrapper identity; the [deterministic functional interface](single-scope-interface-contract.md#deterministic-m3-checkpoint) is accepted, not live-model quality.
|
|
23
25
|
- `compaction`: completed-history compaction planning and per-request marker state (`StateFlowCompactionRequests`).
|
|
@@ -26,13 +28,13 @@ The extension owns durable memory while enabled. The native bridge admits all se
|
|
|
26
28
|
- `memory`: memory-bearing scope diagnostics; explicit selection returns only present selected flags while the legacy no-selection signature retains all-three behavior.
|
|
27
29
|
- `continuation`: native-header discovery, runtime-provenance inspection, deterministic recommendation, and host startup precedence.
|
|
28
30
|
- `protocol`, `logging`: Model/tool presentation and bounded diagnostic persistence. Existing trusted plain renderers/private snippets and their context/extension trust boundaries are evaluated in the [protocol composition decision](protocol-composition-decision.md), without moving semantic execution into prompt hooks.
|
|
29
|
-
- `status`, `telegram`, `extension`: operator projection,
|
|
31
|
+
- `status`, `telegram`, `extension`: observational operator projection, optional fail-open Telegram presentation and native lifecycle composition. Status distinguishes wanted policy from available owners/revisions without fabricated values or acquisition; Telegram mode controls preserve scopes and inspection follows wanted targets. [Usage](usage.md#status-and-controls) owns operator behavior; the [scope acceptance map](scope-selection-contract.md#m2-functional-acceptance-boundary) records proof limits.
|
|
30
32
|
|
|
31
33
|
Test placement is checked in both directions by `tests/invariants.test.ts`: LIB modules have same-named mirrors, and every suite has an exact production owner or a reasoned cross-domain exception. The benchmark suites mirror `benchmarks/benchmark.ts` and `benchmarks/benchmark-session.ts` rather than being exceptions. The four exception reasons live in the invariant itself. Shared fixture modules may set up, read and assert, but cannot be hidden suites: the source-hygiene check erases TypeScript types before checking literal test-runner/suite dependencies and direct registration forms. This is not an arbitrary-code sandbox or a proof of semantic case ownership; independent organization review remains necessary.
|
|
32
34
|
|
|
33
35
|
## Semantic state
|
|
34
36
|
|
|
35
|
-
Runtime views select these
|
|
37
|
+
Runtime views select these built-in semantic planes when present, plus metadata v4-declared external object roots under the [public contract](public-module-contract.md). Stored scope objects may omit any plane; unrelated undeclared roots are not supported semantic fields:
|
|
36
38
|
|
|
37
39
|
```json
|
|
38
40
|
{
|
|
@@ -45,7 +47,7 @@ Runtime views select these documented semantic planes when present. Stored scope
|
|
|
45
47
|
}
|
|
46
48
|
```
|
|
47
49
|
|
|
48
|
-
- `intents` is the queue of chosen actions, not a planner, scheduler, task manager or execution loop. An intent may own same-scope `tactics`/`lazy` keys by structured reference; see [model tools](#model-tools).
|
|
50
|
+
- `intents` is the queue of chosen actions, not a planner, scheduler, task manager or execution loop. An intent may own same-scope `strategy`/`tactics`/`lazy` object keys by structured reference; see [model tools](#model-tools).
|
|
49
51
|
- `strategy` retains binding requirements, accepted approaches/plans, decisions, interfaces and rejected alternatives. Proposals remain distinguishable from commitments; operational contradiction does not silently cancel a binding requirement.
|
|
50
52
|
- `tactics` is the temporary working context of those actions: verified current facts, results and uncertainties.
|
|
51
53
|
- `artifacts` maps exact source paths to compiled routing metadata.
|
|
@@ -65,7 +67,7 @@ Later scopes win. A scope-local `null` deletion removes only that scope's key an
|
|
|
65
67
|
|
|
66
68
|
**Sparse state.** Missing planes are valid sparse semantics, not incomplete storage.
|
|
67
69
|
|
|
68
|
-
- Checkpoint/tail codecs admit declared versions before interpreting fields.
|
|
70
|
+
- Checkpoint/tail codecs admit declared versions before interpreting fields. The [migration contract](semantic-compatibility-decision.md) owns v1/v2 translation, v3/v4 admission, raw collision refusal, retired-root support timing and backed-up owned conversion. The [public module contract](public-module-contract.md) owns metadata v4 descriptors and opaque retention through missing definitions, unrelated writes, folding and forks. Retention and callback activation are distinct responsibilities; both shipped in 0.27.0.
|
|
69
71
|
- Retained record identities and positions survive even when filtering leaves an empty patch.
|
|
70
72
|
- `readTemporalView` selects present known fields at the requested boundary, then overlays scopes without inventing fields.
|
|
71
73
|
- Empty and absent responses mean the same for Active projection; clearing a nonempty response projects as a deletion. Passive omits the plane regardless of its value.
|
|
@@ -382,7 +384,7 @@ meta.json
|
|
|
382
384
|
- Predecessor combined session metadata is unsupported; session `meta.json`, `config.json` and `runtime.json` must already satisfy their canonical ownership contracts.
|
|
383
385
|
- Metadata writers replace only their owned leaves and preserve JSON-safe unknown siblings.
|
|
384
386
|
- A scope without a revision counter initializes it from the still-retained semantic tail and persists that baseline on its next owned write; folded ancestry is not guessed.
|
|
385
|
-
- Scope metadata v3 declares Strategy/Tactics;
|
|
387
|
+
- Scope metadata v3 declares Strategy/Tactics; implemented v4 additionally carries retained module descriptors, including unavailable/deleted-content slots. Legacy1/2 and explicit upgrades to4 use the same complete-cohort backup/exclusion/CAS boundary; raw external namespace collisions reject. Core-only streams keep v3 output, while v4 writes cannot drop or alter retained schema/policy descriptors. Representation alone changes no revision or causal identity; runtime-only persistence and inspection never upgrade. Quiesce old writers: version refusal cannot retrofit unsafe deployed callers.
|
|
386
388
|
- Supported flag-based settings and native `{disabled:true}` markers decode read-only. Mixed session `mode`/`enabled` representations are rejected, and no eager migration runs.
|
|
387
389
|
- Revision-pointer checkpoints are unsupported and fail closed without Git restoration.
|
|
388
390
|
|
|
@@ -809,13 +811,7 @@ The pure `readTemporalState(view, offset, scope?)` accessor is exported separate
|
|
|
809
811
|
- An SDK host disposing a standalone `AgentSession` instead should first `await session.extensionRunner.emit({ type: "session_shutdown", reason: "quit" })`. Ordinary Pi lifecycle owners already deliver the event.
|
|
810
812
|
- Without shutdown, the adapter's queued Start, compaction-stop flags and optional presentation disposal are not notified.
|
|
811
813
|
|
|
812
|
-
**Forks.** Native replacement teardown and State Flow adoption are separate responsibilities.
|
|
813
|
-
|
|
814
|
-
- The child has a fresh origin and its own checkpoint, never a UUID alias or a historical shared-state rewind.
|
|
815
|
-
- A child-owned native reset marker fences inherited passive Stop projection across reload.
|
|
816
|
-
- Parent-owned checkpoints selected later cannot fall through to an ordinary-disabled marker and reset child storage.
|
|
817
|
-
|
|
818
|
-
See the [fork contract](fork-contract.md) and [operating limits](usage.md#fork-support-and-limits).
|
|
814
|
+
**Forks.** Native replacement teardown and State Flow adoption are separate responsibilities. The adapter composes selected shared-only deferral or admitted parent-current private copying under the [fork contract](fork-contract.md); Off remains native-only. Captured policy is not source/copy authority, and an acquired child always uses its own current memory rather than recopying a parent or rewinding history. See [operating limits](usage.md#fork-support-and-limits).
|
|
819
815
|
|
|
820
816
|
**Configuration.** Agent configuration is read once per extension load; session runtime configuration stays branch-selected. See [configuration](usage.md#configuration) for settings and path precedence. Ownership meanings and relative precedence are stable, but participation is a captured validated nonempty subset of Global/CWD/Session; omission defaults to all three, Global is not mandatory. Global defaults and explicit native scope choices remain separate from mode and current/private/source admission; see the [functional scope boundary](scope-selection-contract.md#m2-functional-acceptance-boundary).
|
|
821
817
|
|
|
@@ -844,7 +840,7 @@ Status is a projection of the selected runtime and semantic view, not a second s
|
|
|
844
840
|
**Telegram menu layout.** The optional Telegram leaf adapter shows, in order:
|
|
845
841
|
|
|
846
842
|
1. the current mode as a monospace value in the submenu heading;
|
|
847
|
-
2. matching Mode and Inspect participating memory headings (a long-dash-separated description ending in a colon), with
|
|
843
|
+
2. matching Mode and Inspect participating memory headings (a long-dash-separated description ending in a colon), with selection-aware settings-style descriptions; the captured participating owners are named only by that Inspect list, with no separate scope-summary or Session-exclusion line;
|
|
848
844
|
3. one radio row `Off | Passive | Active`, where selected Off uses 🟣, Passive 🟡 or Active 🟢, and inactive choices use ⚫️;
|
|
849
845
|
4. only captured participating owner-inspection buttons, plus Effective for two or three owners. A sole owner is already effective. Inspection stays explicit and available in all three modes; unavailable memory is not invented.
|
|
850
846
|
|
|
@@ -4,21 +4,23 @@
|
|
|
4
4
|
|
|
5
5
|
State Flow requires matching `pi-coding-agent`, `pi-agent-core`, `pi-ai` and `pi-tui` packages at `>=1.0.0`. Keep all four on the same release line. The open-ended peer range permits newer SDK releases; it does not certify them.
|
|
6
6
|
|
|
7
|
-
**
|
|
7
|
+
**Recorded published-baseline environment:** Linux/x64, Node 26.8.1, Git 2.55.0 and matching Pi SDK 1.0.0 packages.
|
|
8
|
+
|
|
9
|
+
**0.27.2 local candidate checks:** Linux/x64, Node 22.19.0 and 24.21.0, Git 2.56.0 and matching Pi SDK 1.0.0 packages; see the [0.27.2 release record](../CHANGELOG.md). These are local deterministic checks, not new exact-tag release CI or installed-client certification.
|
|
8
10
|
|
|
9
11
|
- Repository validation covers tests, typecheck, build, compiled imports and package dry-run. Results apply to the exact source and dependency identities validated.
|
|
10
|
-
- The release workflow
|
|
12
|
+
- The release workflow validates Node **22.19.0** and **24**, then publishes on Node 24. The recorded v0.27.1 release passed 1,696 tests per supported Node; this is baseline evidence, not a validation result for later edits.
|
|
11
13
|
- Tests use isolated stores and scripted providers through the real Pi SDK. They do not certify installed Telegram/TUI reachability, live provider behavior, other operating systems, mixed SDK versions or untested newer SDK releases.
|
|
12
14
|
|
|
13
15
|
Detailed behavioral witnesses live in [temporal acceptance](temporal-acceptance.md); benchmark methodology and source-bound results live in [performance](performance.md).
|
|
14
16
|
|
|
15
17
|
## Canonical scope format admission
|
|
16
18
|
|
|
17
|
-
Core-only canonical scope metadata remains **version 3**, with `strategy` and `tactics` fields. The
|
|
19
|
+
Core-only canonical scope metadata remains **version 3**, with `strategy` and `tactics` fields. The implemented **version 4** codec additionally retains external object-plane descriptors and opaque values independently of loaded definitions; absent internal `modules` metadata keeps existing v3 output. Declared legacy versions **1/2** translate before known-field filtering. Target-format `contract`/`working` roots reject; nested domain keys remain ordinary JSON. Unsupported versions fail closed. These scope versions are distinct from selection-aware Session lifecycle v2 and public module API v1; supported legacy lifecycle-v1 admission retains its complete-cohort proof requirements. External-root tools, captured Active/Passive context and Active producers shipped in 0.27.0; see the [public module boundary](public-module-contract.md).
|
|
18
20
|
|
|
19
21
|
Legacy inspection is observational. Owned semantic acceptance may convert only admitted owner scopes, after complete target-cohort/identity validation, exact source CAS and a verified private backup outside canonical authority. Missing legacy revisions credit retained records only; conversion itself adds no learning transition. Opaque capture/rollback preserves arbitrary original bytes while semantic interpretation requires valid UTF-8. See [migration proof and support limits](semantic-compatibility-decision.md#guarded-publication-and-support-boundary) and [backup/recovery guidance](usage.md#moving-a-store-and-supported-formats).
|
|
20
22
|
|
|
21
|
-
This
|
|
23
|
+
This breaking semantic API/storage change shipped in **0.27.0** and is retained in **0.27.1**. Existing exported names remain where applicable but their fields, callbacks, schemas and paths use Strategy/Tactics; no permanent old-field aliases are provided. Upgrade/quiesce old consumers before deployment: already-deployed unsafe low-level callers cannot be universally fenced. No active store was operated on during development.
|
|
22
24
|
|
|
23
25
|
## Public host seams
|
|
24
26
|
|
|
@@ -69,11 +71,11 @@ Native tests prove no provider call before coherent acceptance, cancellation whi
|
|
|
69
71
|
|
|
70
72
|
**Preferred representation:**
|
|
71
73
|
|
|
72
|
-
- Global `config.json` accepts `mode: "active" | "passive" | "off"
|
|
73
|
-
- Session `
|
|
74
|
-
-
|
|
74
|
+
- Global `config.json` accepts `mode: "active" | "passive" | "off"`, defaulting to Off, and a nonempty unique `scopes` array, defaulting to all three owners. These are initial defaults, not overrides of captured branch policy.
|
|
75
|
+
- Accepted Session lifecycle v2 configuration stores concrete `{mode, scopes}`. Before canonical acceptance, owner-bound native v2 policy records capture the same choice without semantic storage. Commands and Telegram do not edit global defaults; mode-only actions preserve captured scopes.
|
|
76
|
+
- [Usage](usage.md#lifecycle-operations) defines wanted, available and excluded owners and the 0.27.1 diagnostic. A wanted unacquired Session is unavailable, not excluded; inspection/observation never acquires it. [Scope selection](scope-selection-contract.md#m2-functional-acceptance-boundary) owns legacy proof, deferred forks and request-lifetime requirements.
|
|
75
77
|
|
|
76
|
-
**
|
|
78
|
+
**Legacy readable mode representations.** The following are compatibility inputs, not alternative current policy formats. Decoding is read-only; current accepted lifecycle writers use v2 concrete policy, without inspection-triggered conversion or semantic normalization. Malformed explicit scope evidence rejects rather than falling through to a wider mode-only fallback.
|
|
77
79
|
|
|
78
80
|
- Without explicit global mode, absence of all flag-based mode settings means Off.
|
|
79
81
|
- `autoStart: true` means Active. With any flag-based mode setting present, `passiveBootstrap: false` together with `passiveTools: false` means Off; otherwise the fallback is Passive.
|
|
@@ -84,7 +86,7 @@ Native tests prove no provider call before coherent acceptance, cancellation whi
|
|
|
84
86
|
|
|
85
87
|
To use Passive, select it in the current session or set global `mode: "passive"` for new sessions.
|
|
86
88
|
|
|
87
|
-
**SDK and Telegram controls.** The extension SDK accepts an optional `mode` default override. Both Telegram port variants use `snapshot.mode` plus `select(mode)
|
|
89
|
+
**SDK and Telegram controls.** The extension SDK accepts an optional `mode` default override. Both Telegram port variants use `snapshot.mode` plus `select(mode)` and preserve captured scopes. Optional `snapshot.scopes` supplies participation; legacy omission means all three, while malformed explicit scopes reject. The optional additive `snapshot.inferenceBlocked` diagnostic marks failed Active restoration; legacy ports may omit it. A stale callback keyboard may refresh the view without selecting a mode. Synchronous enum-based ports are supported; Start/Stop port signatures are not.
|
|
88
90
|
|
|
89
91
|
## Mode selection and memory restoration
|
|
90
92
|
|
|
@@ -141,7 +143,7 @@ This optional-backup policy does not apply to required semantic publication or r
|
|
|
141
143
|
|
|
142
144
|
## Telegram adapter
|
|
143
145
|
|
|
144
|
-
The optional adapter presents one Off | Passive | Active row and uses the same mode-selection and inspection owners as native commands.
|
|
146
|
+
The optional adapter presents one Off | Passive | Active row and uses the same mode-selection and inspection owners as native commands. It is not a scope chooser: only wanted owners receive inspection buttons, and Effective is offered only for two or three wanted owners. Inspections read validated available memory without acquiring missing owners or clearing fences.
|
|
145
147
|
|
|
146
148
|
- Inspection returns coherent state plus matching revisions, without publication.
|
|
147
149
|
- Controls and inspections acknowledge callbacks before waiting, suppress revoked results and escape late failures in the current menu.
|