@code-yeongyu/senpi 2026.11.2-3 → 2026.11.3-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/bundle/chunks/{anthropic-messages-WUPLDYD6.js → anthropic-messages-AFWQB3KN.js} +1 -1
- package/dist/bundle/chunks/{args-AOI4NEA6.js → args-O3WS4WCO.js} +1 -1
- package/dist/bundle/chunks/{chunk-O4GRBX4R.js → chunk-3WJ2DE2G.js} +1 -1
- package/dist/bundle/chunks/{chunk-LMIETUPG.js → chunk-4BF4FLT6.js} +1 -1
- package/dist/bundle/chunks/{chunk-T5ZJ2Q4O.js → chunk-4SENPCEA.js} +1 -1
- package/dist/bundle/chunks/chunk-5DZD623T.js +448 -0
- package/dist/bundle/chunks/{chunk-TXOR5BQL.js → chunk-6BSMXZKQ.js} +1 -1
- package/dist/bundle/chunks/{chunk-VRWJJMHO.js → chunk-7565XQAU.js} +1 -1
- package/dist/bundle/chunks/{chunk-IWM5QRAE.js → chunk-7KLEFHSU.js} +1 -1
- package/dist/bundle/chunks/{chunk-FO56LSUK.js → chunk-BNIZP4OS.js} +1 -1
- package/dist/bundle/chunks/{chunk-L3V65XW7.js → chunk-CJWSQ6CK.js} +1 -1
- package/dist/bundle/chunks/{chunk-QLTQ3UUI.js → chunk-DAPBNRN5.js} +1 -1
- package/dist/bundle/chunks/{chunk-GIY7PGOH.js → chunk-DPBPO5OU.js} +1 -1
- package/dist/bundle/chunks/chunk-ESQBKTNG.js +2 -0
- package/dist/bundle/chunks/{chunk-N4TSAHRL.js → chunk-EVTTLPIY.js} +1 -1
- package/dist/bundle/chunks/{chunk-NYXXKS6D.js → chunk-F4OHTL2K.js} +3 -2
- package/dist/bundle/chunks/{chunk-TVMW2SUP.js → chunk-FJ2UCBOA.js} +2 -2
- package/dist/bundle/chunks/{chunk-KVPRQ5KN.js → chunk-FLM6GZPT.js} +1 -1
- package/dist/bundle/chunks/{chunk-P4AT7SBE.js → chunk-HBCNDC53.js} +1 -1
- package/dist/bundle/chunks/chunk-MOH5HOHX.js +2 -0
- package/dist/bundle/chunks/{chunk-7FUO655J.js → chunk-MOOFLKLI.js} +1 -1
- package/dist/bundle/chunks/{chunk-IHOQR7TU.js → chunk-PX7FF5LE.js} +1 -1
- package/dist/bundle/chunks/{chunk-QAM6AXA2.js → chunk-QTQ3ES2S.js} +12 -9
- package/dist/bundle/chunks/{chunk-FJSJUVQQ.js → chunk-TOOB6OLG.js} +3 -3
- package/dist/bundle/chunks/{chunk-662SCMTH.js → chunk-VPDQ6MOL.js} +1 -1
- package/dist/bundle/chunks/{chunk-BW4YXS7X.js → chunk-WCRNJYHO.js} +1 -1
- package/dist/bundle/chunks/{chunk-ZSVWKOAJ.js → chunk-ZNLCKKF6.js} +170 -226
- package/dist/bundle/chunks/{cli-main-534A3WSC.js → cli-main-XM5FWY3Z.js} +1 -1
- package/dist/bundle/chunks/{credential-accounts-OAK2E5O2.js → credential-accounts-YZYSKA7X.js} +1 -1
- package/dist/bundle/chunks/{health-write-EB4CPHXN.js → health-write-45CX64T2.js} +1 -1
- package/dist/bundle/chunks/{help-fast-path-U2PSNNWO.js → help-fast-path-3EDGRKQM.js} +1 -1
- package/dist/bundle/chunks/{host-command-WJIMRBGN.js → host-command-PZ4VYQIW.js} +1 -1
- package/dist/bundle/chunks/{host-session-command-PWVPQ2OV.js → host-session-command-OJFARE5Q.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-NPHFDPGH.js → interactive-mode-7JSJVVIS.js} +1 -1
- package/dist/bundle/chunks/{login-health-7G2DZVOV.js → login-health-YOPTYRTU.js} +1 -1
- package/dist/bundle/chunks/{main-I6FJAFUP.js → main-3YGJ2O4I.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-7E26R5JF.js → multi-session-host-N2RQ7JSZ.js} +4 -4
- package/dist/bundle/chunks/openai-chatgpt.js +1 -1
- package/dist/bundle/chunks/{openai-codex-responses-VNBMMIL3.js → openai-codex-responses-YTWLG4OL.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-JLR32APM.js → openai-completions-TIFDYHZL.js} +1 -1
- package/dist/bundle/chunks/{openai-images-LEBNERSM.js → openai-images-OAEMY4RG.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-JCDUNMHA.js → openai-responses-L35NIG5Y.js} +1 -1
- package/dist/bundle/chunks/{package-manager-cli-CBSDV36M.js → package-manager-cli-JPNA27E5.js} +1 -1
- package/dist/bundle/chunks/{role-LP6LVNCY.js → role-45Y7PQFC.js} +1 -1
- package/dist/bundle/chunks/{rotation-stream-ZDCNHIBE.js → rotation-stream-WXWJKJZN.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-GBBTN2WP.js → rpc-mode-Z7MN2ZWA.js} +1 -1
- package/dist/bundle/chunks/{run-attached-tui-PVLUHHJX.js → run-attached-tui-TI6MELEI.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-W45NYTTK.js → schedule-command-OZ5ESMIT.js} +1 -1
- package/dist/bundle/chunks/{session-control-endpoint-LFLUNALC.js → session-control-endpoint-5YKBYJOO.js} +1 -1
- package/dist/bundle/chunks/{session-picker-OZUINLD7.js → session-picker-CMRV72VA.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +324 -376
- package/dist/bundle/chunks/{state-store-SZARKD36.js → state-store-Q47AYMRI.js} +1 -1
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/bundle/runtime-manifest.json +1 -1
- package/dist/core/agent-session.d.ts +8 -0
- package/dist/core/agent-session.js +68 -60
- package/dist/core/credential-pool/classify.d.ts +3 -2
- package/dist/core/credential-pool/classify.js +10 -3
- package/dist/core/dynamic-prompt/build.d.ts +2 -1
- package/dist/core/dynamic-prompt/build.js +1 -2
- package/dist/core/dynamic-prompt/handoff.d.ts +1 -1
- package/dist/core/dynamic-prompt/handoff.js +9 -9
- package/dist/core/dynamic-prompt/identity.js +1 -1
- package/dist/core/dynamic-prompt/intent-gate.d.ts +1 -1
- package/dist/core/dynamic-prompt/intent-gate.js +8 -8
- package/dist/core/dynamic-prompt/policies.d.ts +1 -1
- package/dist/core/dynamic-prompt/policies.js +5 -7
- package/dist/core/dynamic-prompt/style.js +5 -5
- package/dist/core/dynamic-prompt/tool-section.d.ts +5 -0
- package/dist/core/dynamic-prompt/tool-section.js +8 -6
- package/dist/core/dynamic-prompt/verification.d.ts +6 -6
- package/dist/core/dynamic-prompt/verification.js +12 -12
- package/dist/core/dynamic-prompt/working-task.d.ts +1 -1
- package/dist/core/dynamic-prompt/working-task.js +3 -3
- package/dist/core/dynamic-prompt/workstation.js +1 -1
- package/dist/core/extensions/builtin/anthropic-subscription/session-registry-pump.d.ts +13 -0
- package/dist/core/extensions/builtin/anthropic-subscription/session-registry-pump.js +64 -2
- package/dist/core/extensions/builtin/anthropic-subscription/session-stream.js +5 -1
- package/dist/core/extensions/builtin/anthropic-subscription/session-turn-attempt.d.ts +7 -0
- package/dist/core/extensions/builtin/anthropic-subscription/session-turn-attempt.js +28 -1
- package/dist/core/extensions/builtin/anthropic-subscription/session-turn-types.d.ts +2 -0
- package/dist/core/extensions/builtin/bash-timeout/index.d.ts +1 -1
- package/dist/core/extensions/builtin/bash-timeout/index.js +3 -28
- package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts +0 -11
- package/dist/core/extensions/builtin/bash-timeout/timeout.js +0 -11
- package/dist/core/extensions/builtin/imagegen/index.d.ts +0 -1
- package/dist/core/extensions/builtin/imagegen/index.js +0 -11
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +5 -5
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +5 -5
- package/dist/core/extensions/builtin/prompt-preset/glm-5.d.ts +1 -1
- package/dist/core/extensions/builtin/prompt-preset/glm-5.js +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js +8 -1
- package/dist/core/extensions/builtin/terminal/notify.js +9 -3
- package/dist/core/extensions/builtin/terminal/prompt.d.ts +7 -1
- package/dist/core/extensions/builtin/terminal/prompt.js +27 -60
- package/dist/core/extensions/builtin/terminal/tools/bash.js +10 -2
- package/dist/core/extensions/builtin/todotools/normalize.d.ts +20 -3
- package/dist/core/extensions/builtin/todotools/normalize.js +251 -5
- package/dist/core/extensions/builtin/todotools/prompt.d.ts +2 -2
- package/dist/core/extensions/builtin/todotools/prompt.js +5 -5
- package/dist/core/extensions/builtin/todotools/tools/todo.js +9 -8
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.js +0 -5
- package/dist/core/extensions/builtin/websearch/index.js +9 -4
- package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts +2 -0
- package/dist/core/extensions/builtin/websearch/websearch/tool.js +3 -1
- package/dist/core/model-runtime.js +1 -1
- package/dist/core/provider-failure.d.ts +6 -0
- package/dist/core/provider-failure.js +6 -2
- package/dist/core/retry-fallback/exhaustion.d.ts +18 -0
- package/dist/core/retry-fallback/exhaustion.js +20 -0
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/tools/bash.d.ts +3 -1
- package/dist/core/tools/bash.js +14 -4
- package/dist/core/tools/edit.d.ts +1 -1
- package/dist/core/tools/edit.js +1 -6
- package/dist/core/tools/grep/index.js +2 -3
- package/dist/core/tools/powershell.d.ts +1 -1
- package/dist/core/tools/powershell.js +1 -1
- package/dist/core/tools/read.d.ts +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/write.d.ts +1 -1
- package/dist/core/tools/write.js +1 -1
- package/dist/engine-trust/shell-trust.d.ts +36 -0
- package/dist/engine-trust/shell-trust.js +44 -0
- package/dist/engine-trust/transport-failure.d.ts +12 -0
- package/dist/engine-trust/transport-failure.js +48 -0
- package/dist/modes/interactive/interactive-mode.js +9 -3
- package/dist/modes/print-mode.js +2 -1
- package/dist/modes/rpc/compact-catalog-families.d.ts +5 -2
- package/dist/modes/rpc/compact-catalog-families.js +5 -2
- package/dist/modes/rpc/compact-catalog-registry.d.ts +9 -1
- package/dist/modes/rpc/compact-catalog-registry.js +9 -2
- package/dist/modes/rpc/compact-recovery-manifest-kinds.d.ts +17 -0
- package/dist/modes/rpc/compact-recovery-manifest-kinds.js +21 -0
- package/dist/modes/rpc/compact-recovery-manifest-shape.d.ts +7 -0
- package/dist/modes/rpc/compact-recovery-manifest.js +11 -3
- package/dist/modes/rpc/compact-socket-commands.js +6 -0
- package/dist/modes/rpc/connection-handler.js +21 -5
- package/dist/modes/rpc/connection-question-bridge.d.ts +3 -1
- package/dist/modes/rpc/connection-question-bridge.js +4 -1
- package/dist/modes/rpc/connection-roles.d.ts +8 -0
- package/dist/modes/rpc/connection-roles.js +18 -0
- package/dist/modes/rpc/method-classes-schema-session.d.ts +4 -0
- package/dist/modes/rpc/method-classes-schema-session.js +1 -0
- package/dist/modes/rpc/method-classes-schema.d.ts +4 -0
- package/dist/modes/rpc/protocol-identity.js +2 -0
- package/dist/modes/rpc/remote-origin.d.ts +31 -0
- package/dist/modes/rpc/remote-origin.js +58 -0
- package/dist/modes/rpc/rpc-protocol-info-types.d.ts +8 -0
- package/dist/modes/rpc/rpc-question-types.d.ts +7 -0
- package/dist/modes/rpc/rpc-question-types.js +0 -3
- package/dist/modes/rpc/rpc-session-command-types.d.ts +3 -0
- package/dist/modes/rpc/session-registry.js +12 -3
- package/dist/modes/rpc/session-worker-client.js +2 -0
- package/dist/modes/rpc/session-worker-protocol.d.ts +3 -0
- package/dist/modes/rpc/session-worker.js +2 -0
- package/docs/engine-socket/fixtures/admission-routes/c-baseline.json +3 -3
- package/docs/engine-socket/fixtures/admission-routes/h-legacy.json +1 -1
- package/docs/engine-socket/fixtures/admission-routes/i-reset-stream.json +3 -3
- package/docs/engine-socket/fixtures/recovery-manifest/index.json +32 -0
- package/docs/engine-socket/fixtures/recovery-manifest/one-partial-family.json +118 -0
- package/docs/rpc.md +93 -3
- package/package.json +6 -6
- package/dist/bundle/chunks/chunk-7UC4W2T2.js +0 -2
- package/dist/bundle/chunks/chunk-R23WXN4L.js +0 -448
- package/dist/bundle/chunks/chunk-W5NLCRB3.js +0 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type RpcRemoteOrigin } from "./remote-origin.ts";
|
|
1
2
|
/**
|
|
2
3
|
* Connection roles (senpi#3811): the capabilities that say who a connection speaks for, which is what
|
|
3
4
|
* authority checks read. A role belongs to one connection, never to a session: a shared host serves every
|
|
@@ -16,12 +17,19 @@ export declare function roleConnection(connectionId: string | undefined): string
|
|
|
16
17
|
export declare const CONNECTION_ROLE_FIXED = "connection_role_fixed: interactive_user and task_parent cannot change after they are declared";
|
|
17
18
|
export declare class ConnectionRoles {
|
|
18
19
|
private readonly declared;
|
|
20
|
+
private readonly origins;
|
|
19
21
|
/** Records the roles a `set_client_info` carries; false when this connection already declared other roles. */
|
|
20
22
|
declare(connectionId: string, capabilities: readonly string[]): boolean;
|
|
21
23
|
/** The roles this connection explicitly declared, or undefined while it has declared none (no id = a stdio client). */
|
|
22
24
|
rolesOf(connectionId: string | undefined): readonly string[] | undefined;
|
|
23
25
|
/** Takes a declaration made elsewhere (the host, for a worker isolate) unless this connection already declared. */
|
|
24
26
|
adopt(connectionId: string, roles: readonly string[]): void;
|
|
27
|
+
/** Whether `origin` may be declared for this connection: none yet, or the same one again (senpi#5475). */
|
|
28
|
+
acceptsOrigin(connectionId: string, origin: RpcRemoteOrigin): boolean;
|
|
29
|
+
/** Records the remote device a connection speaks for; call only after `acceptsOrigin` allowed it. */
|
|
30
|
+
declareOrigin(connectionId: string, origin: RpcRemoteOrigin): void;
|
|
31
|
+
/** The remote device this connection declared it speaks for, or undefined for a local connection. */
|
|
32
|
+
originOf(connectionId: string | undefined): RpcRemoteOrigin | undefined;
|
|
25
33
|
has(connectionId: string | undefined, role: string): boolean;
|
|
26
34
|
release(connectionId: string): void;
|
|
27
35
|
/** Forgets every connection, for a worker isolate whose session ends. */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { INTERACTIVE_USER_CAPABILITY, TASK_PARENT_CAPABILITY } from "./custom-capability.js";
|
|
2
|
+
import { sameRemoteOrigin } from "./remote-origin.js";
|
|
2
3
|
/**
|
|
3
4
|
* Connection roles (senpi#3811): the capabilities that say who a connection speaks for, which is what
|
|
4
5
|
* authority checks read. A role belongs to one connection, never to a session: a shared host serves every
|
|
@@ -20,6 +21,7 @@ export const CONNECTION_ROLE_FIXED = "connection_role_fixed: interactive_user an
|
|
|
20
21
|
export class ConnectionRoles {
|
|
21
22
|
constructor() {
|
|
22
23
|
this.declared = new Map();
|
|
24
|
+
this.origins = new Map();
|
|
23
25
|
}
|
|
24
26
|
/** Records the roles a `set_client_info` carries; false when this connection already declared other roles. */
|
|
25
27
|
declare(connectionId, capabilities) {
|
|
@@ -39,15 +41,31 @@ export class ConnectionRoles {
|
|
|
39
41
|
if (!this.declared.has(connectionId))
|
|
40
42
|
this.declared.set(connectionId, [...roles]);
|
|
41
43
|
}
|
|
44
|
+
/** Whether `origin` may be declared for this connection: none yet, or the same one again (senpi#5475). */
|
|
45
|
+
acceptsOrigin(connectionId, origin) {
|
|
46
|
+
const prior = this.origins.get(connectionId);
|
|
47
|
+
return prior === undefined || sameRemoteOrigin(prior, origin);
|
|
48
|
+
}
|
|
49
|
+
/** Records the remote device a connection speaks for; call only after `acceptsOrigin` allowed it. */
|
|
50
|
+
declareOrigin(connectionId, origin) {
|
|
51
|
+
if (this.acceptsOrigin(connectionId, origin))
|
|
52
|
+
this.origins.set(connectionId, origin);
|
|
53
|
+
}
|
|
54
|
+
/** The remote device this connection declared it speaks for, or undefined for a local connection. */
|
|
55
|
+
originOf(connectionId) {
|
|
56
|
+
return this.origins.get(roleConnection(connectionId));
|
|
57
|
+
}
|
|
42
58
|
has(connectionId, role) {
|
|
43
59
|
return this.declared.get(roleConnection(connectionId))?.includes(role) ?? false;
|
|
44
60
|
}
|
|
45
61
|
release(connectionId) {
|
|
46
62
|
this.declared.delete(connectionId);
|
|
63
|
+
this.origins.delete(connectionId);
|
|
47
64
|
}
|
|
48
65
|
/** Forgets every connection, for a worker isolate whose session ends. */
|
|
49
66
|
clear() {
|
|
50
67
|
this.declared.clear();
|
|
68
|
+
this.origins.clear();
|
|
51
69
|
}
|
|
52
70
|
}
|
|
53
71
|
//# sourceMappingURL=connection-roles.js.map
|
|
@@ -923,6 +923,10 @@ export declare const SESSION_RECORD_SCHEMAS: {
|
|
|
923
923
|
} & {
|
|
924
924
|
readonly width: Type.TInteger;
|
|
925
925
|
readonly capabilities: Type.TOptional<Type.TArray<Type.TString>>;
|
|
926
|
+
readonly remoteOrigin: Type.TOptional<Type.TObject<{
|
|
927
|
+
deviceId: Type.TString;
|
|
928
|
+
deviceName: Type.TOptional<Type.TString>;
|
|
929
|
+
}>>;
|
|
926
930
|
}>;
|
|
927
931
|
};
|
|
928
932
|
//# sourceMappingURL=method-classes-schema-session.d.ts.map
|
|
@@ -198,6 +198,7 @@ const SURFACE_AND_ACCOUNT_SCHEMAS = {
|
|
|
198
198
|
set_client_info: session("set_client_info", {
|
|
199
199
|
width: Type.Integer({ minimum: 1, maximum: 100_000 }),
|
|
200
200
|
capabilities: Opt(Strings),
|
|
201
|
+
remoteOrigin: Opt(Type.Object({ deviceId: Id, deviceName: OptId }, { additionalProperties: false })),
|
|
201
202
|
}),
|
|
202
203
|
};
|
|
203
204
|
export const SESSION_RECORD_SCHEMAS = {
|
|
@@ -1268,6 +1268,10 @@ export declare const RPC_INBOUND_SCHEMAS: {
|
|
|
1268
1268
|
} & {
|
|
1269
1269
|
readonly width: import("typebox").TInteger;
|
|
1270
1270
|
readonly capabilities: import("typebox").TOptional<import("typebox").TArray<import("typebox").TString>>;
|
|
1271
|
+
readonly remoteOrigin: import("typebox").TOptional<import("typebox").TObject<{
|
|
1272
|
+
deviceId: import("typebox").TString;
|
|
1273
|
+
deviceName: import("typebox").TOptional<import("typebox").TString>;
|
|
1274
|
+
}>>;
|
|
1271
1275
|
}>;
|
|
1272
1276
|
};
|
|
1273
1277
|
export type RpcInboundValidation = {
|
|
@@ -19,6 +19,7 @@ import { parseArgs, resolveSessionRuntime } from "../../cli/args.js";
|
|
|
19
19
|
import { getAgentDir } from "../../config.js";
|
|
20
20
|
import { engineBuildIdentity } from "../../core/engine-build-identity.js";
|
|
21
21
|
import { HOST_GENERATION_ENV, HOST_INSTANCE_ID_ENV } from "./host-identity-env.js";
|
|
22
|
+
import { RPC_METHOD_CLASSES_DIGEST, RPC_METHOD_CLASSES_VERSION } from "./method-classes.js";
|
|
22
23
|
export { HOST_GENERATION_ENV, HOST_INSTANCE_ID_ENV };
|
|
23
24
|
/** Identity of THIS host process, fixed for its lifetime. */
|
|
24
25
|
const INSTANCE_ID = resolveInstanceId(process.env[HOST_INSTANCE_ID_ENV]);
|
|
@@ -69,6 +70,7 @@ export function protocolIdentity(agentDir = resolve(getAgentDir())) {
|
|
|
69
70
|
engineOrdinal: build.ordinal,
|
|
70
71
|
launch_profile: cachedProfile,
|
|
71
72
|
agentDir,
|
|
73
|
+
method_classes: { version: RPC_METHOD_CLASSES_VERSION, digest: RPC_METHOD_CLASSES_DIGEST },
|
|
72
74
|
};
|
|
73
75
|
}
|
|
74
76
|
//# sourceMappingURL=protocol-identity.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The remote device a connection speaks for (senpi#5475, omo-relay-daemon#184 P5).
|
|
3
|
+
*
|
|
4
|
+
* A relay forwarder opens one engine connection per remote sender and declares, through its own
|
|
5
|
+
* `set_client_info`, which device that connection speaks for. Every dialog a command of that connection raises
|
|
6
|
+
* then carries the value as `remoteOrigin`, so the host's desktop and TUI can label it "Requested from <device>".
|
|
7
|
+
* A connection that never declared one is local, and its dialogs carry no `remoteOrigin`. The engine copies only
|
|
8
|
+
* this declared value, never a free-form client name. `set_client_info` is `connection_local` in the method-class
|
|
9
|
+
* table, so a forwarded record can never set or change it.
|
|
10
|
+
*/
|
|
11
|
+
export interface RpcRemoteOrigin {
|
|
12
|
+
readonly deviceId: string;
|
|
13
|
+
readonly deviceName?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Validates a `set_client_info.remoteOrigin` against what the connection already declared, before anything of the
|
|
17
|
+
* declaration is committed: the origin to record (none when the field is absent), or the refusal to answer.
|
|
18
|
+
*/
|
|
19
|
+
export declare function remoteOriginDeclaration(value: unknown, accepts: (origin: RpcRemoteOrigin) => boolean): {
|
|
20
|
+
readonly origin: RpcRemoteOrigin | undefined;
|
|
21
|
+
} | {
|
|
22
|
+
readonly refusal: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function sameRemoteOrigin(a: RpcRemoteOrigin, b: RpcRemoteOrigin): boolean;
|
|
25
|
+
export declare function remoteOriginField(origin: RpcRemoteOrigin | undefined): {
|
|
26
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
27
|
+
};
|
|
28
|
+
export declare function originField(origin: RpcRemoteOrigin | undefined): {
|
|
29
|
+
origin?: RpcRemoteOrigin;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=remote-origin.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The remote device a connection speaks for (senpi#5475, omo-relay-daemon#184 P5).
|
|
3
|
+
*
|
|
4
|
+
* A relay forwarder opens one engine connection per remote sender and declares, through its own
|
|
5
|
+
* `set_client_info`, which device that connection speaks for. Every dialog a command of that connection raises
|
|
6
|
+
* then carries the value as `remoteOrigin`, so the host's desktop and TUI can label it "Requested from <device>".
|
|
7
|
+
* A connection that never declared one is local, and its dialogs carry no `remoteOrigin`. The engine copies only
|
|
8
|
+
* this declared value, never a free-form client name. `set_client_info` is `connection_local` in the method-class
|
|
9
|
+
* table, so a forwarded record can never set or change it.
|
|
10
|
+
*/
|
|
11
|
+
const MAX_DEVICE_ID_CHARACTERS = 256;
|
|
12
|
+
const MAX_DEVICE_NAME_CHARACTERS = 256;
|
|
13
|
+
const REMOTE_ORIGIN_INVALID = "remote_origin_invalid: remoteOrigin must be { deviceId: non-empty string, deviceName?: non-empty string }";
|
|
14
|
+
const REMOTE_ORIGIN_FIXED = "remote_origin_fixed: a connection's remoteOrigin cannot change after it is declared";
|
|
15
|
+
function boundedText(value, max) {
|
|
16
|
+
return typeof value === "string" && value.length > 0 && value.length <= max;
|
|
17
|
+
}
|
|
18
|
+
/** The declared origin, `undefined` when the field is absent, or `"invalid"` for any other shape. */
|
|
19
|
+
function parseRemoteOrigin(value) {
|
|
20
|
+
if (value === undefined)
|
|
21
|
+
return undefined;
|
|
22
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
23
|
+
return "invalid";
|
|
24
|
+
const deviceId = Reflect.get(value, "deviceId");
|
|
25
|
+
const deviceName = Reflect.get(value, "deviceName");
|
|
26
|
+
const keys = Object.keys(value);
|
|
27
|
+
if (keys.some((key) => key !== "deviceId" && key !== "deviceName"))
|
|
28
|
+
return "invalid";
|
|
29
|
+
if (!boundedText(deviceId, MAX_DEVICE_ID_CHARACTERS))
|
|
30
|
+
return "invalid";
|
|
31
|
+
if (deviceName === undefined)
|
|
32
|
+
return { deviceId };
|
|
33
|
+
if (!boundedText(deviceName, MAX_DEVICE_NAME_CHARACTERS))
|
|
34
|
+
return "invalid";
|
|
35
|
+
return { deviceId, deviceName };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Validates a `set_client_info.remoteOrigin` against what the connection already declared, before anything of the
|
|
39
|
+
* declaration is committed: the origin to record (none when the field is absent), or the refusal to answer.
|
|
40
|
+
*/
|
|
41
|
+
export function remoteOriginDeclaration(value, accepts) {
|
|
42
|
+
const origin = parseRemoteOrigin(value);
|
|
43
|
+
if (origin === "invalid")
|
|
44
|
+
return { refusal: REMOTE_ORIGIN_INVALID };
|
|
45
|
+
if (origin !== undefined && !accepts(origin))
|
|
46
|
+
return { refusal: REMOTE_ORIGIN_FIXED };
|
|
47
|
+
return { origin };
|
|
48
|
+
}
|
|
49
|
+
export function sameRemoteOrigin(a, b) {
|
|
50
|
+
return a.deviceId === b.deviceId && a.deviceName === b.deviceName;
|
|
51
|
+
}
|
|
52
|
+
export function remoteOriginField(origin) {
|
|
53
|
+
return origin === undefined ? {} : { remoteOrigin: origin };
|
|
54
|
+
}
|
|
55
|
+
export function originField(origin) {
|
|
56
|
+
return origin === undefined ? {} : { origin };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=remote-origin.js.map
|
|
@@ -33,6 +33,14 @@ export interface RpcProtocolIdentity {
|
|
|
33
33
|
readonly launch_profile: RpcLaunchProfile;
|
|
34
34
|
/** Absolute agent directory this host reads and writes; a handoff from another agent dir is refused. */
|
|
35
35
|
readonly agentDir: string;
|
|
36
|
+
/**
|
|
37
|
+
* The inbound method-class table this engine runs (`method-classes.ts`): a remote forwarder classifies with its
|
|
38
|
+
* own copy only while that copy's digest equals `digest`.
|
|
39
|
+
*/
|
|
40
|
+
readonly method_classes: {
|
|
41
|
+
readonly version: number;
|
|
42
|
+
readonly digest: string;
|
|
43
|
+
};
|
|
36
44
|
}
|
|
37
45
|
export interface RpcProtocolInfo extends RpcProtocolIdentity {
|
|
38
46
|
/** Present only on a public POSIX endpoint's answer to a challenge (wire contract v1.1). */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RpcRemoteOrigin } from "./remote-origin.ts";
|
|
1
2
|
/** One question in an RPC `question` UI request. Matches canonical QuestionRequest.questions. */
|
|
2
3
|
export type RpcQuestionSpec = {
|
|
3
4
|
id: string;
|
|
@@ -25,6 +26,8 @@ export type RpcQuestionUiRequest = {
|
|
|
25
26
|
questions: RpcQuestionSpec[];
|
|
26
27
|
/** The connection whose command raised the question, or `"agent"` when no connection's command was dispatching. */
|
|
27
28
|
raisedBy?: string;
|
|
29
|
+
/** The remote device the raising connection speaks for (senpi#5475); absent for a local connection. */
|
|
30
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
28
31
|
timeout: number;
|
|
29
32
|
askedAtMs: number;
|
|
30
33
|
deadlineAtMs: number;
|
|
@@ -35,6 +38,7 @@ export type RpcExtensionUIRequest = {
|
|
|
35
38
|
type: "extension_ui_request";
|
|
36
39
|
id: string;
|
|
37
40
|
method: "select";
|
|
41
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
38
42
|
/** Permanent MCP env grant; only a grant_select presentation may answer. */
|
|
39
43
|
grantSelect?: boolean;
|
|
40
44
|
title: string;
|
|
@@ -50,10 +54,12 @@ export type RpcExtensionUIRequest = {
|
|
|
50
54
|
title: string;
|
|
51
55
|
message: string;
|
|
52
56
|
timeout?: number;
|
|
57
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
53
58
|
} | {
|
|
54
59
|
type: "extension_ui_request";
|
|
55
60
|
id: string;
|
|
56
61
|
method: "input";
|
|
62
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
57
63
|
secret?: boolean;
|
|
58
64
|
deadlineAtMs?: number;
|
|
59
65
|
title: string;
|
|
@@ -67,6 +73,7 @@ export type RpcExtensionUIRequest = {
|
|
|
67
73
|
method: "editor";
|
|
68
74
|
title: string;
|
|
69
75
|
prefill?: string;
|
|
76
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
70
77
|
} | {
|
|
71
78
|
type: "extension_ui_request";
|
|
72
79
|
id: string;
|
|
@@ -6,6 +6,7 @@ import type { ClientMessageIdentity } from "../../core/client-message-identity.t
|
|
|
6
6
|
import type { SessionEntry } from "../../core/session-manager.ts";
|
|
7
7
|
import type { ToolBarrierSpec } from "../../core/tool-barrier.ts";
|
|
8
8
|
import type { RpcRecoveryCommand } from "./rpc-recovery-command-types.ts";
|
|
9
|
+
import type { RpcRemoteOrigin } from "./remote-origin.ts";
|
|
9
10
|
import type { RpcSessionModelEntry } from "./rpc-session-state-types.ts";
|
|
10
11
|
export type RpcSessionCommand = {
|
|
11
12
|
id?: string;
|
|
@@ -521,6 +522,8 @@ export type RpcSessionCommand = {
|
|
|
521
522
|
type: "set_client_info";
|
|
522
523
|
width: number;
|
|
523
524
|
capabilities?: string[];
|
|
525
|
+
/** Declared by a relay forwarder for the remote device this connection speaks for (senpi#5475). */
|
|
526
|
+
remoteOrigin?: RpcRemoteOrigin;
|
|
524
527
|
};
|
|
525
528
|
/** What `steer`/`follow_up` do on an idle session: queue (default) or start a turn. */
|
|
526
529
|
export type RpcWhenIdle = "queue" | "start";
|
|
@@ -4,7 +4,7 @@ import { createRegistryWarm } from "./host-warm.js";
|
|
|
4
4
|
import { refreshesSessionActivity } from "./session-command-activity.js";
|
|
5
5
|
import { publishedSessionContext } from "./session-context-patch.js";
|
|
6
6
|
import { attachLiveSession, markPathAttached } from "./session-live-attachment.js";
|
|
7
|
-
import { syncRuntimeMetadata } from "./session-registry-claims.js";
|
|
7
|
+
import { beginPendingClaim, syncRuntimeMetadata } from "./session-registry-claims.js";
|
|
8
8
|
import { openRegistrySession } from "./session-registry-open.js";
|
|
9
9
|
import { RpcSessionRegistryError, } from "./session-registry-types.js";
|
|
10
10
|
import { beginSessionClose, closeMarkedSession, closeSession } from "./session-teardown.js";
|
|
@@ -44,8 +44,17 @@ export class RpcSessionRegistry {
|
|
|
44
44
|
return deleted;
|
|
45
45
|
},
|
|
46
46
|
releaseReservation: async (key) => {
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
// Close may finish at its grace deadline before removal settles. Keep
|
|
48
|
+
// that work visible to reopen even after the closing entry is gone. A failed removal
|
|
49
|
+
// still gives the path back: no entry is left to ever release it later.
|
|
50
|
+
const settle = beginPendingClaim(this.pendingClaims, key);
|
|
51
|
+
try {
|
|
52
|
+
await this.options.pathReservations?.release(key);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
this.reservations.delete(key);
|
|
56
|
+
settle();
|
|
57
|
+
}
|
|
49
58
|
},
|
|
50
59
|
markDetached: (key) => this.options.pathReservations?.setAttached(key, false),
|
|
51
60
|
now: () => this.now(),
|
|
@@ -5,6 +5,7 @@ import { createWebViewBroker } from "../../core/webview/webview-broker.js";
|
|
|
5
5
|
import { workerCapabilities } from "./worker-client-capabilities.js";
|
|
6
6
|
import { captureAdmissionReply, withAdmissionReply } from "./compact-admission-reply.js";
|
|
7
7
|
import { roleConnection } from "./connection-roles.js";
|
|
8
|
+
import { originField } from "./remote-origin.js";
|
|
8
9
|
import { answeredUiRequestId, isGrantSelectRequest, refusedExtensionUiResponse } from "./extension-ui-response.js";
|
|
9
10
|
import { enqueueLegacyRecord } from "./legacy-record-depth.js";
|
|
10
11
|
import { SessionAcceptanceLane } from "./session-acceptance-lane.js";
|
|
@@ -199,6 +200,7 @@ export class SessionWorkerClient {
|
|
|
199
200
|
command,
|
|
200
201
|
connection,
|
|
201
202
|
roles: options.connectionRoles?.rolesOf(roleConnection(connection)),
|
|
203
|
+
...originField(options.connectionRoles?.originOf(connection)),
|
|
202
204
|
...(owner === undefined ? {} : { owner }),
|
|
203
205
|
});
|
|
204
206
|
},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RpcRemoteOrigin } from "./remote-origin.ts";
|
|
1
2
|
import type { BrowserEngine } from "../../core/browser-engine.ts";
|
|
2
3
|
import type { McpFormInput, McpFormOutcome } from "../../core/mcp-form-types.ts";
|
|
3
4
|
import type { RecoveryCarrier } from "../../core/session-recovery-identity.ts";
|
|
@@ -96,6 +97,8 @@ export type HostToSessionWorker = {
|
|
|
96
97
|
command: object;
|
|
97
98
|
connection?: string;
|
|
98
99
|
roles?: readonly string[];
|
|
100
|
+
/** The remote device the connection declared on the host (senpi#5475); the isolate adopts it. */
|
|
101
|
+
origin?: RpcRemoteOrigin;
|
|
99
102
|
/** The gate the host captured at ingress, before its first await (#4728). */
|
|
100
103
|
owner?: ExtensionOwnerWire;
|
|
101
104
|
}
|
|
@@ -338,6 +338,8 @@ async function handle(message) {
|
|
|
338
338
|
throw new Error("session_closing");
|
|
339
339
|
if (message.roles !== undefined)
|
|
340
340
|
connectionRoles.adopt(roleConnection(message.connection), message.roles);
|
|
341
|
+
if (message.origin !== undefined)
|
|
342
|
+
connectionRoles.declareOrigin(roleConnection(message.connection), message.origin);
|
|
341
343
|
const activeBinding = binding;
|
|
342
344
|
const run = () => activeBinding.handle(message.command);
|
|
343
345
|
await workerAdmissionCommand(message, writer, issuedOwners, run);
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"hint": "restart_from_catalog",
|
|
44
44
|
"retryAfterMs": 0
|
|
45
45
|
},
|
|
46
|
-
"length":
|
|
47
|
-
"digest": "
|
|
48
|
-
"bytes": "
|
|
46
|
+
"length": 1230,
|
|
47
|
+
"digest": "afc0506ef0b5e09ae70818c0b435b2fa633d3536d44f6e357950aad78d0102f9",
|
|
48
|
+
"bytes": "ewAiAGYAbwByAG0AYQB0ACIAOgAiAHMAZQBuAHAAaQAtAHIAZQBjAG8AdgBlAHIAeQAtAG0AYQBuAGkAZgBlAHMAdAAiACwAIgB2AGUAcgBzAGkAbwBuACIAOgAxACwAIgBzAG8AYwBrAGUAdABFAHAAbwBjAGgAIgA6AHsAIgBpAGQAIgA6ACIAcwBvAGMAawBlAHQALQAxACIAfQAsACIAYQBkAG0AaQBzAHMAaQBvAG4ASQBkACIAOgB7ACIAaQBkACIAOgAiAGcAbwBsAGQAZQBuAC0AYQAiAH0ALAAiAHIAbwB1AHQAZQBLAGkAbgBkACIAOgAiAG8AcgBkAGkAbgBhAHIAeQAiACwAIgBzAGUAcwBzAGkAbwBuACIAOgB7ACIAaQBkACIAOgAiAHIAcABjAC0AMQAiAH0ALAAiAHMAZQBzAHMAaQBvAG4ARQBwAG8AYwBoACIAOgB7ACIAaQBkACIAOgAiADAAMAAwADAAMAAwADAAMAAtADAAMAAwADAALQA0ADAAMAAwAC0AOAAwADAAMAAtADAAMAAwADAAMAAwADAAMAAwADAAMAAxACIAfQAsACIAZwBlAG4AZQByAGEAdABpAG8AbgAiADoAMQAsACIAcwBlAHEAdQBlAG4AYwBlACIAOgAwACwAIgBoAGkAcwB0AG8AcgB5AFYAZQByAHMAaQBvAG4AIgA6ADUALAAiAHQAbwBrAGUAbgAiADoAewAiAGkAZAAiADoAIgBzAG8AYwBrAGUAdAAtADEAOgAxACIAfQAsACIAbABlAGEAZgAiADoAewAiAGkAZAAiADoAIgAwADAAMAAwADAAMAAwADEAIgB9ACwAIgBhAGMAdABpAHYAZQBNAGUAcwBzAGEAZwBlACIAOgBuAHUAbABsACwAIgB0AHUAcgBuACIAOgBuAHUAbABsACwAIgBjAGgAZQBjAGsAcABvAGkAbgB0AEQAaQBnAGUAcwB0ACIAOgAiADEAYgBiAGMAYQBkADIAOQAzADIAMABmADIAMAA4ADQANwBhADUAMQA1AGMAYwA4ADUANAAwADYAMwBjAGQAYQAwAGQAZABhAGUAYQAyADAAYwBkAGMAZgBmADQANQBlAGIANgBiADUAZQAwAGUAOQBlAGUAMQA1AGYAYgBkADQAIgAsACIAYwBhAHQAYQBsAG8AZwBSAG8AbwB0ACIAOgAiAGMALQAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAxACIALAAiAGMAYQB0AGEAbABvAGcAUgBvAG8AdABMAGUAbgBnAHQAaAAiADoAMwA5ADQANgAsACIAcgBlAHEAdQBpAHIAZQBkAEsAaQBuAGQAcwAiADoAWwAiAGEAYwB0AGkAdgBlACIALAAiAGMAYQBsAGwAcwAiACwAIgBkAGkAYQBsAG8AZwBzACIALAAiAGkAZABlAG4AdABpAHQAeQAiACwAIgBsAGkAZgBlAGMAeQBjAGwAZQAiACwAIgBvAHAAYQBxAHUAZQAiACwAIgByAHUAbgAiACwAIgBzAGUAdAB0AGwAZQBkACIALAAiAHMAbwB1AHIAYwBlACIALAAiAHQAcgBhAG4AcwBjAHIAaQBwAHQAIgBdAH0A"
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"rpcClientRequests": "{\"type\":\"get_protocol_info\",\"id\":\"rpc-auth-protocol\",\"observe\":true,\"auth\":{\"client_nonce\":\"<public-nonce>\"}}\n{\"type\":\"set_client_info\",\"width\":100,\"capabilities\":[],\"id\":\"req_1\"}\n{\"type\":\"open_session\",\"cwd\":\"<root>/cwd\",\"sessionPath\":\"<root>/cwd/session.jsonl\",\"id\":\"req_2\"}\n{\"type\":\"get_entries\",\"sessionId\":\"rpc-1\",\"id\":\"req_3\"}\n{\"type\":\"close_session\",\"sessionId\":\"rpc-1\",\"id\":\"req_4\"}\n",
|
|
3
|
-
"rpcClientFrames": "{\"id\":\"rpc-auth-protocol\",\"type\":\"response\",\"command\":\"get_protocol_info\",\"success\":true,\"data\":{\"protocolVersion\":1,\"serverVersion\":\"<server-version>\",\"capabilities\":[\"<capabilities>\"],\"mode\":\"multi\",\"instanceId\":\"<uuid-1>\",\"generation\":0,\"engineVersion\":\"<server-version>\",\"engineOrdinal\":\"<engine-ordinal>\",\"launch_profile\":{\"profile_id\":\"ca7a49435f02009fdda5dac49d29408dcfeb1ab5374353784c5a9def467f5be1\",\"core\":{\"extensions\":[],\"multi_session\":false,\"session_runtime\":\"worker\"}},\"agentDir\":\"<root>/agent\",\"memory_pressure\":false,\"path_identity_resolver\":{\"state\":\"not_started\",\"detail\":null}}}\n{\"id\":\"req_1\",\"type\":\"response\",\"command\":\"set_client_info\",\"success\":true}\n{\"type\":\"queued\",\"for_request\":\"req_2\",\"position\":1,\"in_flight\":0}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-2>\",\"method\":\"setWidget\",\"widgetKey\":\"todo-sidebar\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-3>\",\"method\":\"setStatus\",\"statusKey\":\"anthropic-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-4>\",\"method\":\"setWidget\",\"widgetKey\":\"anthropic-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-5>\",\"method\":\"setStatus\",\"statusKey\":\"openai-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-6>\",\"method\":\"setWidget\",\"widgetKey\":\"openai-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-7>\",\"method\":\"setStatus\",\"statusKey\":\"monitors\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-8>\",\"method\":\"setStatus\",\"statusKey\":\"pi-websearch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-9>\",\"method\":\"setWidget\",\"widgetKey\":\"pi-websearch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-10>\",\"method\":\"setStatus\",\"statusKey\":\"pi-webfetch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-11>\",\"method\":\"setWidget\",\"widgetKey\":\"pi-webfetch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"entry_appended\",\"entry\":{\"type\":\"custom\",\"customType\":\"pi-rules.scan\",\"data\":{\"cwd\":\"<root>/cwd\",\"reason\":\"startup\"},\"startupBookkeeping\":true,\"id\":\"<entry-1>\",\"parentId\":\"<entry-2>\",\"timestamp\":\"2026-10-29T00:00:00.000Z\"},\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-12>\",\"method\":\"setStatus\",\"statusKey\":\"todo-waiting\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-13>\",\"method\":\"setStatus\",\"statusKey\":\"goal\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"session_opened\",\"sessionId\":\"rpc-1\",\"durableSessionId\":\"<uuid-14>\",\"sessionPath\":\"<root>/cwd/session.jsonl\",\"kind\":\"interactive\",\"cwd\":\"<root>/cwd\"}\n{\"id\":\"req_2\",\"type\":\"response\",\"command\":\"open_session\",\"success\":true,\"data\":{\"sessionId\":\"rpc-1\",\"state\":{\"answeredUiRequests\":[],\"paused\":false,\"pausedNoticeCount\":0,\"holds\":[],\"lifecycle\":{\"state\":\"done\",\"seq\":0,\"epoch\":0,\"epochOrigin\":\"automatic\",\"humanInputRevision\":0,\"selfSettleEligible\":true,\"restoring\":false,\"persisted\":false,\"runPaused\":false,\"since\":\"2026-10-29T00:00:00.000Z\",\"role\":\"root\",\"rootSessionId\":\"<uuid-14>\",\"activityRevision\":{\"instanceId\":\"<uuid-15>\",\"revision\":0},\"waitingOn\":{\"children\":0,\"background\":[],\"human\":[]},\"holds\":[],\"observedAt\":\"2026-10-29T00:00:00.000Z\"},\"pendingQuestions\":[],\"pendingDialogs\":[],\"model\":{\"id\":\"faux-a\",\"name\":\"faux-a\",\"api\":\"faux:fixture\",\"provider\":\"faux\",\"baseUrl\":\"http://localhost:0\",\"reasoning\":false,\"input\":[\"text\",\"image\"],\"cost\":{\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0},\"contextWindow\":128000,\"maxTokens\":16384},\"pendingModelSwitch\":null,\"thinkingLevel\":\"off\",\"thinkingLevelSource\":\"default\",\"sessionModelThinkingLevels\":{\"faux/faux-a\":\"off\"},\"fastMode\":false,\"isStreaming\":false,\"pausedHeldInputCount\":0,\"runPaused\":false,\"pause\":{\"pauseSeq\":0,\"records\":[]},\"isCompacting\":false,\"retryAttempt\":0,\"isBashRunning\":false,\"steeringMode\":\"all\",\"followUpMode\":\"one-at-a-time\",\"sessionFile\":\"<root>/cwd/session.jsonl\",\"sessionId\":\"<uuid-14>\",\"cwd\":\"<root>/cwd\",\"projectTrusted\":false,\"entries\":[{\"type\":\"model_change\",\"id\":\"<entry-3>\",\"parentId\":null,\"timestamp\":\"2026-10-29T00:00:00.000Z\",\"provider\":\"faux\",\"modelId\":\"faux-a\"},{\"type\":\"thinking_level_change\",\"id\":\"<entry-2>\",\"parentId\":\"<entry-3>\",\"timestamp\":\"2026-10-29T00:00:00.000Z\",\"thinkingLevel\":\"off\",\"provider\":\"faux\",\"modelId\":\"faux-a\"},{\"type\":\"custom\",\"customType\":\"pi-rules.scan\",\"data\":{\"cwd\":\"<root>/cwd\",\"reason\":\"startup\"},\"startupBookkeeping\":true,\"id\":\"<entry-1>\",\"parentId\":\"<entry-2>\",\"timestamp\":\"2026-10-29T00:00:00.000Z\"}],\"steering\":[],\"followUp\":[],\"ordered\":[],\"autoCompactionEnabled\":true,\"messageCount\":0,\"pendingMessageCount\":0,\"usageTotals\":{\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0,\"cost\":0},\"contextUsage\":{\"tokens\":0,\"contextWindow\":128000,\"percent\":0},\"favoriteModels\":[],\"scopedModels\":[]}},\"sessionId\":\"rpc-1\"}\n{\"id\":\"req_3\",\"type\":\"response\",\"command\":\"get_entries\",\"success\":true,\"data\":{\"entries\":[{\"type\":\"model_change\",\"id\":\"<entry-3>\",\"parentId\":null,\"timestamp\":\"2026-10-29T00:00:00.000Z\",\"provider\":\"faux\",\"modelId\":\"faux-a\"},{\"type\":\"thinking_level_change\",\"id\":\"<entry-2>\",\"parentId\":\"<entry-3>\",\"timestamp\":\"2026-10-29T00:00:00.000Z\",\"thinkingLevel\":\"off\",\"provider\":\"faux\",\"modelId\":\"faux-a\"},{\"type\":\"custom\",\"customType\":\"pi-rules.scan\",\"data\":{\"cwd\":\"<root>/cwd\",\"reason\":\"startup\"},\"startupBookkeeping\":true,\"id\":\"<entry-1>\",\"parentId\":\"<entry-2>\",\"timestamp\":\"2026-10-29T00:00:00.000Z\"}],\"leafId\":\"<entry-1>\"},\"sessionId\":\"rpc-1\"}\n{\"type\":\"session_closed\",\"sessionId\":\"rpc-1\",\"reason\":\"client_close\"}\n{\"id\":\"req_4\",\"type\":\"response\",\"command\":\"close_session\",\"success\":true,\"data\":{},\"sessionId\":\"rpc-1\"}\n",
|
|
3
|
+
"rpcClientFrames": "{\"id\":\"rpc-auth-protocol\",\"type\":\"response\",\"command\":\"get_protocol_info\",\"success\":true,\"data\":{\"protocolVersion\":1,\"serverVersion\":\"<server-version>\",\"capabilities\":[\"<capabilities>\"],\"mode\":\"multi\",\"instanceId\":\"<uuid-1>\",\"generation\":0,\"engineVersion\":\"<server-version>\",\"engineOrdinal\":\"<engine-ordinal>\",\"launch_profile\":{\"profile_id\":\"ca7a49435f02009fdda5dac49d29408dcfeb1ab5374353784c5a9def467f5be1\",\"core\":{\"extensions\":[],\"multi_session\":false,\"session_runtime\":\"worker\"}},\"agentDir\":\"<root>/agent\",\"method_classes\":{\"version\":1,\"digest\":\"71d6846585dffea212d60019e24296f5cd2882c0e8ff54b4d6e40cef3945b80a\"},\"memory_pressure\":false,\"path_identity_resolver\":{\"state\":\"not_started\",\"detail\":null}}}\n{\"id\":\"req_1\",\"type\":\"response\",\"command\":\"set_client_info\",\"success\":true}\n{\"type\":\"queued\",\"for_request\":\"req_2\",\"position\":1,\"in_flight\":0}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-2>\",\"method\":\"setWidget\",\"widgetKey\":\"todo-sidebar\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-3>\",\"method\":\"setStatus\",\"statusKey\":\"anthropic-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-4>\",\"method\":\"setWidget\",\"widgetKey\":\"anthropic-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-5>\",\"method\":\"setStatus\",\"statusKey\":\"openai-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-6>\",\"method\":\"setWidget\",\"widgetKey\":\"openai-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-7>\",\"method\":\"setStatus\",\"statusKey\":\"monitors\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-8>\",\"method\":\"setStatus\",\"statusKey\":\"pi-websearch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-9>\",\"method\":\"setWidget\",\"widgetKey\":\"pi-websearch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-10>\",\"method\":\"setStatus\",\"statusKey\":\"pi-webfetch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-11>\",\"method\":\"setWidget\",\"widgetKey\":\"pi-webfetch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"entry_appended\",\"entry\":{\"type\":\"custom\",\"customType\":\"pi-rules.scan\",\"data\":{\"cwd\":\"<root>/cwd\",\"reason\":\"startup\"},\"startupBookkeeping\":true,\"id\":\"<entry-1>\",\"parentId\":\"<entry-2>\",\"timestamp\":\"2026-10-29T00:00:00.000Z\"},\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-12>\",\"method\":\"setStatus\",\"statusKey\":\"todo-waiting\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-13>\",\"method\":\"setStatus\",\"statusKey\":\"goal\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"session_opened\",\"sessionId\":\"rpc-1\",\"durableSessionId\":\"<uuid-14>\",\"sessionPath\":\"<root>/cwd/session.jsonl\",\"kind\":\"interactive\",\"cwd\":\"<root>/cwd\"}\n{\"id\":\"req_2\",\"type\":\"response\",\"command\":\"open_session\",\"success\":true,\"data\":{\"sessionId\":\"rpc-1\",\"state\":{\"answeredUiRequests\":[],\"paused\":false,\"pausedNoticeCount\":0,\"holds\":[],\"lifecycle\":{\"state\":\"done\",\"seq\":0,\"epoch\":0,\"epochOrigin\":\"automatic\",\"humanInputRevision\":0,\"selfSettleEligible\":true,\"restoring\":false,\"persisted\":false,\"runPaused\":false,\"since\":\"2026-10-29T00:00:00.000Z\",\"role\":\"root\",\"rootSessionId\":\"<uuid-14>\",\"activityRevision\":{\"instanceId\":\"<uuid-15>\",\"revision\":0},\"waitingOn\":{\"children\":0,\"background\":[],\"human\":[]},\"holds\":[],\"observedAt\":\"2026-10-29T00:00:00.000Z\"},\"pendingQuestions\":[],\"pendingDialogs\":[],\"model\":{\"id\":\"faux-a\",\"name\":\"faux-a\",\"api\":\"faux:fixture\",\"provider\":\"faux\",\"baseUrl\":\"http://localhost:0\",\"reasoning\":false,\"input\":[\"text\",\"image\"],\"cost\":{\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0},\"contextWindow\":128000,\"maxTokens\":16384},\"pendingModelSwitch\":null,\"thinkingLevel\":\"off\",\"thinkingLevelSource\":\"default\",\"sessionModelThinkingLevels\":{\"faux/faux-a\":\"off\"},\"fastMode\":false,\"isStreaming\":false,\"pausedHeldInputCount\":0,\"runPaused\":false,\"pause\":{\"pauseSeq\":0,\"records\":[]},\"isCompacting\":false,\"retryAttempt\":0,\"isBashRunning\":false,\"steeringMode\":\"all\",\"followUpMode\":\"one-at-a-time\",\"sessionFile\":\"<root>/cwd/session.jsonl\",\"sessionId\":\"<uuid-14>\",\"cwd\":\"<root>/cwd\",\"projectTrusted\":false,\"entries\":[{\"type\":\"model_change\",\"id\":\"<entry-3>\",\"parentId\":null,\"timestamp\":\"2026-10-29T00:00:00.000Z\",\"provider\":\"faux\",\"modelId\":\"faux-a\"},{\"type\":\"thinking_level_change\",\"id\":\"<entry-2>\",\"parentId\":\"<entry-3>\",\"timestamp\":\"2026-10-29T00:00:00.000Z\",\"thinkingLevel\":\"off\",\"provider\":\"faux\",\"modelId\":\"faux-a\"},{\"type\":\"custom\",\"customType\":\"pi-rules.scan\",\"data\":{\"cwd\":\"<root>/cwd\",\"reason\":\"startup\"},\"startupBookkeeping\":true,\"id\":\"<entry-1>\",\"parentId\":\"<entry-2>\",\"timestamp\":\"2026-10-29T00:00:00.000Z\"}],\"steering\":[],\"followUp\":[],\"ordered\":[],\"autoCompactionEnabled\":true,\"messageCount\":0,\"pendingMessageCount\":0,\"usageTotals\":{\"input\":0,\"output\":0,\"cacheRead\":0,\"cacheWrite\":0,\"cost\":0},\"contextUsage\":{\"tokens\":0,\"contextWindow\":128000,\"percent\":0},\"favoriteModels\":[],\"scopedModels\":[]}},\"sessionId\":\"rpc-1\"}\n{\"id\":\"req_3\",\"type\":\"response\",\"command\":\"get_entries\",\"success\":true,\"data\":{\"entries\":[{\"type\":\"model_change\",\"id\":\"<entry-3>\",\"parentId\":null,\"timestamp\":\"2026-10-29T00:00:00.000Z\",\"provider\":\"faux\",\"modelId\":\"faux-a\"},{\"type\":\"thinking_level_change\",\"id\":\"<entry-2>\",\"parentId\":\"<entry-3>\",\"timestamp\":\"2026-10-29T00:00:00.000Z\",\"thinkingLevel\":\"off\",\"provider\":\"faux\",\"modelId\":\"faux-a\"},{\"type\":\"custom\",\"customType\":\"pi-rules.scan\",\"data\":{\"cwd\":\"<root>/cwd\",\"reason\":\"startup\"},\"startupBookkeeping\":true,\"id\":\"<entry-1>\",\"parentId\":\"<entry-2>\",\"timestamp\":\"2026-10-29T00:00:00.000Z\"}],\"leafId\":\"<entry-1>\"},\"sessionId\":\"rpc-1\"}\n{\"type\":\"session_closed\",\"sessionId\":\"rpc-1\",\"reason\":\"client_close\"}\n{\"id\":\"req_4\",\"type\":\"response\",\"command\":\"close_session\",\"success\":true,\"data\":{},\"sessionId\":\"rpc-1\"}\n",
|
|
4
4
|
"subscribeRequests": "{\"type\":\"subscribe_sessions\",\"mirror\":\"all\",\"id\":\"subscriber-1\"}\n{\"type\":\"unsubscribe_sessions\",\"subscriptionId\":\"sub-1\",\"id\":\"subscriber-2\"}\n",
|
|
5
5
|
"subscribeFrames": "{\"id\":\"subscriber-1\",\"type\":\"response\",\"command\":\"subscribe_sessions\",\"success\":true,\"data\":{\"subscriptionId\":\"sub-1\",\"snapshot\":[],\"seq\":0,\"hostGeneration\":\"0\",\"hostInstanceId\":\"<uuid-1>\"}}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-2>\",\"method\":\"setWidget\",\"widgetKey\":\"todo-sidebar\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-3>\",\"method\":\"setStatus\",\"statusKey\":\"anthropic-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-4>\",\"method\":\"setWidget\",\"widgetKey\":\"anthropic-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-5>\",\"method\":\"setStatus\",\"statusKey\":\"openai-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-6>\",\"method\":\"setWidget\",\"widgetKey\":\"openai-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-7>\",\"method\":\"setStatus\",\"statusKey\":\"monitors\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-8>\",\"method\":\"setStatus\",\"statusKey\":\"pi-websearch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-9>\",\"method\":\"setWidget\",\"widgetKey\":\"pi-websearch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-10>\",\"method\":\"setStatus\",\"statusKey\":\"pi-webfetch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-11>\",\"method\":\"setWidget\",\"widgetKey\":\"pi-webfetch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"entry_appended\",\"entry\":{\"type\":\"custom\",\"customType\":\"pi-rules.scan\",\"data\":{\"cwd\":\"<root>/cwd\",\"reason\":\"startup\"},\"startupBookkeeping\":true,\"id\":\"<entry-1>\",\"parentId\":\"<entry-2>\",\"timestamp\":\"2026-10-29T00:00:00.000Z\"},\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-12>\",\"method\":\"setStatus\",\"statusKey\":\"todo-waiting\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-13>\",\"method\":\"setStatus\",\"statusKey\":\"goal\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"session_opened\",\"sessionId\":\"rpc-1\",\"durableSessionId\":\"<uuid-14>\",\"sessionPath\":\"<root>/cwd/session.jsonl\",\"kind\":\"interactive\",\"cwd\":\"<root>/cwd\"}\n{\"type\":\"session_status\",\"subscriptionId\":\"sub-1\",\"seq\":1,\"sessionId\":\"rpc-1\",\"status\":\"idle\",\"kind\":\"interactive\",\"cwd\":\"<root>/cwd\",\"attachments\":1,\"durableSessionId\":\"<uuid-14>\",\"sessionPath\":\"<root>/cwd/session.jsonl\",\"model\":{\"provider\":\"faux\",\"id\":\"faux-a\"},\"thinkingLevel\":\"off\",\"pendingQueue\":{\"steering\":0,\"followUp\":0},\"lastChange\":{\"at\":\"2026-10-29T00:00:00.000Z\",\"cause\":\"open\",\"by\":\"client\"}}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-15>\",\"method\":\"setStatus\",\"statusKey\":\"anthropic-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-16>\",\"method\":\"setWidget\",\"widgetKey\":\"anthropic-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-17>\",\"method\":\"setStatus\",\"statusKey\":\"openai-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-18>\",\"method\":\"setWidget\",\"widgetKey\":\"openai-web-search\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-19>\",\"method\":\"setStatus\",\"statusKey\":\"monitors\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-20>\",\"method\":\"setStatus\",\"statusKey\":\"pi-websearch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-21>\",\"method\":\"setWidget\",\"widgetKey\":\"pi-websearch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-22>\",\"method\":\"setStatus\",\"statusKey\":\"pi-webfetch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-23>\",\"method\":\"setWidget\",\"widgetKey\":\"pi-webfetch\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"extension_ui_request\",\"id\":\"<uuid-24>\",\"method\":\"setStatus\",\"statusKey\":\"loop\",\"sessionId\":\"rpc-1\"}\n{\"type\":\"session_closed\",\"sessionId\":\"rpc-1\",\"reason\":\"client_close\"}\n{\"type\":\"session_status\",\"subscriptionId\":\"sub-1\",\"seq\":2,\"sessionId\":\"rpc-1\",\"status\":\"closed\",\"reason\":\"client_close\",\"kind\":\"interactive\",\"cwd\":\"<root>/cwd\",\"attachments\":1,\"durableSessionId\":\"<uuid-14>\",\"sessionPath\":\"<root>/cwd/session.jsonl\",\"model\":{\"provider\":\"faux\",\"id\":\"faux-a\"},\"thinkingLevel\":\"off\",\"pendingQueue\":{\"steering\":0,\"followUp\":0},\"lastChange\":{\"at\":\"2026-10-29T00:00:00.000Z\",\"cause\":\"close\",\"by\":\"client\"}}\n{\"id\":\"subscriber-2\",\"type\":\"response\",\"command\":\"unsubscribe_sessions\",\"success\":true}\n"
|
|
6
6
|
}
|
|
@@ -96,9 +96,9 @@
|
|
|
96
96
|
"hint": "restart_from_catalog",
|
|
97
97
|
"retryAfterMs": 0
|
|
98
98
|
},
|
|
99
|
-
"length":
|
|
100
|
-
"digest": "
|
|
101
|
-
"bytes": "
|
|
99
|
+
"length": 1232,
|
|
100
|
+
"digest": "d78530753a0e52e3f73d2a204dc0cd2b77656535adb7b14da8b8176d53eac997",
|
|
101
|
+
"bytes": "ewAiAGYAbwByAG0AYQB0ACIAOgAiAHMAZQBuAHAAaQAtAHIAZQBjAG8AdgBlAHIAeQAtAG0AYQBuAGkAZgBlAHMAdAAiACwAIgB2AGUAcgBzAGkAbwBuACIAOgAxACwAIgBzAG8AYwBrAGUAdABFAHAAbwBjAGgAIgA6AHsAIgBpAGQAIgA6ACIAcwBvAGMAawBlAHQALQAxACIAfQAsACIAYQBkAG0AaQBzAHMAaQBvAG4ASQBkACIAOgB7ACIAaQBkACIAOgAiAGcAbwBsAGQAZQBuAC0AaQAiAH0ALAAiAHIAbwB1AHQAZQBLAGkAbgBkACIAOgAiAG8AcgBkAGkAbgBhAHIAeQAiACwAIgBzAGUAcwBzAGkAbwBuACIAOgB7ACIAaQBkACIAOgAiAHIAcABjAC0AMQAiAH0ALAAiAHMAZQBzAHMAaQBvAG4ARQBwAG8AYwBoACIAOgB7ACIAaQBkACIAOgAiADAAMAAwADAAMAAwADAAMAAtADAAMAAwADAALQA0ADAAMAAwAC0AOAAwADAAMAAtADAAMAAwADAAMAAwADAAMAAwADAAMAAxACIAfQAsACIAZwBlAG4AZQByAGEAdABpAG8AbgAiADoAMgAsACIAcwBlAHEAdQBlAG4AYwBlACIAOgAxADQALAAiAGgAaQBzAHQAbwByAHkAVgBlAHIAcwBpAG8AbgAiADoANgAsACIAdABvAGsAZQBuACIAOgB7ACIAaQBkACIAOgAiAHMAbwBjAGsAZQB0AC0AMQA6ADIAIgB9ACwAIgBsAGUAYQBmACIAOgB7ACIAaQBkACIAOgAiADAAMAAwADAAMAAwADAAMQAiAH0ALAAiAGEAYwB0AGkAdgBlAE0AZQBzAHMAYQBnAGUAIgA6AG4AdQBsAGwALAAiAHQAdQByAG4AIgA6AG4AdQBsAGwALAAiAGMAaABlAGMAawBwAG8AaQBuAHQARABpAGcAZQBzAHQAIgA6ACIAMQBiAGIAYwBhAGQAMgA5ADMAMgAwAGYAMgAwADgANAA3AGEANQAxADUAYwBjADgANQA0ADAANgAzAGMAZABhADAAZABkAGEAZQBhADIAMABjAGQAYwBmAGYANAA1AGUAYgA2AGIANQBlADAAZQA5AGUAZQAxADUAZgBiAGQANAAiACwAIgBjAGEAdABhAGwAbwBnAFIAbwBvAHQAIgA6ACIAYwAtADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADEAIgAsACIAYwBhAHQAYQBsAG8AZwBSAG8AbwB0AEwAZQBuAGcAdABoACIAOgA0ADUAMAAyACwAIgByAGUAcQB1AGkAcgBlAGQASwBpAG4AZABzACIAOgBbACIAYQBjAHQAaQB2AGUAIgAsACIAYwBhAGwAbABzACIALAAiAGQAaQBhAGwAbwBnAHMAIgAsACIAaQBkAGUAbgB0AGkAdAB5ACIALAAiAGwAaQBmAGUAYwB5AGMAbABlACIALAAiAG8AcABhAHEAdQBlACIALAAiAHIAdQBuACIALAAiAHMAZQB0AHQAbABlAGQAIgAsACIAcwBvAHUAcgBjAGUAIgAsACIAdAByAGEAbgBzAGMAcgBpAHAAdAAiAF0AfQA="
|
|
102
102
|
}
|
|
103
103
|
},
|
|
104
104
|
"refusals": {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contract": "CONTRACT-r6",
|
|
3
|
+
"section": "B1",
|
|
4
|
+
"rulings": [
|
|
5
|
+
"RULING-60",
|
|
6
|
+
"RULING-61",
|
|
7
|
+
"RULING-67",
|
|
8
|
+
"RULING-128"
|
|
9
|
+
],
|
|
10
|
+
"requiredKindsRule": "manifest.requiredKinds is the sorted (code-unit order), de-duplicated list of the catalog families this cut's root requires: its complete families only, partial ones excluded by the engine. The same list is the requiredKinds of the cut's families/families registry component, inside the content checkpointDigest covers.",
|
|
11
|
+
"clientRules": [
|
|
12
|
+
"Read requiredKinds verbatim; never derive it from a built-in family list.",
|
|
13
|
+
"A manifest without requiredKinds (an older engine) is refused as manifest_missing_required_kinds, never opened from a built-in list.",
|
|
14
|
+
"A kind the client does not know is refused as manifest_unknown_required_kind, never ignored.",
|
|
15
|
+
"A list that differs from the complete families of the digest-verified families/families component is refused as manifest_required_kinds_mismatch."
|
|
16
|
+
],
|
|
17
|
+
"normalization": "Random epoch ids become 00000000-0000-4000-8000-<n> and every 64-hex digest a stable alias, in order of first appearance; every other byte is the engine's.",
|
|
18
|
+
"regenerate": "SENPI_WRITE_RECOVERY_GOLDENS=1 npx vitest run test/suite/regressions/5397-required-kinds-golden.test.ts (packages/coding-agent, senpi repository)",
|
|
19
|
+
"cases": [
|
|
20
|
+
{
|
|
21
|
+
"caseId": "one-partial-family",
|
|
22
|
+
"file": "one-partial-family.json",
|
|
23
|
+
"kind": "manifest",
|
|
24
|
+
"contractIds": [
|
|
25
|
+
"R4.B1",
|
|
26
|
+
"RULING-61",
|
|
27
|
+
"RULING-67",
|
|
28
|
+
"RULING-128"
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
{
|
|
2
|
+
"caseId": "one-partial-family",
|
|
3
|
+
"kind": "manifest",
|
|
4
|
+
"contractIds": [
|
|
5
|
+
"R4.B1",
|
|
6
|
+
"RULING-61",
|
|
7
|
+
"RULING-67",
|
|
8
|
+
"RULING-128"
|
|
9
|
+
],
|
|
10
|
+
"description": "A cut whose identity family is partial (one client correlation refused at the protocol depth limit): requiredKinds lists the nine complete families in code-unit order and leaves identity out; the cut's families/families registry carries the same list.",
|
|
11
|
+
"expected": {
|
|
12
|
+
"manifest": {
|
|
13
|
+
"format": "senpi-recovery-manifest",
|
|
14
|
+
"version": 1,
|
|
15
|
+
"socketEpoch": {
|
|
16
|
+
"id": "socket-1"
|
|
17
|
+
},
|
|
18
|
+
"admissionId": {
|
|
19
|
+
"id": "attach-1"
|
|
20
|
+
},
|
|
21
|
+
"routeKind": "ordinary",
|
|
22
|
+
"session": {
|
|
23
|
+
"id": "s"
|
|
24
|
+
},
|
|
25
|
+
"sessionEpoch": {
|
|
26
|
+
"id": "00000000-0000-4000-8000-000000000001"
|
|
27
|
+
},
|
|
28
|
+
"generation": 1,
|
|
29
|
+
"sequence": 3,
|
|
30
|
+
"historyVersion": 0,
|
|
31
|
+
"token": {
|
|
32
|
+
"id": "socket-1:1"
|
|
33
|
+
},
|
|
34
|
+
"leaf": null,
|
|
35
|
+
"activeMessage": {
|
|
36
|
+
"id": "message-1"
|
|
37
|
+
},
|
|
38
|
+
"turn": {
|
|
39
|
+
"id": "00000000-0000-4000-8000-000000000002"
|
|
40
|
+
},
|
|
41
|
+
"checkpointDigest": "1bbcad29320f20847a515cc854063cda0ddaea20cdcff45eb6b5e0e9ee15fbd4",
|
|
42
|
+
"catalogRoot": "c-0000000000000001",
|
|
43
|
+
"catalogRootLength": 2830,
|
|
44
|
+
"requiredKinds": [
|
|
45
|
+
"active",
|
|
46
|
+
"calls",
|
|
47
|
+
"dialogs",
|
|
48
|
+
"lifecycle",
|
|
49
|
+
"opaque",
|
|
50
|
+
"run",
|
|
51
|
+
"settled",
|
|
52
|
+
"source",
|
|
53
|
+
"transcript"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"families": {
|
|
57
|
+
"format": "senpi-recovery-families",
|
|
58
|
+
"version": 1,
|
|
59
|
+
"families": [
|
|
60
|
+
{
|
|
61
|
+
"family": "transcript",
|
|
62
|
+
"producer": "complete"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"family": "run",
|
|
66
|
+
"producer": "complete"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"family": "lifecycle",
|
|
70
|
+
"producer": "complete"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"family": "dialogs",
|
|
74
|
+
"producer": "complete"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"family": "opaque",
|
|
78
|
+
"producer": "complete"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"family": "active",
|
|
82
|
+
"producer": "complete"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"family": "calls",
|
|
86
|
+
"producer": "complete"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"family": "settled",
|
|
90
|
+
"producer": "complete"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"family": "identity",
|
|
94
|
+
"producer": "partial"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"family": "source",
|
|
98
|
+
"producer": "complete"
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
"requiredKinds": [
|
|
102
|
+
"active",
|
|
103
|
+
"calls",
|
|
104
|
+
"dialogs",
|
|
105
|
+
"lifecycle",
|
|
106
|
+
"opaque",
|
|
107
|
+
"run",
|
|
108
|
+
"settled",
|
|
109
|
+
"source",
|
|
110
|
+
"transcript"
|
|
111
|
+
],
|
|
112
|
+
"assembly": "incomplete",
|
|
113
|
+
"incomplete": [
|
|
114
|
+
"identity"
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|