@llblab/pi-kit 0.24.1 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/BACKLOG.md +5 -1
- package/CHANGELOG.md +12 -0
- package/README.md +11 -8
- package/node_modules/@llblab/pi-actors/AGENTS.md +2 -0
- package/node_modules/@llblab/pi-actors/CHANGELOG.md +4 -1
- package/node_modules/@llblab/pi-actors/LICENSE +21 -0
- package/node_modules/@llblab/pi-actors/README.md +1 -1
- package/node_modules/@llblab/pi-actors/docs/coordinator-delivery.md +1 -1
- package/node_modules/@llblab/pi-actors/package.json +4 -3
- package/node_modules/@llblab/pi-claude-usage/AGENTS.md +23 -0
- package/node_modules/@llblab/pi-claude-usage/BACKLOG.md +4 -0
- package/node_modules/@llblab/pi-claude-usage/CHANGELOG.md +21 -0
- package/node_modules/@llblab/pi-claude-usage/LICENSE +22 -0
- package/node_modules/@llblab/pi-claude-usage/README.md +155 -0
- package/node_modules/@llblab/pi-claude-usage/banner.jpg +0 -0
- package/node_modules/@llblab/pi-claude-usage/index.ts +8 -0
- package/node_modules/@llblab/pi-claude-usage/lib/extension.ts +30 -0
- package/node_modules/@llblab/pi-claude-usage/lib/fast.ts +24 -0
- package/node_modules/@llblab/pi-claude-usage/lib/query.ts +146 -0
- package/node_modules/@llblab/pi-claude-usage/lib/status-format.ts +297 -0
- package/node_modules/@llblab/pi-claude-usage/lib/status.ts +366 -0
- package/node_modules/@llblab/pi-claude-usage/lib/telegram.ts +44 -0
- package/node_modules/@llblab/pi-claude-usage/lib/usage-store.ts +221 -0
- package/node_modules/@llblab/pi-claude-usage/lib/usage.ts +128 -0
- package/node_modules/@llblab/pi-claude-usage/package.json +64 -0
- package/node_modules/@llblab/pi-clean-room/AGENTS.md +1 -0
- package/node_modules/@llblab/pi-clean-room/CHANGELOG.md +5 -0
- package/node_modules/@llblab/pi-clean-room/LICENSE +21 -0
- package/node_modules/@llblab/pi-clean-room/README.md +1 -1
- package/node_modules/@llblab/pi-clean-room/package.json +3 -2
- package/node_modules/@llblab/pi-codex-usage/AGENTS.md +9 -6
- package/node_modules/@llblab/pi-codex-usage/BACKLOG.md +2 -1
- package/node_modules/@llblab/pi-codex-usage/CHANGELOG.md +17 -0
- package/node_modules/@llblab/pi-codex-usage/README.md +75 -17
- package/node_modules/@llblab/pi-codex-usage/index.ts +8 -1602
- package/node_modules/@llblab/pi-codex-usage/lib/extension.ts +25 -0
- package/node_modules/@llblab/pi-codex-usage/lib/fast.ts +23 -0
- package/node_modules/@llblab/pi-codex-usage/lib/query.ts +368 -0
- package/node_modules/@llblab/pi-codex-usage/lib/status-format.ts +347 -0
- package/node_modules/@llblab/pi-codex-usage/lib/status.ts +435 -0
- package/node_modules/@llblab/pi-codex-usage/lib/telegram.ts +45 -0
- package/node_modules/@llblab/pi-codex-usage/lib/usage-store.ts +229 -0
- package/node_modules/@llblab/pi-codex-usage/lib/usage.ts +425 -0
- package/node_modules/@llblab/pi-codex-usage/package.json +11 -6
- package/node_modules/@llblab/pi-command-fast/AGENTS.md +7 -0
- package/node_modules/@llblab/pi-command-fast/BACKLOG.md +9 -0
- package/node_modules/@llblab/pi-command-fast/CHANGELOG.md +7 -0
- package/node_modules/@llblab/pi-command-fast/LICENSE +21 -0
- package/node_modules/@llblab/pi-command-fast/README.md +42 -0
- package/node_modules/@llblab/pi-command-fast/dist/command.d.ts +8 -0
- package/node_modules/@llblab/pi-command-fast/dist/command.js +52 -0
- package/node_modules/@llblab/pi-command-fast/dist/index.d.ts +3 -0
- package/node_modules/@llblab/pi-command-fast/dist/index.js +3 -0
- package/node_modules/@llblab/pi-command-fast/dist/models-json.d.ts +10 -0
- package/node_modules/@llblab/pi-command-fast/dist/models-json.js +81 -0
- package/node_modules/@llblab/pi-command-fast/package.json +49 -0
- package/node_modules/@llblab/pi-grow-loop/AGENTS.md +1 -0
- package/node_modules/@llblab/pi-grow-loop/CHANGELOG.md +4 -1
- package/node_modules/@llblab/pi-grow-loop/LICENSE +21 -0
- package/node_modules/@llblab/pi-grow-loop/README.md +1 -1
- package/node_modules/@llblab/pi-grow-loop/package.json +3 -2
- package/node_modules/@llblab/pi-state-flow/AGENTS.md +43 -56
- package/node_modules/@llblab/pi-state-flow/BACKLOG.md +17 -3
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +25 -0
- package/node_modules/@llblab/pi-state-flow/LICENSE +21 -0
- package/node_modules/@llblab/pi-state-flow/README.md +18 -15
- package/node_modules/@llblab/pi-state-flow/dist/index.d.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/index.js +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/compaction.d.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/compaction.js +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/config.d.ts +7 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/config.js +16 -7
- package/node_modules/@llblab/pi-state-flow/dist/lib/context.d.ts +9 -9
- package/node_modules/@llblab/pi-state-flow/dist/lib/context.js +5 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/continuation.js +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/durable.d.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/durable.js +7 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/episode.d.ts +3 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/episode.js +5 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/extension.d.ts +3 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +503 -235
- package/node_modules/@llblab/pi-state-flow/dist/lib/git.d.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/git.js +16 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/history.d.ts +11 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/history.js +6 -7
- package/node_modules/@llblab/pi-state-flow/dist/lib/logging.d.ts +4 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/logging.js +1 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/query.d.ts +4 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/query.js +13 -13
- package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.d.ts +7 -6
- package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.js +9 -9
- package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.d.ts +3 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.js +17 -12
- package/node_modules/@llblab/pi-state-flow/dist/lib/session.d.ts +13 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/session.js +62 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.d.ts +23 -8
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.js +52 -20
- package/node_modules/@llblab/pi-state-flow/dist/lib/state.d.ts +22 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/state.js +30 -10
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.d.ts +5 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.js +19 -28
- package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.d.ts +17 -15
- package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.js +52 -52
- package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.d.ts +8 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.js +34 -18
- package/node_modules/@llblab/pi-state-flow/dist/lib/transition.d.ts +5 -5
- package/node_modules/@llblab/pi-state-flow/dist/lib/transition.js +13 -19
- package/node_modules/@llblab/pi-state-flow/dist/package.json +12 -11
- package/node_modules/@llblab/pi-state-flow/dist/skills/state-flow-guide/SKILL.md +2 -2
- package/node_modules/@llblab/pi-state-flow/docs/README.md +2 -1
- package/node_modules/@llblab/pi-state-flow/docs/agent-contract-relocation.md +72 -0
- package/node_modules/@llblab/pi-state-flow/docs/architecture.md +44 -36
- package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +14 -6
- package/node_modules/@llblab/pi-state-flow/docs/fork-contract.md +7 -5
- package/node_modules/@llblab/pi-state-flow/docs/lazy-state.md +6 -6
- package/node_modules/@llblab/pi-state-flow/docs/performance.md +1 -1
- package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +13 -12
- package/node_modules/@llblab/pi-state-flow/docs/usage.md +37 -33
- package/node_modules/@llblab/pi-state-flow/index.ts +3 -2
- package/node_modules/@llblab/pi-state-flow/lib/compaction.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/lib/config.ts +20 -10
- package/node_modules/@llblab/pi-state-flow/lib/context.ts +15 -14
- package/node_modules/@llblab/pi-state-flow/lib/continuation.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/lib/durable.ts +8 -6
- package/node_modules/@llblab/pi-state-flow/lib/episode.ts +6 -6
- package/node_modules/@llblab/pi-state-flow/lib/extension.ts +484 -232
- package/node_modules/@llblab/pi-state-flow/lib/git.ts +14 -5
- package/node_modules/@llblab/pi-state-flow/lib/history.ts +16 -11
- package/node_modules/@llblab/pi-state-flow/lib/logging.ts +5 -1
- package/node_modules/@llblab/pi-state-flow/lib/query.ts +16 -16
- package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +11 -11
- package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +19 -13
- package/node_modules/@llblab/pi-state-flow/lib/session.ts +57 -3
- package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +57 -22
- package/node_modules/@llblab/pi-state-flow/lib/state.ts +46 -13
- package/node_modules/@llblab/pi-state-flow/lib/status.ts +23 -32
- package/node_modules/@llblab/pi-state-flow/lib/telegram.ts +66 -65
- package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +39 -19
- package/node_modules/@llblab/pi-state-flow/lib/transition.ts +19 -27
- package/node_modules/@llblab/pi-state-flow/package.json +12 -11
- package/node_modules/@llblab/pi-state-flow/skills/state-flow-guide/SKILL.md +2 -2
- package/node_modules/jsonc-parser/CHANGELOG.md +76 -0
- package/node_modules/jsonc-parser/LICENSE.md +21 -0
- package/node_modules/jsonc-parser/README.md +364 -0
- package/node_modules/jsonc-parser/SECURITY.md +41 -0
- package/node_modules/jsonc-parser/lib/esm/impl/edit.js +185 -0
- package/node_modules/jsonc-parser/lib/esm/impl/format.js +261 -0
- package/node_modules/jsonc-parser/lib/esm/impl/parser.js +659 -0
- package/node_modules/jsonc-parser/lib/esm/impl/scanner.js +443 -0
- package/node_modules/jsonc-parser/lib/esm/impl/string-intern.js +29 -0
- package/node_modules/jsonc-parser/lib/esm/main.d.ts +351 -0
- package/node_modules/jsonc-parser/lib/esm/main.js +178 -0
- package/node_modules/jsonc-parser/lib/umd/impl/edit.js +201 -0
- package/node_modules/jsonc-parser/lib/umd/impl/format.js +275 -0
- package/node_modules/jsonc-parser/lib/umd/impl/parser.js +682 -0
- package/node_modules/jsonc-parser/lib/umd/impl/scanner.js +456 -0
- package/node_modules/jsonc-parser/lib/umd/impl/string-intern.js +42 -0
- package/node_modules/jsonc-parser/lib/umd/main.d.ts +351 -0
- package/node_modules/jsonc-parser/lib/umd/main.js +194 -0
- package/node_modules/jsonc-parser/package.json +37 -0
- package/package.json +10 -6
|
@@ -20,35 +20,50 @@ export function stateFlowTelegramSectionSpecifiers(moduleUrl = import.meta.url)
|
|
|
20
20
|
new URL("../../../pi-telegram/dist/api/sections.js", moduleUrl).href,
|
|
21
21
|
];
|
|
22
22
|
}
|
|
23
|
-
/** Main-menu section label
|
|
23
|
+
/** Main-menu section label shows only the current session mode. */
|
|
24
24
|
export function formatStateFlowSectionLabel(snapshot) {
|
|
25
|
-
|
|
26
|
-
return "🌀 State Flow: off";
|
|
27
|
-
return `🌀 State Flow: ${snapshot.revisions ? formatScopeRevisionVector(snapshot.revisions) : `#${snapshot.step}`}`;
|
|
25
|
+
return `🌀 State Flow: ${snapshot.mode}`;
|
|
28
26
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return
|
|
27
|
+
export const STATE_FLOW_MODES = ["off", "passive", "active"];
|
|
28
|
+
const STATE_FLOW_MODE_LABELS = { off: "Off", passive: "Passive", active: "Active" };
|
|
29
|
+
const STATE_FLOW_SELECTED_MARKERS = { off: "🟡", passive: "🟣", active: "🟢" };
|
|
30
|
+
function isStateFlowModeAction(value) {
|
|
31
|
+
return STATE_FLOW_MODES.includes(value);
|
|
34
32
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
function modeReceiptNotice(mode, result) {
|
|
34
|
+
if (result.ok && (result.message === `State Flow ${mode}` || result.message === `State Flow is already ${mode}`))
|
|
35
|
+
return undefined;
|
|
36
|
+
return result.message;
|
|
38
37
|
}
|
|
39
|
-
/**
|
|
40
|
-
const STATE_FLOW_SECTION_HELP = "Accepted memory remains visible in active and passive modes. Start or Stop changes episode behavior, not state access.";
|
|
41
|
-
/** The submenu header repeats the button's state line; the single action matches the current state. */
|
|
38
|
+
/** One radio-style mode row followed directly by read-only scope actions. */
|
|
42
39
|
export function buildStateFlowSectionView(snapshot, callbackData) {
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
const modes = STATE_FLOW_MODES.map((mode) => ({
|
|
41
|
+
text: `${mode === snapshot.mode ? STATE_FLOW_SELECTED_MARKERS[mode] : "⚫️"} ${STATE_FLOW_MODE_LABELS[mode]}`,
|
|
42
|
+
callback_data: callbackData(mode),
|
|
43
|
+
}));
|
|
46
44
|
return {
|
|
47
|
-
text: [
|
|
45
|
+
text: [
|
|
46
|
+
`<b>🌀 State Flow:</b> <code>${snapshot.mode}</code>`,
|
|
47
|
+
"",
|
|
48
|
+
"<b>Mode</b> — choose a workflow (switching modes never erases stored memory):",
|
|
49
|
+
"",
|
|
50
|
+
"<code>-</code> <code>off</code> (default): regular chat without State Flow memory tools or context.",
|
|
51
|
+
"<code>-</code> <code>passive</code>: regular chat with memory tools; available combined memory enters the agent's context.",
|
|
52
|
+
"<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.",
|
|
53
|
+
"",
|
|
54
|
+
"<b>Inspect memory</b> — view stored state even in Off:",
|
|
55
|
+
"",
|
|
56
|
+
"<code>-</code> <code>global</code>: memory shared across projects and sessions.",
|
|
57
|
+
"<code>-</code> <code>cwd</code>: memory shared by sessions in this directory.",
|
|
58
|
+
"<code>-</code> <code>session</code>: private memory for this session, kept on resume.",
|
|
59
|
+
"<code>-</code> <code>effective</code>: merged Global, CWD and Session state; the agent can use it when memory is enabled and available.",
|
|
60
|
+
].join("\n"),
|
|
48
61
|
parseMode: "html",
|
|
49
62
|
replyMarkup: { inline_keyboard: [
|
|
50
|
-
|
|
51
|
-
[
|
|
63
|
+
modes,
|
|
64
|
+
...[["global", "cwd"], ["session", "effective"]].map((row) => row.map((scope) => ({
|
|
65
|
+
text: STATE_FLOW_SCOPE_LABELS[scope], callback_data: callbackData("inspect", scope),
|
|
66
|
+
}))),
|
|
52
67
|
] },
|
|
53
68
|
};
|
|
54
69
|
}
|
|
@@ -58,17 +73,6 @@ const STATE_FLOW_SCOPE_LABELS = {
|
|
|
58
73
|
session: "💬 Session",
|
|
59
74
|
effective: "🧬 Effective",
|
|
60
75
|
};
|
|
61
|
-
export function buildStateFlowScopeChooser(callbackData) {
|
|
62
|
-
return {
|
|
63
|
-
text: "<b>👁 Show state:</b>",
|
|
64
|
-
parseMode: "html",
|
|
65
|
-
replyMarkup: { inline_keyboard: [
|
|
66
|
-
...["global", "cwd", "session", "effective"].map((scope) => [
|
|
67
|
-
{ text: STATE_FLOW_SCOPE_LABELS[scope], callback_data: callbackData("inspect", scope) },
|
|
68
|
-
]),
|
|
69
|
-
] },
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
76
|
// The complete message serializes each preformatted field one additional time;
|
|
73
77
|
// 3,000 leaves safe headroom for worst-case JSON escaping across all four fields.
|
|
74
78
|
const STATE_FLOW_TELEGRAM_FIELD_MAX_CHARS = 3_000;
|
|
@@ -113,10 +117,10 @@ export function renderStateFlowRichState(scope, revisions, state) {
|
|
|
113
117
|
text: [`${STATE_FLOW_SCOPE_LABELS[scope]}: `, { type: "code", text: revision }],
|
|
114
118
|
size: 3,
|
|
115
119
|
},
|
|
116
|
-
...fields.map((field) => ({
|
|
120
|
+
...fields.filter((field) => state[field] !== undefined && state[field] !== "").map((field) => ({
|
|
117
121
|
type: "details",
|
|
118
122
|
summary: { type: "code", text: field },
|
|
119
|
-
blocks: [{ type: "pre", language: "json", text: renderStateFlowTelegramField(state[field]
|
|
123
|
+
blocks: [{ type: "pre", language: "json", text: renderStateFlowTelegramField(state[field]) }],
|
|
120
124
|
})),
|
|
121
125
|
],
|
|
122
126
|
skip_entity_detection: true,
|
|
@@ -131,20 +135,16 @@ function buildStateFlowTelegramSection(port, isActive) {
|
|
|
131
135
|
id: STATE_FLOW_TELEGRAM_ID,
|
|
132
136
|
label: "🌀 State Flow",
|
|
133
137
|
getLabel: () => formatStateFlowSectionLabel(port.snapshot()),
|
|
134
|
-
render: (ctx) => buildStateFlowSectionView(port.snapshot(), (action) => ctx.callbackData(action)),
|
|
138
|
+
render: (ctx) => buildStateFlowSectionView(port.snapshot(), (action, payload) => ctx.callbackData(action, payload)),
|
|
135
139
|
handleCallback: async (ctx) => {
|
|
136
|
-
//
|
|
137
|
-
|
|
140
|
+
// Keyboards sent by earlier versions re-render (start/stop/refresh) or withdraw deferral (cancel); they change no mode.
|
|
141
|
+
const legacy = ctx.action === "start" || ctx.action === "stop" || ctx.action === "cancel" || ctx.action === "refresh";
|
|
142
|
+
if (!isStateFlowModeAction(ctx.action) && !legacy && ctx.action !== "show-state" && ctx.action !== "inspect" && ctx.action !== "back")
|
|
138
143
|
return "pass";
|
|
139
144
|
const request = ++interaction;
|
|
140
145
|
let notice;
|
|
141
146
|
let acknowledged = false;
|
|
142
147
|
try {
|
|
143
|
-
if (ctx.action === "show-state") {
|
|
144
|
-
await ctx.answerCallback();
|
|
145
|
-
await ctx.edit(buildStateFlowScopeChooser((action, payload) => ctx.callbackData(action, payload)));
|
|
146
|
-
return "handled";
|
|
147
|
-
}
|
|
148
148
|
if (ctx.action === "inspect") {
|
|
149
149
|
if (!isStateFlowTelegramScope(ctx.payload))
|
|
150
150
|
throw new Error("Unknown State Flow scope");
|
|
@@ -167,25 +167,25 @@ function buildStateFlowTelegramSection(port, isActive) {
|
|
|
167
167
|
await ctx.answerCallback();
|
|
168
168
|
return "handled";
|
|
169
169
|
}
|
|
170
|
-
const
|
|
171
|
-
if (
|
|
170
|
+
const mode = isStateFlowModeAction(ctx.action) && (ctx.action !== "active" || port.canStartNow()) ? ctx.action : undefined;
|
|
171
|
+
if (mode) {
|
|
172
172
|
if ("inspect" in port) {
|
|
173
173
|
acknowledged = true;
|
|
174
|
-
//
|
|
174
|
+
// Apply the control immediately and acknowledge in parallel; neither promise can reject unobserved.
|
|
175
175
|
const [, result] = await Promise.all([
|
|
176
|
-
ctx.answerCallback(
|
|
177
|
-
Promise.resolve().then(() => port
|
|
176
|
+
ctx.answerCallback(`Switching State Flow to ${mode}`),
|
|
177
|
+
Promise.resolve().then(() => port.select(mode)),
|
|
178
178
|
]);
|
|
179
179
|
if (result.signal?.aborted)
|
|
180
180
|
return "handled";
|
|
181
|
-
notice = result
|
|
181
|
+
notice = modeReceiptNotice(mode, result);
|
|
182
182
|
}
|
|
183
183
|
else
|
|
184
|
-
notice = port
|
|
184
|
+
notice = modeReceiptNotice(mode, port.select(mode));
|
|
185
185
|
}
|
|
186
|
-
else if (ctx.action === "
|
|
186
|
+
else if (ctx.action === "active") {
|
|
187
187
|
port.deferStart();
|
|
188
|
-
notice = "State Flow will
|
|
188
|
+
notice = "State Flow will become active after the current turn";
|
|
189
189
|
}
|
|
190
190
|
else if (ctx.action === "cancel") {
|
|
191
191
|
port.cancelStart();
|
|
@@ -198,7 +198,7 @@ function buildStateFlowTelegramSection(port, isActive) {
|
|
|
198
198
|
if (request !== interaction || !isActive())
|
|
199
199
|
return "handled";
|
|
200
200
|
const summary = notice === undefined ? undefined : conciseDiagnostic(notice, 200);
|
|
201
|
-
const view = buildStateFlowSectionView(port.snapshot(), (action) => ctx.callbackData(action));
|
|
201
|
+
const view = buildStateFlowSectionView(port.snapshot(), (action, payload) => ctx.callbackData(action, payload));
|
|
202
202
|
if (acknowledged && summary !== undefined) {
|
|
203
203
|
// Callback queries can expire during storage waits; retain errors in the existing menu instead.
|
|
204
204
|
view.text += `\n\n${summary.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">")}`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type RecentScopePatch } from "./history.ts";
|
|
2
|
-
import { type MaterializedState, type
|
|
2
|
+
import { type MaterializedState, type SemanticState, type ScopedSemanticStates, type StateScope } from "./state.ts";
|
|
3
3
|
/** Owns hot temporal algebra; excludes filesystem, Git, identity allocation, and Pi lifecycle. */
|
|
4
4
|
export interface TransitionBoundary {
|
|
5
5
|
id: string;
|
|
@@ -9,7 +9,7 @@ export interface TransitionBoundary {
|
|
|
9
9
|
}
|
|
10
10
|
export interface ScopeCheckpoint {
|
|
11
11
|
through: TransitionBoundary;
|
|
12
|
-
state:
|
|
12
|
+
state: SemanticState;
|
|
13
13
|
}
|
|
14
14
|
export interface TemporalPatch {
|
|
15
15
|
transition: TransitionBoundary;
|
|
@@ -37,7 +37,7 @@ export declare function validateTemporalState(view: TemporalState, historyLimit?
|
|
|
37
37
|
/** Adopt revision-proven inherited streams without rewriting their checkpoints or tails. */
|
|
38
38
|
export declare function adoptTemporalStreams(scopes: Record<StateScope, ScopeStream>, id: string, historyLimit?: number): TemporalState;
|
|
39
39
|
/** New or migrated state starts at a proven current boundary, with no invented past. */
|
|
40
|
-
export declare function createTemporalState(states:
|
|
40
|
+
export declare function createTemporalState(states: ScopedSemanticStates, id: string, historyLimit?: number): TemporalState;
|
|
41
41
|
/** Fold retained tails to a lower configured limit without inventing history. */
|
|
42
42
|
export declare function constrainTemporalState(view: TemporalState, historyLimit: number): TemporalState;
|
|
43
43
|
/** Select one scope at a proven retained boundary from its owning runtime lineage. */
|
|
@@ -46,7 +46,11 @@ export declare function selectScopeStreamAtBoundary(stream: ScopeStream, scope:
|
|
|
46
46
|
export declare function selectTemporalStateBoundary(view: TemporalState, boundaryId: string, historyLimit?: number): TemporalState;
|
|
47
47
|
/** Current independent scope revisions; Effective uses this vector rather than inventing a scalar owner. */
|
|
48
48
|
export declare function temporalScopeRevisions(view: TemporalState): ScopeRevisions;
|
|
49
|
-
/**
|
|
49
|
+
/** Exact scope semantics for authored staging; defaults must never become implicit writes. */
|
|
50
|
+
export declare function readTemporalScopes(view: TemporalState, offset?: number, historyLimit?: number): ScopedSemanticStates;
|
|
51
|
+
/** Sparse current/historical view: unknown planes and absent values never become effective data. */
|
|
52
|
+
export declare function readTemporalView(view: TemporalState, offset?: number, scope?: StateScope, historyLimit?: number): SemanticState;
|
|
53
|
+
/** Internal defaulted materialization for consumers that require object registries. */
|
|
50
54
|
export declare function readTemporalState(view: TemporalState, offset?: number, scope?: StateScope, historyLimit?: number): MaterializedState;
|
|
51
55
|
/** Allocate the identity outside this algebra; only materially effective patches accept it. */
|
|
52
56
|
export declare function advanceTemporalState(view: TemporalState, transitions: readonly RecentScopePatch[], id: string, historyLimit?: number): TemporalState;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_HISTORY_LIMIT, MAX_HISTORY_LIMIT, validateRecentTransition } from "./history.js";
|
|
2
2
|
import { applyPatch, containsNull, isJsonValue, isObject, sameJson } from "./json.js";
|
|
3
|
-
import {
|
|
3
|
+
import { emptyState, isSemanticState, overlayStates, projectSemanticState } from "./state.js";
|
|
4
4
|
const SCOPES = ["global", "cwd", "session"];
|
|
5
5
|
function validateHistoryLimit(limit) {
|
|
6
6
|
if (!Number.isSafeInteger(limit) || limit < 0 || limit > MAX_HISTORY_LIMIT) {
|
|
@@ -16,14 +16,20 @@ function validateBoundary(boundary) {
|
|
|
16
16
|
throw new Error("Invalid State Flow temporal boundary");
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
function validateState(state) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
function validateState(state, location) {
|
|
20
|
+
const json = isJsonValue(state);
|
|
21
|
+
const hasNull = json && isObject(state) && Object.keys(emptyState()).some((key) => containsNull(state[key]));
|
|
22
|
+
if (json && isSemanticState(state) && !hasNull)
|
|
23
|
+
return;
|
|
24
|
+
const reason = !json ? "expected finite, acyclic JSON data"
|
|
25
|
+
: !isObject(state) ? "expected a semantic object"
|
|
26
|
+
: hasNull ? "null is not allowed"
|
|
27
|
+
: "invalid semantic fields or artifact metadata";
|
|
28
|
+
throw new Error(`Invalid temporal materialized semantic state${location ? ` in ${location}` : ""}: ${reason}`);
|
|
23
29
|
}
|
|
24
|
-
function apply(state, patch) {
|
|
30
|
+
function apply(state, patch, location) {
|
|
25
31
|
const next = applyPatch(state, patch);
|
|
26
|
-
validateState(next);
|
|
32
|
+
validateState(next, location);
|
|
27
33
|
return next;
|
|
28
34
|
}
|
|
29
35
|
function sameBoundary(left, right) {
|
|
@@ -42,7 +48,7 @@ export function validateScopeStream(value, scope, historyLimit = DEFAULT_HISTORY
|
|
|
42
48
|
}
|
|
43
49
|
const stream = value;
|
|
44
50
|
validateBoundary(stream.checkpoint.through);
|
|
45
|
-
validateState(stream.checkpoint.state);
|
|
51
|
+
validateState(stream.checkpoint.state, `${scope} checkpoint`);
|
|
46
52
|
if (stream.patches.length > historyLimit)
|
|
47
53
|
throw new Error(`Temporal scope tail exceeds configured history limit ${historyLimit}`);
|
|
48
54
|
if (stream.revision < stream.patches.length)
|
|
@@ -62,9 +68,7 @@ export function validateScopeStream(value, scope, historyLimit = DEFAULT_HISTORY
|
|
|
62
68
|
throw new Error("Disconnected State Flow temporal ancestry");
|
|
63
69
|
}
|
|
64
70
|
validateRecentTransition({ id: record.transition.id, at: 0, transitions: [{ scope, patch: record.patch }] });
|
|
65
|
-
const next = apply(state, record.patch);
|
|
66
|
-
if (sameJson(next, state))
|
|
67
|
-
throw new Error("Temporal scope tail contains a semantic no-op");
|
|
71
|
+
const next = apply(state, record.patch, `${scope} tail`);
|
|
68
72
|
state = next;
|
|
69
73
|
previous = record.transition;
|
|
70
74
|
identities.add(previous.id);
|
|
@@ -244,21 +248,33 @@ export function temporalScopeRevisions(view) {
|
|
|
244
248
|
}
|
|
245
249
|
return revisions;
|
|
246
250
|
}
|
|
247
|
-
|
|
248
|
-
export function readTemporalState(view, offset = 0, scope, historyLimit = DEFAULT_HISTORY_LIMIT) {
|
|
251
|
+
function readBoundary(view, offset, historyLimit) {
|
|
249
252
|
validateHistoryLimit(historyLimit);
|
|
250
253
|
if (!Number.isSafeInteger(offset) || offset < 0 || offset > historyLimit) {
|
|
251
254
|
throw new Error(`State Flow hot-history offset must be an integer from 0 to ${historyLimit}`);
|
|
252
255
|
}
|
|
253
|
-
if (scope !== undefined && !SCOPES.includes(scope))
|
|
254
|
-
throw new Error("Unknown temporal scope");
|
|
255
256
|
validateTemporalState(view, historyLimit);
|
|
256
257
|
const boundary = view.lineage[view.lineage.length - 1 - offset];
|
|
257
258
|
if (!boundary)
|
|
258
259
|
throw new Error("Requested history predates the proven temporal origin");
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
260
|
+
return boundary;
|
|
261
|
+
}
|
|
262
|
+
/** Exact scope semantics for authored staging; defaults must never become implicit writes. */
|
|
263
|
+
export function readTemporalScopes(view, offset = 0, historyLimit = DEFAULT_HISTORY_LIMIT) {
|
|
264
|
+
const boundary = readBoundary(view, offset, historyLimit);
|
|
265
|
+
return { global: scopeAt(view.scopes.global, boundary), cwd: scopeAt(view.scopes.cwd, boundary), session: scopeAt(view.scopes.session, boundary) };
|
|
266
|
+
}
|
|
267
|
+
/** Sparse current/historical view: unknown planes and absent values never become effective data. */
|
|
268
|
+
export function readTemporalView(view, offset = 0, scope, historyLimit = DEFAULT_HISTORY_LIMIT) {
|
|
269
|
+
if (scope !== undefined && !SCOPES.includes(scope))
|
|
270
|
+
throw new Error("Unknown temporal scope");
|
|
271
|
+
const boundary = readBoundary(view, offset, historyLimit);
|
|
272
|
+
const owners = scope === undefined ? SCOPES : [scope];
|
|
273
|
+
return owners.reduce((state, owner) => applyPatch(state, projectSemanticState(scopeAt(view.scopes[owner], boundary))), {});
|
|
274
|
+
}
|
|
275
|
+
/** Internal defaulted materialization for consumers that require object registries. */
|
|
276
|
+
export function readTemporalState(view, offset = 0, scope, historyLimit = DEFAULT_HISTORY_LIMIT) {
|
|
277
|
+
return overlayStates(readTemporalView(view, offset, scope, historyLimit));
|
|
262
278
|
}
|
|
263
279
|
/** Allocate the identity outside this algebra; only materially effective patches accept it. */
|
|
264
280
|
export function advanceTemporalState(view, transitions, id, historyLimit = DEFAULT_HISTORY_LIMIT) {
|
|
@@ -3,9 +3,9 @@ import type { SuccessfulArtifactRead } from "./acquisition.ts";
|
|
|
3
3
|
import { type AcceptedTransition } from "./history.ts";
|
|
4
4
|
import { type SuccessfulSkillRead } from "./skills.ts";
|
|
5
5
|
import type { Snapshot } from "./snapshot.ts";
|
|
6
|
-
import type { AtomicScopePatches,
|
|
6
|
+
import type { AtomicScopePatches, ScopedSemanticStates, StateScope, TerminalTransition } from "./state.ts";
|
|
7
7
|
export interface StagedScopedTransition {
|
|
8
|
-
nextStates:
|
|
8
|
+
nextStates: ScopedSemanticStates;
|
|
9
9
|
stateHashes: Record<StateScope, string>;
|
|
10
10
|
/** Fresh runtime-owned provenance for artifacts compiled in this transition. */
|
|
11
11
|
provenanceUpdates: Record<StateScope, Record<string, ArtifactProvenance>>;
|
|
@@ -13,11 +13,11 @@ export interface StagedScopedTransition {
|
|
|
13
13
|
committed: boolean;
|
|
14
14
|
}
|
|
15
15
|
/** Stage one canonical atomic scope cohort without changing the finalized response. */
|
|
16
|
-
export declare function stageAtomicScopePatches(currentStates:
|
|
17
|
-
export declare function stageScopedTransition(currentStates:
|
|
16
|
+
export declare function stageAtomicScopePatches(currentStates: ScopedSemanticStates, patches: AtomicScopePatches, successfulSkillReads: Iterable<SuccessfulSkillRead>, causalBasis: string, successfulArtifactReads?: Iterable<SuccessfulArtifactRead>): StagedScopedTransition;
|
|
17
|
+
export declare function stageScopedTransition(currentStates: ScopedSemanticStates, transition: TerminalTransition, successfulSkillReads: Iterable<SuccessfulSkillRead>, causalBasis: string, successfulArtifactReads?: Iterable<SuccessfulArtifactRead>): StagedScopedTransition;
|
|
18
18
|
/** Commit one accepted transition; durable publication receives all changed scopes as one cohort. */
|
|
19
19
|
export interface CommitScopedTransitionOptions {
|
|
20
20
|
/** Runtime response reconciliation finalizes bootstrap lifecycle state. */
|
|
21
21
|
finalizeRun?: boolean;
|
|
22
22
|
}
|
|
23
|
-
export declare function commitScopedTransition(snapshot: Snapshot, states:
|
|
23
|
+
export declare function commitScopedTransition(snapshot: Snapshot, states: ScopedSemanticStates, stage: StagedScopedTransition, publishDurable: (accepted: AcceptedTransition | undefined, nextSnapshot: Snapshot) => void, causalBasis: string, options?: CommitScopedTransitionOptions): boolean;
|
|
@@ -2,6 +2,7 @@ import { compileArtifact, ORDINARY_ARTIFACT_COMPILER, validateArtifactMetadata,
|
|
|
2
2
|
import { createAcceptedTransition } from "./history.js";
|
|
3
3
|
import { applyPatch, containsNull, hashJson, isObject, validatePatch } from "./json.js";
|
|
4
4
|
import { hasCompiledSkillArtifact, SKILL_ARTIFACT_COMPILER } from "./skills.js";
|
|
5
|
+
import { emptyState } from "./state.js";
|
|
5
6
|
const SCOPES = new Set(["global", "cwd", "session"]);
|
|
6
7
|
const PATCH_KEYS = new Set(["intents", "contract", "working", "artifacts", "lazy"]);
|
|
7
8
|
function compileReadArtifacts(nextState, patch, successfulArtifactReads, provenance) {
|
|
@@ -82,7 +83,7 @@ function compileReadSkills(scope, nextState, patch, successfulSkillReads, proven
|
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
function validateMaterializedTransition(nextState, scope) {
|
|
85
|
-
if (containsNull(nextState)) {
|
|
86
|
+
if (Object.keys(emptyState()).some((key) => containsNull(nextState[key]))) {
|
|
86
87
|
throw new Error("Materialized state cannot contain null; use null only as an object-key deletion marker");
|
|
87
88
|
}
|
|
88
89
|
validateArtifactRegistry(nextState.artifacts, `${scope}.artifacts`);
|
|
@@ -111,16 +112,6 @@ function validateScopePatch(scope, patch) {
|
|
|
111
112
|
if (isObject(patch.artifacts))
|
|
112
113
|
validateModelArtifactPatch(patch.artifacts, `${scope}.artifacts`);
|
|
113
114
|
}
|
|
114
|
-
function completePatch(patch, response) {
|
|
115
|
-
return {
|
|
116
|
-
artifacts: patch.artifacts ?? {},
|
|
117
|
-
contract: patch.contract ?? {},
|
|
118
|
-
working: patch.working ?? {},
|
|
119
|
-
intents: patch.intents ?? {},
|
|
120
|
-
response,
|
|
121
|
-
lazy: structuredClone(patch.lazy ?? {}),
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
115
|
/** Stage all scope updates against one immutable basis before any state is published. */
|
|
125
116
|
function stageScopedSemanticTransition(currentStates, transition, successfulSkillReads, causalBasis, successfulArtifactReads, acceptedResponse) {
|
|
126
117
|
if (!Array.isArray(transition.transitions))
|
|
@@ -146,14 +137,17 @@ function stageScopedSemanticTransition(currentStates, transition, successfulSkil
|
|
|
146
137
|
const provenanceUpdates = { global: {}, cwd: {}, session: {} };
|
|
147
138
|
for (const scope of SCOPES) {
|
|
148
139
|
const authored = patches.get(scope) ?? {};
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
140
|
+
const patch = { ...authored, ...(scope === "session" && acceptedResponse !== undefined ? { response: acceptedResponse } : {}) };
|
|
141
|
+
const materialized = applyPatch({ ...emptyState(), ...currentStates[scope] }, patch);
|
|
142
|
+
compileReadArtifacts(materialized, { artifacts: authored.artifacts ?? {} }, artifactReads.filter((read) => (read.scope ?? "global") === scope), provenanceUpdates[scope]);
|
|
143
|
+
compileReadSkills(scope, materialized, { artifacts: authored.artifacts ?? {} }, skillReads.filter((read) => read.scope === scope), provenanceUpdates[scope]);
|
|
144
|
+
validateMaterializedTransition(materialized, scope);
|
|
145
|
+
const nextState = materialized;
|
|
146
|
+
for (const key of Object.keys(emptyState())) {
|
|
147
|
+
if (!Object.hasOwn(currentStates[scope], key) && !Object.hasOwn(patch, key)
|
|
148
|
+
&& !(key === "artifacts" && Object.keys(provenanceUpdates[scope]).length > 0))
|
|
149
|
+
delete nextState[key];
|
|
150
|
+
}
|
|
157
151
|
nextStates[scope] = nextState;
|
|
158
152
|
}
|
|
159
153
|
return {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llblab/pi-state-flow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
|
+
"license": "MIT",
|
|
4
5
|
"private": false,
|
|
5
6
|
"description": "Incremental scoped state/context/memory compiler for Pi, inspired by SKILL.state",
|
|
6
7
|
"keywords": [
|
|
@@ -66,17 +67,17 @@
|
|
|
66
67
|
"node": ">=22.19.0"
|
|
67
68
|
},
|
|
68
69
|
"peerDependencies": {
|
|
69
|
-
"@earendil-works/pi-agent-core": ">=0.
|
|
70
|
-
"@earendil-works/pi-ai": ">=0.
|
|
71
|
-
"@earendil-works/pi-coding-agent": ">=0.
|
|
72
|
-
"@earendil-works/pi-tui": ">=0.
|
|
70
|
+
"@earendil-works/pi-agent-core": ">=1.0.0",
|
|
71
|
+
"@earendil-works/pi-ai": ">=1.0.0",
|
|
72
|
+
"@earendil-works/pi-coding-agent": ">=1.0.0",
|
|
73
|
+
"@earendil-works/pi-tui": ">=1.0.0"
|
|
73
74
|
},
|
|
74
75
|
"devDependencies": {
|
|
75
|
-
"@earendil-works/pi-agent-core": "0.
|
|
76
|
-
"@earendil-works/pi-ai": "0.
|
|
77
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
78
|
-
"@earendil-works/pi-tui": "0.
|
|
79
|
-
"@types/node": "
|
|
80
|
-
"typescript": "
|
|
76
|
+
"@earendil-works/pi-agent-core": "1.0.0",
|
|
77
|
+
"@earendil-works/pi-ai": "1.0.0",
|
|
78
|
+
"@earendil-works/pi-coding-agent": "1.0.0",
|
|
79
|
+
"@earendil-works/pi-tui": "1.0.0",
|
|
80
|
+
"@types/node": "^26.4.0",
|
|
81
|
+
"typescript": "^7.0.2"
|
|
81
82
|
}
|
|
82
83
|
}
|
|
@@ -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-
|
|
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. Commands and Telegram change only the current session's `mode`. Global `mode` defaults to Off for new sessions and never overrides retained choices. Do not change mode without operator authorization.
|
|
19
19
|
|
|
20
20
|
## Map
|
|
21
21
|
|
|
@@ -56,7 +56,7 @@ Call `patch_state` alone per assistant response; await acceptance before depende
|
|
|
56
56
|
|
|
57
57
|
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.
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
When present, semantic planes `intents`, `contract`, `working`, `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. Checkpoint/tail readers ignore unknown top-level fields, and writers emit only known fields. 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, omitted fields persist. Nested `null` removes an owned object key; inherited content may reappear. Canonical `"[N]"` keys patch array elements; indexed deletion is forbidden.
|
|
60
60
|
|
|
61
61
|
Illustrative deletion, only for an actually completed intent and after satisfying pending acquisitions:
|
|
62
62
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# State Flow documentation
|
|
2
2
|
|
|
3
|
-
- [Usage and recovery](usage.md): Configuration, new/resumed sessions,
|
|
3
|
+
- [Usage and recovery](usage.md): Configuration, new/resumed sessions, Active/Passive/Off controls, diagnostics, privacy, and storage recovery.
|
|
4
4
|
- [Architecture](architecture.md): Semantic state, temporal algebra, Pi lifecycle, storage, publication, artifacts, and embedding contracts.
|
|
5
5
|
- [Lazy state](lazy-state.md): Implemented ordinary-JSON lazy planes, an effective-by-default `lazy` read path, pure state/patch snapshots, narrow structural `meta` + `keys`, and recursive indexed array patches.
|
|
6
6
|
- [Filesystem recovery](filesystem-recovery.md): Cohort-wide absence, partial-presence, malformed-evidence, repair-authority, and transaction rules.
|
|
7
7
|
- [Temporal acceptance](temporal-acceptance.md): Required temporal properties and their executable witnesses.
|
|
8
8
|
- [SDK compatibility](compatibility.md): Tested dependency stacks, public lifecycle seams, isolated validation, and host limits.
|
|
9
9
|
- [Physical fork contract](fork-contract.md): Session-stream copying, live shared memory, child ownership/origin, and tested support boundaries.
|
|
10
|
+
- [Agent contract relocation ledger](agent-contract-relocation.md): Source-bound paragraph-to-owner parity map for the compact `AGENTS.md`, with transferred clauses and validation evidence.
|
|
10
11
|
- [Session performance](performance.md): Reproducible native-Pi/stateful workloads, long-session resume measurements, two-process publication probes, and evidence limits.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Agent contract relocation ledger
|
|
2
|
+
|
|
3
|
+
This is the source-bound **paragraph-to-owner parity map** for the 8,141-word pre-compaction `AGENTS.md` (SHA-256 `0d328eacc96d6b67c5eb036a51adc27e1dcd24d20bb6695f2fff6d5a3c87737b`; source lines 3–58, based on commit `70baecde` plus the Passive-footprint and `barrier-block` edits). Each `L##` identifies exactly one original bullet/paragraph. Its destination is the current owner of that paragraph's reusable contract; where necessary, a compact root rule or executable witness is also named. The root remains approximately 1,300 words; its 0.23.0 default-mode rule supersedes the original Passive-default clause. This is a reviewed documentation trace, not a claim that prose links alone prove runtime correctness.
|
|
4
|
+
|
|
5
|
+
## Composition, semantics, and model access
|
|
6
|
+
|
|
7
|
+
- L03 domain ownership, entrypoint and mirrored tests → [composition](architecture.md#composition), [invariant tests](../tests/invariants.test.ts).
|
|
8
|
+
- L04 Active opt-in, former Passive default/conditional projection, Off → [configuration](usage.md#configuration), [mode behavior](usage.md#active-passive-and-configured-off).
|
|
9
|
+
- L05 three session-owned mode workflows and global default → [mode behavior](usage.md#active-passive-and-configured-off), [configuration](usage.md#configuration).
|
|
10
|
+
- L06 native trace, frozen head, run anchors and foreign context → [Pi lifecycle](architecture.md#pi-lifecycle), [context limits](performance.md#context-projection-and-trajectory-selection), [lifecycle witnesses](temporal-acceptance.md#required-properties-and-witnesses).
|
|
11
|
+
- L07 sparse planes, projection, lazy filtering and intents → [semantic state](architecture.md#semantic-state), [model tools](architecture.md#model-tools), [lazy state](lazy-state.md).
|
|
12
|
+
- L08 artifact entries and hidden provenance → [artifact routing](architecture.md#artifact-routing).
|
|
13
|
+
- L09 exact registered-path observation → [artifact routing](architecture.md#artifact-routing), [source acquisition](usage.md#memory-and-source-acquisition).
|
|
14
|
+
- L10 compilation classifier, fingerprints and Skill masking → [artifact routing](architecture.md#artifact-routing).
|
|
15
|
+
- L11 stable exact-path acquisition and fork provenance → [artifact routing](architecture.md#artifact-routing), [Git/restore provenance](architecture.md#optional-git-backup), [fork contract](fork-contract.md).
|
|
16
|
+
- L12 global config, legacy modes and limits → [configuration](usage.md#configuration), [mode compatibility](compatibility.md#mode-configuration-compatibility).
|
|
17
|
+
- L13 session runtime/config/checkpoints and continuation authority → [storage and identity](architecture.md#storage-and-identity), [session continuation](architecture.md#session-continuation), [mode restoration](compatibility.md#mode-selection-and-memory-restoration).
|
|
18
|
+
- L14 overlay, scope ownership and Skill routing → [semantic state](architecture.md#semantic-state), [artifact routing](architecture.md#artifact-routing).
|
|
19
|
+
- L17 composed historical offsets → [temporal model](architecture.md#temporal-model).
|
|
20
|
+
- L18 lazy historical reads and tool availability → [model tools](architecture.md#model-tools), [lazy navigation](usage.md#lazy-navigation-and-historical-reading).
|
|
21
|
+
- L27 patch grammar, shared-head staging and private ownership → [model tools](architecture.md#model-tools), [asynchronous transaction](architecture.md#asynchronous-storage-transaction).
|
|
22
|
+
- L28 barrier and minimal acceptance receipts → [Pi lifecycle](architecture.md#pi-lifecycle), [tool preflight evidence](performance.md#tool-preflight-parent-traversal).
|
|
23
|
+
- L29 accepted-response reconciliation and cancellation → [Pi lifecycle](architecture.md#pi-lifecycle), [session behavior](usage.md#session-behavior).
|
|
24
|
+
- L35 omission, empty-scope rejection and response equivalence → [model tools](architecture.md#model-tools), [temporal model](architecture.md#temporal-model).
|
|
25
|
+
- L37 public-boundary draft detachment → [storage and identity](architecture.md#storage-and-identity), [COW evidence](performance.md#memory-only-owned-draft-cow).
|
|
26
|
+
- L38 recursive patch/null and replay → [model tools](architecture.md#model-tools), [semantic state](architecture.md#semantic-state).
|
|
27
|
+
- L39 no project schemas or size/action ledgers → [model tools](architecture.md#model-tools), [operational boundaries](../README.md#operational-boundaries).
|
|
28
|
+
- L49 no strict boundedness claim → [operational boundaries](../README.md#operational-boundaries), [performance limits](performance.md#scope).
|
|
29
|
+
- L51 tool toggle and Passive read/write boundary → [mode behavior](usage.md#active-passive-and-configured-off), [model tools](architecture.md#model-tools).
|
|
30
|
+
|
|
31
|
+
## Canonical storage, lifecycle, and backup
|
|
32
|
+
|
|
33
|
+
- L15 anchored checkpoints/tails and retention folding → [temporal model](architecture.md#temporal-model), [storage and identity](architecture.md#storage-and-identity).
|
|
34
|
+
- L16 opaque causal identity, origins and shared drift → [temporal model](architecture.md#temporal-model), [Pi lifecycle](architecture.md#pi-lifecycle).
|
|
35
|
+
- L19 canonical layout and identity → [storage and identity](architecture.md#storage-and-identity).
|
|
36
|
+
- L20 optimistic durability, optional backup and contention → [power-loss boundary](filesystem-recovery.md#power-loss-durability), [asynchronous transaction](architecture.md#asynchronous-storage-transaction), [optional Git backup](architecture.md#optional-git-backup).
|
|
37
|
+
- L21 cohort classification and missing shared pairs → [recovery](usage.md#missing-partial-and-malformed-storage), [transaction rule](filesystem-recovery.md#transaction-rule).
|
|
38
|
+
- L22 predecessor formats and no in-place migration → [format boundary](usage.md#moving-a-store-and-the-017-format-boundary), [optional Git backup](architecture.md#optional-git-backup).
|
|
39
|
+
- L23 exact-file CAS, awaited transaction and rollback → [asynchronous transaction](architecture.md#asynchronous-storage-transaction), [storage and identity](architecture.md#storage-and-identity), [transaction rule](filesystem-recovery.md#transaction-rule).
|
|
40
|
+
- L24 initialization and exact-source fork → [Pi lifecycle](architecture.md#pi-lifecycle), [fork contract](fork-contract.md).
|
|
41
|
+
- L25 retained-boundary restore, failed-Stop read-only recovery and selection races → [Pi lifecycle](architecture.md#pi-lifecycle), [mode restoration](compatibility.md#mode-selection-and-memory-restoration).
|
|
42
|
+
- L26 independent revisions, backup capture/index/push/shutdown → [temporal model](architecture.md#temporal-model), [optional Git backup](architecture.md#optional-git-backup).
|
|
43
|
+
- L40 first active context preparation, abort and specification authority → [Pi lifecycle](architecture.md#pi-lifecycle), [pre-inference cancellation](compatibility.md#pre-inference-cancellation).
|
|
44
|
+
- L41 one existing-session bootstrap run → [session behavior](usage.md#session-behavior).
|
|
45
|
+
- L42 selected-branch retained-boundary restoration → [Pi lifecycle](architecture.md#pi-lifecycle), [fork contract](fork-contract.md).
|
|
46
|
+
- L44 Start/current-head acceptance and Active default → [asynchronous transaction](architecture.md#asynchronous-storage-transaction), [mode behavior](usage.md#active-passive-and-configured-off).
|
|
47
|
+
- L45 Passive/Off persistence and frozen Stop handoff → [Pi lifecycle](architecture.md#pi-lifecycle), [mode operations](usage.md#lifecycle-operations), [mode restoration](compatibility.md#mode-selection-and-memory-restoration).
|
|
48
|
+
- L46 failed-Stop marker and fence → [storage recovery](usage.md#storage-and-recovery), [Pi lifecycle](architecture.md#pi-lifecycle).
|
|
49
|
+
- L47 settled native compaction boundary → [session behavior](usage.md#session-behavior), [SDK settlement](compatibility.md#settlement-cancellation), [lifecycle witnesses](temporal-acceptance.md#required-properties-and-witnesses).
|
|
50
|
+
|
|
51
|
+
## Operator, agent, and development policy
|
|
52
|
+
|
|
53
|
+
- L30 terminal handoff plane routing → [operational guidance](architecture.md#operational-guidance-and-memory-curation), [semantic state](architecture.md#semantic-state).
|
|
54
|
+
- L31 consequential evidence, semantic references and dangling hints → [model tools](architecture.md#model-tools), [lazy navigation](usage.md#lazy-navigation-and-historical-reading), [memory curation](architecture.md#operational-guidance-and-memory-curation).
|
|
55
|
+
- L32 volatile observation and external-effects revalidation → [operational boundaries](../README.md#operational-boundaries), [memory guidance](usage.md#memory-and-source-acquisition).
|
|
56
|
+
- L33 registered Skill acquisition → [artifact routing](architecture.md#artifact-routing).
|
|
57
|
+
- L34 bounded curation and verified transfers → [operational guidance](architecture.md#operational-guidance-and-memory-curation), [memory Skill](../skills/state-flow-memory/SKILL.md).
|
|
58
|
+
- L36 logging categories, privacy and error elision → [diagnostic privacy](usage.md#diagnostic-logging-and-privacy), [barrier contract](architecture.md#pi-lifecycle).
|
|
59
|
+
- L43 terminal status and read-only scope inspection → [status and controls](usage.md#status-and-controls), [observability](architecture.md#observability).
|
|
60
|
+
- L48 system section, context refresh and foreign prompt precedence → [Pi lifecycle](architecture.md#pi-lifecycle), [host context compatibility](compatibility.md#context-tools-and-provider-input).
|
|
61
|
+
- L50 extension-agnostic core and Telegram controls/receipts → [composition](architecture.md#composition), [observability](architecture.md#observability), [Telegram compatibility](compatibility.md#telegram-adapter).
|
|
62
|
+
- L52 tag release authority and version alignment → [release workflow](../.github/workflows/release.yml), [release boundary](../BACKLOG.md#release-boundary). Retain the durable no-token constraint in compact `AGENTS.md` until a permanent developer contract owns it.
|
|
63
|
+
- L53 opt-in benchmark location and source identity → [benchmark guide](../benchmarks/README.md), [performance validation](performance.md#validation-and-reporting).
|
|
64
|
+
- L54 provider callback completion witness → [temporal acceptance](temporal-acceptance.md#required-properties-and-witnesses), [integration tests](../tests/integration.test.ts).
|
|
65
|
+
- L55 awaited fixture handlers and withdrawal witness → [temporal acceptance](temporal-acceptance.md#required-properties-and-witnesses), [extension tests](../tests/extension.test.ts).
|
|
66
|
+
- L56 tracked `dist/` and build/package parity → [release workflow](../.github/workflows/release.yml), [release invariant tests](../tests/invariants.test.ts). Retain the developer rule in compact `AGENTS.md` unless a durable release guide takes ownership.
|
|
67
|
+
- L57 current docs vs delivery history → [documentation index](README.md), compact `AGENTS.md` (durable documentation policy).
|
|
68
|
+
- L58 validation order → compact `AGENTS.md` (durable development rule), [validation procedure](compatibility.md#validation-procedure).
|
|
69
|
+
|
|
70
|
+
## Verification evidence
|
|
71
|
+
|
|
72
|
+
The map names all 56 source paragraphs exactly once. Each was compared with its destinations; the highest-risk clause groups were checked explicitly: L06/L45 native run anchors and Stop context, L23–L26 CAS/backup/rollback, L28 receipt-elision bounds, L31 reference/epistemic limits, L36 diagnostic privacy, L47 native compaction and L50 callback revocation. An additional exact-code-token audit exposed otherwise easy-to-lose clauses: legacy `{disabled:true}`, in-memory header key derivation, materialization equality, `contract.compiled_skills` rejection, Skill compiler revision, runtime-origin null exception and normalized artifact replay. Those are now stated in architecture; terse `patches[n]` and `{value:null, hint:[...]}` from the source are represented there by the more precise scoped patch path and expanded dangling-reference sentinel. The remaining uniquely durable developer rules, including no live-store fixture edits, stay in the compact root. `tests/invariants.test.ts` is unchanged; native and domain-specific witnesses remain in their named test files. Package, context and domain-DAG validation establish the final checked boundary; they cannot substitute for semantic judgment about future models.
|