@hachej/boring-agent 0.1.108 → 0.1.110
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/dist/{errors-CEU4iujR.d.ts → admin-DORVQfLn.d.ts} +80 -3
- package/dist/{chunk-GS4ADE34.js → chunk-42D6KAQV.js} +36 -12
- package/dist/{chunk-6OANSUEI.js → chunk-72KT6VWV.js} +59 -2
- package/dist/{chunk-3JFPS2O6.js → chunk-KJIEMSQP.js} +10 -1
- package/dist/{chunk-MVKXLMH3.js → chunk-KN72XWP7.js} +1 -1
- package/dist/{chunk-KDXIXVF6.js → chunk-V3H5A3BR.js} +12410 -5047
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +2 -1
- package/dist/{createHarness-AHWSC36D.js → createHarness-DOLOHA62.js} +2 -2
- package/dist/file-search-BUgMSKZE.d.ts +289 -0
- package/dist/front/index.d.ts +89 -4
- package/dist/front/index.js +508 -47
- package/dist/front/styles.css +55 -55
- package/dist/{harness-Ct0e4RWc.d.ts → harness-qHlMJhZo.d.ts} +1 -1
- package/dist/{piChatEvent-BUWIzw5l.d.ts → piChatEvent-DpE0lIb9.d.ts} +49 -17
- package/dist/{piChatSessionService-nvroRAVk.d.ts → piChatSessionService-CBct-hmz.d.ts} +4 -1
- package/dist/server/agent-host/testing/gatewayConformance.d.ts +7 -6
- package/dist/server/agent-host/testing/gatewayConformance.js +14 -7
- package/dist/server/index.d.ts +890 -56
- package/dist/server/index.js +73 -7
- package/dist/server/worker/index.js +5 -5
- package/dist/{lease-nASWv2tU.d.ts → share-entry-CxS6UJ_L.d.ts} +77 -179
- package/dist/shared/index.d.ts +118 -222
- package/dist/shared/index.js +17 -5
- package/dist/{types-B7-PN5jV.d.ts → types-DcWoQMn8.d.ts} +346 -10
- package/docs/AGENT_GATEWAY_V0.md +22 -2
- package/docs/AGENT_PACKAGES.md +15 -5
- package/docs/ERROR_CODES.md +14 -0
- package/package.json +10 -18
- package/dist/file-search-BGUHnW9o.d.ts +0 -87
package/dist/shared/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
AgentTaskSchema,
|
|
12
12
|
ArtifactLocatorSchema,
|
|
13
13
|
ArtifactRefSchema,
|
|
14
|
+
CHANNEL_DESCRIPTORS,
|
|
14
15
|
CREDENTIAL_AAD_ENCODING_VERSION,
|
|
15
16
|
CREDENTIAL_AUTH_TAG_BYTE_LENGTH_V1,
|
|
16
17
|
CREDENTIAL_DEK_BYTE_LENGTH_V1,
|
|
@@ -47,9 +48,11 @@ import {
|
|
|
47
48
|
WORKSPACE_KEK_PROVIDER_VERSION,
|
|
48
49
|
WorkspaceFileLocatorSchema,
|
|
49
50
|
agentRefEquals,
|
|
51
|
+
assertCredentialCustodyScopeV1,
|
|
50
52
|
assertNoConsumptionCycle,
|
|
51
53
|
assertValidTransition,
|
|
52
54
|
assertWithinConsumptionDepth,
|
|
55
|
+
channelDescriptor,
|
|
53
56
|
createAgentAssetDigest,
|
|
54
57
|
createAgentDefinitionDigest,
|
|
55
58
|
createAgentDeploymentDigest,
|
|
@@ -57,6 +60,7 @@ import {
|
|
|
57
60
|
createNotImplementedSandboxCredentialPayloadResolverV1,
|
|
58
61
|
createProviderCredentialRefFactoryV1,
|
|
59
62
|
createProviderRegistryV1,
|
|
63
|
+
credentialCustodySubjectKeyV1,
|
|
60
64
|
detectConsumptionCycle,
|
|
61
65
|
isReadonlyFilesystemMutationError,
|
|
62
66
|
isValidTaskTransition,
|
|
@@ -65,13 +69,15 @@ import {
|
|
|
65
69
|
providerCredentialFieldsV1,
|
|
66
70
|
resolveShareEntry,
|
|
67
71
|
sandboxCredentialPayloadMetadataBytesV1,
|
|
72
|
+
userCredentialCustodyScopeV1,
|
|
68
73
|
validateAgentDefinition,
|
|
69
74
|
validateAgentDeployment,
|
|
70
75
|
validateAgentTask,
|
|
71
76
|
validateConfig,
|
|
72
77
|
validateConsumptionGuards,
|
|
73
|
-
validateTool
|
|
74
|
-
|
|
78
|
+
validateTool,
|
|
79
|
+
workspaceCredentialCustodyScopeV1
|
|
80
|
+
} from "../chunk-72KT6VWV.js";
|
|
75
81
|
import {
|
|
76
82
|
SAFE_NATIVE_SESSION_ID,
|
|
77
83
|
compareSessionOrder,
|
|
@@ -114,7 +120,7 @@ import {
|
|
|
114
120
|
extractToolUiMetadata,
|
|
115
121
|
isToolUiMetadata,
|
|
116
122
|
sanitizeToolUiMetadata2 as sanitizeToolUiMetadata
|
|
117
|
-
} from "../chunk-
|
|
123
|
+
} from "../chunk-KN72XWP7.js";
|
|
118
124
|
import {
|
|
119
125
|
safeRandomUUID
|
|
120
126
|
} from "../chunk-YGRQ4Q5P.js";
|
|
@@ -127,7 +133,7 @@ import {
|
|
|
127
133
|
ERROR_CODES,
|
|
128
134
|
ErrorCode,
|
|
129
135
|
ErrorLogFieldsSchema
|
|
130
|
-
} from "../chunk-
|
|
136
|
+
} from "../chunk-KJIEMSQP.js";
|
|
131
137
|
export {
|
|
132
138
|
AGENT_GATEWAY_ERROR_CODES,
|
|
133
139
|
AGENT_KNOWLEDGE_FILESYSTEM_ID,
|
|
@@ -153,6 +159,7 @@ export {
|
|
|
153
159
|
ArtifactRefSchema,
|
|
154
160
|
BoringChatMessageSchema,
|
|
155
161
|
BoringChatPartSchema,
|
|
162
|
+
CHANNEL_DESCRIPTORS,
|
|
156
163
|
CREDENTIAL_AAD_ENCODING_VERSION,
|
|
157
164
|
CREDENTIAL_AUTH_TAG_BYTE_LENGTH_V1,
|
|
158
165
|
CREDENTIAL_DEK_BYTE_LENGTH_V1,
|
|
@@ -216,9 +223,11 @@ export {
|
|
|
216
223
|
WORKSPACE_KEK_PROVIDER_VERSION,
|
|
217
224
|
WorkspaceFileLocatorSchema,
|
|
218
225
|
agentRefEquals,
|
|
226
|
+
assertCredentialCustodyScopeV1,
|
|
219
227
|
assertNoConsumptionCycle,
|
|
220
228
|
assertValidTransition,
|
|
221
229
|
assertWithinConsumptionDepth,
|
|
230
|
+
channelDescriptor,
|
|
222
231
|
compareSessionOrder,
|
|
223
232
|
createAgentAssetDigest,
|
|
224
233
|
createAgentDefinitionDigest,
|
|
@@ -227,6 +236,7 @@ export {
|
|
|
227
236
|
createNotImplementedSandboxCredentialPayloadResolverV1,
|
|
228
237
|
createProviderCredentialRefFactoryV1,
|
|
229
238
|
createProviderRegistryV1,
|
|
239
|
+
credentialCustodySubjectKeyV1,
|
|
230
240
|
detectConsumptionCycle,
|
|
231
241
|
extractToolUiMetadata,
|
|
232
242
|
isReadonlyFilesystemMutationError,
|
|
@@ -241,10 +251,12 @@ export {
|
|
|
241
251
|
safeRandomUUID,
|
|
242
252
|
sandboxCredentialPayloadMetadataBytesV1,
|
|
243
253
|
sanitizeToolUiMetadata,
|
|
254
|
+
userCredentialCustodyScopeV1,
|
|
244
255
|
validateAgentDefinition,
|
|
245
256
|
validateAgentDeployment,
|
|
246
257
|
validateAgentTask,
|
|
247
258
|
validateConfig,
|
|
248
259
|
validateConsumptionGuards,
|
|
249
|
-
validateTool
|
|
260
|
+
validateTool,
|
|
261
|
+
workspaceCredentialCustodyScopeV1
|
|
250
262
|
};
|
|
@@ -1,14 +1,67 @@
|
|
|
1
|
+
import { d as PiChatEvent, C as ChatModelSelection } from './piChatEvent-DpE0lIb9.js';
|
|
2
|
+
import { v as SessionStreamIdentity, C as ToolReadinessRequirement, w as TelemetrySink, s as AgentTool, D as AgentHarnessFactory } from './harness-qHlMJhZo.js';
|
|
1
3
|
import { FastifyRequest, FastifyPluginAsync } from 'fastify';
|
|
2
|
-
import {
|
|
3
|
-
import { F as FileSearch, b as AgentSkillResource, c as WorkspaceAgentDirectRunInput, L as LeaseBoundWorkspaceAgent } from './file-search-BGUHnW9o.js';
|
|
4
|
+
import { F as FileSearch, g as AgentSkillResource, P as ProviderId, n as CredentialEnvelopeV1, K as WrappedWorkspaceDekV1, B as WorkspaceCredentialAuthorityVerifierV1, V as VerifiedWorkspaceCredentialAuthorityV1, t as WorkspaceAgentDirectRunInput, L as LeaseBoundWorkspaceAgent } from './file-search-BUgMSKZE.js';
|
|
4
5
|
import { b as Workspace, h as RuntimeFilesystemCapability, j as WorkspaceRuntimeContext, c as Sandbox } from './sandbox-BMhut3kh.js';
|
|
5
|
-
import { b as AgentSessionRef, V as VerifiedAgentScopeClaim, k as AgentGatewayErrorDTO,
|
|
6
|
-
import { C as ChatModelSelection } from './piChatEvent-BUWIzw5l.js';
|
|
6
|
+
import { B as CredentialLifecycleStateV1, b as AgentSessionRef, V as VerifiedAgentScopeClaim, k as AgentGatewayErrorDTO, P as JsonValue, a as AuthorizedAgentScope, A as AgentGateway, m as AgentScopeVerifier, T as ResolveAgentAccess } from './admin-DORVQfLn.js';
|
|
7
7
|
import { RuntimeHostOperations, RuntimeFilesystemBinding as RuntimeFilesystemBinding$1 } from '@hachej/boring-bash/agent';
|
|
8
8
|
import { BwrapArgsOptions } from '@hachej/boring-sandbox/providers/bwrap';
|
|
9
9
|
import { CreateNodeWorkspaceOptions, BoringAgentRuntimePaths } from '@hachej/boring-sandbox/providers/node-workspace';
|
|
10
|
+
import { CredentialStore } from '@earendil-works/pi-ai';
|
|
10
11
|
import { PackageSource, ExtensionFactory } from '@mariozechner/pi-coding-agent';
|
|
11
12
|
|
|
13
|
+
interface EventStreamReadResult {
|
|
14
|
+
events: Array<{
|
|
15
|
+
data: unknown;
|
|
16
|
+
offset: string;
|
|
17
|
+
}>;
|
|
18
|
+
nextOffset: string;
|
|
19
|
+
upToDate: boolean;
|
|
20
|
+
closed: boolean;
|
|
21
|
+
}
|
|
22
|
+
interface EventStreamMeta {
|
|
23
|
+
nextOffset: string;
|
|
24
|
+
closed: boolean;
|
|
25
|
+
}
|
|
26
|
+
interface SessionStreamOwner {
|
|
27
|
+
readonly path: string;
|
|
28
|
+
readonly workspaceScopeId: string;
|
|
29
|
+
readonly sessionId: string;
|
|
30
|
+
readonly agentTypeId: string | null;
|
|
31
|
+
readonly authSubjectId: string | null;
|
|
32
|
+
readonly seatId: string | null;
|
|
33
|
+
readonly threadId: string | null;
|
|
34
|
+
readonly keyVersion: number;
|
|
35
|
+
readonly createdAt: number;
|
|
36
|
+
}
|
|
37
|
+
interface CreateSessionStreamAttributes {
|
|
38
|
+
readonly agentTypeId: string;
|
|
39
|
+
readonly authSubjectId?: string;
|
|
40
|
+
}
|
|
41
|
+
declare const ownedSessionStreamBrand: unique symbol;
|
|
42
|
+
interface OwnedSessionStream {
|
|
43
|
+
readonly [ownedSessionStreamBrand]: true;
|
|
44
|
+
readonly path: string;
|
|
45
|
+
readonly identity: SessionStreamIdentity;
|
|
46
|
+
}
|
|
47
|
+
interface EventStreamStore {
|
|
48
|
+
createStream(path: string): Promise<void>;
|
|
49
|
+
createSessionStream(identity: SessionStreamIdentity, attrs: CreateSessionStreamAttributes): Promise<OwnedSessionStream>;
|
|
50
|
+
readStreamOwner(path: string): Promise<SessionStreamOwner | null>;
|
|
51
|
+
appendEvent(path: string, event: unknown): Promise<string>;
|
|
52
|
+
appendEventOnce(path: string, key: string, event: unknown): Promise<string>;
|
|
53
|
+
appendAgentEvent(stream: OwnedSessionStream, chunk: PiChatEvent, opts?: {
|
|
54
|
+
idempotencyKey?: string;
|
|
55
|
+
}): Promise<string>;
|
|
56
|
+
readEvents(path: string, opts?: {
|
|
57
|
+
offset?: string;
|
|
58
|
+
limit?: number;
|
|
59
|
+
}): Promise<EventStreamReadResult>;
|
|
60
|
+
closeStream(path: string): Promise<void>;
|
|
61
|
+
getStreamMeta(path: string): Promise<EventStreamMeta | null>;
|
|
62
|
+
subscribe(path: string, listener: () => void): () => void;
|
|
63
|
+
}
|
|
64
|
+
|
|
12
65
|
type SessionFileChangeOp = 'write' | 'edit' | 'unlink' | 'rename' | 'mkdir';
|
|
13
66
|
interface SessionFileChange {
|
|
14
67
|
op: SessionFileChangeOp;
|
|
@@ -320,7 +373,8 @@ interface ResolveInstallSourceOpts {
|
|
|
320
373
|
fingerprint: string;
|
|
321
374
|
}
|
|
322
375
|
interface WorkspaceProvisioningAdapter {
|
|
323
|
-
|
|
376
|
+
/** Application-owned runtime ID; provisioning does not select builtin adapters. */
|
|
377
|
+
mode: string;
|
|
324
378
|
exec(command: string, args: string[], opts?: {
|
|
325
379
|
cwd?: string;
|
|
326
380
|
env?: Record<string, string>;
|
|
@@ -403,6 +457,51 @@ type RuntimeFilesystemStrategy = {
|
|
|
403
457
|
kind: 'remote-workspace';
|
|
404
458
|
pathOptions?: RuntimeRemoteWorkspacePathOptions;
|
|
405
459
|
};
|
|
460
|
+
interface RuntimeProjectionRequest {
|
|
461
|
+
/** Server-private endpoint coordinates. Never expose this request to plugin/front/model code. */
|
|
462
|
+
port: number;
|
|
463
|
+
path?: string;
|
|
464
|
+
}
|
|
465
|
+
interface RuntimeProjectionLease {
|
|
466
|
+
/** Sealed upstream consumed only by the Host projection broker. */
|
|
467
|
+
readonly url: string;
|
|
468
|
+
readonly expiresAt: string;
|
|
469
|
+
revoke(): Promise<void>;
|
|
470
|
+
}
|
|
471
|
+
type RuntimeTrustedServiceOperation = 'start' | 'observe' | 'act' | 'takeover' | 'return-control' | 'stop';
|
|
472
|
+
interface RuntimeTrustedServiceQualificationV1 {
|
|
473
|
+
readonly serviceRef: 'trusted-service-v1';
|
|
474
|
+
readonly protocolDigest: string;
|
|
475
|
+
readonly imageDigest: string;
|
|
476
|
+
readonly isolation: 'dedicated-uid-private-channel';
|
|
477
|
+
}
|
|
478
|
+
interface RuntimeTrustedServiceLeaseV1 {
|
|
479
|
+
readonly qualification: RuntimeTrustedServiceQualificationV1;
|
|
480
|
+
invoke(input: {
|
|
481
|
+
readonly operation: RuntimeTrustedServiceOperation;
|
|
482
|
+
readonly payload?: Uint8Array;
|
|
483
|
+
readonly timeoutMs: number;
|
|
484
|
+
readonly signal: AbortSignal;
|
|
485
|
+
}): Promise<{
|
|
486
|
+
readonly status: 'ok' | 'rejected' | 'unknown-outcome';
|
|
487
|
+
readonly payload?: Uint8Array;
|
|
488
|
+
}>;
|
|
489
|
+
/** Host-only fixed endpoint lookup. No host, port, URL, or provider identity crosses this seam. */
|
|
490
|
+
createProjection(input: {
|
|
491
|
+
readonly mode: 'observe' | 'control';
|
|
492
|
+
readonly expiresAt: Date;
|
|
493
|
+
}): Promise<RuntimeProjectionLease>;
|
|
494
|
+
close(): Promise<void>;
|
|
495
|
+
}
|
|
496
|
+
interface RuntimeTrustedServiceMechanismV1 {
|
|
497
|
+
readonly qualification: RuntimeTrustedServiceQualificationV1;
|
|
498
|
+
acquire(input: {
|
|
499
|
+
readonly leaseId: string;
|
|
500
|
+
readonly idleTtlMs: number;
|
|
501
|
+
readonly absoluteTtlMs: number;
|
|
502
|
+
readonly signal: AbortSignal;
|
|
503
|
+
}): Promise<RuntimeTrustedServiceLeaseV1>;
|
|
504
|
+
}
|
|
406
505
|
interface RuntimeModeAdapter {
|
|
407
506
|
readonly id: RuntimeModeId;
|
|
408
507
|
readonly runtimeHost?: AgentRuntimeHostOperations;
|
|
@@ -574,6 +673,10 @@ interface RuntimeBundle {
|
|
|
574
673
|
filesystem?: RuntimeFilesystemStrategy;
|
|
575
674
|
/** Optional filesystem bindings prepared for this runtime/session. */
|
|
576
675
|
filesystemBindings?: RuntimeFilesystemBinding[];
|
|
676
|
+
/** Pair-local projection authority captured with this exact RuntimeBundle generation. */
|
|
677
|
+
createRuntimeProjection?: (request: RuntimeProjectionRequest) => Promise<RuntimeProjectionLease>;
|
|
678
|
+
/** Qualified fixed service channel. Ordinary Agent tools never receive this field. */
|
|
679
|
+
trustedServiceV1?: RuntimeTrustedServiceMechanismV1;
|
|
577
680
|
/**
|
|
578
681
|
* Workspace-relative prefixes the host protects from mutation. Carried on the
|
|
579
682
|
* bundle so shell/provisioning enforcement uses the same policy as the
|
|
@@ -602,6 +705,8 @@ interface PiHarnessOptions {
|
|
|
602
705
|
noSkills?: boolean;
|
|
603
706
|
/** Disable ambient Pi extensions (required when tools execute in a remote runtime). */
|
|
604
707
|
noExtensions?: boolean;
|
|
708
|
+
/** Ignore packages from user/project Pi settings while preserving explicit host package grants. */
|
|
709
|
+
noAmbientPackages?: boolean;
|
|
605
710
|
additionalSkillPaths?: string[];
|
|
606
711
|
defaultModel?: {
|
|
607
712
|
provider: string;
|
|
@@ -631,6 +736,8 @@ interface PiHarnessOptions {
|
|
|
631
736
|
getHotReloadableResources?: () => HotReloadablePiResources;
|
|
632
737
|
/** Reject an explicit unavailable/unknown model instead of silently falling back. */
|
|
633
738
|
strictModelResolution?: boolean;
|
|
739
|
+
/** Host-owned, actor-bound credential source. Never projected into the runtime workspace. */
|
|
740
|
+
credentialStore?: CredentialStore;
|
|
634
741
|
}
|
|
635
742
|
/** Pi harness options with the discovery flags resolved to definite booleans. */
|
|
636
743
|
type ResolvedPiHarnessOptions = PiHarnessOptions & {
|
|
@@ -672,7 +779,151 @@ interface AgentSkillResourceSnapshot {
|
|
|
672
779
|
locateSkill(filePath: string): AgentSkillResource | undefined;
|
|
673
780
|
}
|
|
674
781
|
|
|
675
|
-
|
|
782
|
+
/**
|
|
783
|
+
* Injectable persistence port for the credential vault.
|
|
784
|
+
*
|
|
785
|
+
* The ratified persistence model (docs/issues/820/byok-secret-vault-plan.md,
|
|
786
|
+
* "Proposed persistence model") maps one-to-one onto these methods:
|
|
787
|
+
* `workspace_provider_credentials` -> credential record,
|
|
788
|
+
* `workspace_credential_keys` -> wrapped DEK,
|
|
789
|
+
* `workspace_provider_credential_fields` -> field envelope.
|
|
790
|
+
*
|
|
791
|
+
* S1 supplies both in-memory and Postgres implementations. Only ciphertext,
|
|
792
|
+
* nonce, tag, persisted AAD, and metadata-only tombstones cross this port —
|
|
793
|
+
* never plaintext, never a KEK.
|
|
794
|
+
*/
|
|
795
|
+
type CredentialMaterialKindV1 = 'field-set' | 'none';
|
|
796
|
+
/** Metadata-only projection. Secret envelopes are deliberately unreachable here. */
|
|
797
|
+
interface StoredCredentialMetadataV1 {
|
|
798
|
+
readonly providerId: ProviderId;
|
|
799
|
+
readonly displayLabel: string;
|
|
800
|
+
readonly credentialType: string;
|
|
801
|
+
readonly state: CredentialLifecycleStateV1;
|
|
802
|
+
readonly credentialVersion: number;
|
|
803
|
+
readonly maskedLastFourSuffix?: string;
|
|
804
|
+
readonly createdAt: string;
|
|
805
|
+
readonly updatedAt: string;
|
|
806
|
+
}
|
|
807
|
+
interface StoredCredentialRecordV1 {
|
|
808
|
+
/** Stable per-(workspace, provider) credential identity, bound into AAD. */
|
|
809
|
+
readonly credentialId: string;
|
|
810
|
+
readonly credentialVersion: number;
|
|
811
|
+
readonly dekGeneration: number;
|
|
812
|
+
readonly materialKind: CredentialMaterialKindV1;
|
|
813
|
+
}
|
|
814
|
+
interface CredentialFieldKeyV1 {
|
|
815
|
+
readonly workspaceId: string;
|
|
816
|
+
readonly providerId: ProviderId;
|
|
817
|
+
readonly credentialVersion: number;
|
|
818
|
+
/** Required when persisting a live envelope; omitted for keyed reads. */
|
|
819
|
+
readonly dekGeneration?: number;
|
|
820
|
+
readonly fieldId: string;
|
|
821
|
+
}
|
|
822
|
+
type CredentialFieldDeletionReasonV1 = 'superseded-version' | 'credential-tombstone' | 'crypto-shred';
|
|
823
|
+
interface WorkspaceDekRotationStateV1 {
|
|
824
|
+
/** Caller-stable idempotency key. A retry must present the same operation id. */
|
|
825
|
+
readonly operationId: string;
|
|
826
|
+
readonly sourceGeneration: number;
|
|
827
|
+
readonly targetGeneration: number;
|
|
828
|
+
readonly phase: 'reencrypting' | 'verified' | 'anchor-advanced';
|
|
829
|
+
}
|
|
830
|
+
interface WorkspaceDekRotationReceiptV1 {
|
|
831
|
+
readonly operationId: string;
|
|
832
|
+
readonly sourceGeneration: number;
|
|
833
|
+
readonly targetGeneration: number;
|
|
834
|
+
}
|
|
835
|
+
interface WorkspaceCredentialRecordV1 {
|
|
836
|
+
readonly providerId: ProviderId;
|
|
837
|
+
readonly record: StoredCredentialRecordV1;
|
|
838
|
+
}
|
|
839
|
+
interface CommitDekRotationRecordInputV1 {
|
|
840
|
+
readonly workspaceId: string;
|
|
841
|
+
readonly providerId: ProviderId;
|
|
842
|
+
readonly expectedCredentialVersion: number;
|
|
843
|
+
readonly sourceGeneration: number;
|
|
844
|
+
readonly targetGeneration: number;
|
|
845
|
+
readonly fields: ReadonlyMap<string, CredentialEnvelopeV1>;
|
|
846
|
+
}
|
|
847
|
+
interface CredentialFieldTombstoneV1 {
|
|
848
|
+
readonly deletedAt: string;
|
|
849
|
+
readonly reason: CredentialFieldDeletionReasonV1;
|
|
850
|
+
}
|
|
851
|
+
interface CommitCredentialVersionInputV1 {
|
|
852
|
+
readonly workspaceId: string;
|
|
853
|
+
readonly providerId: ProviderId;
|
|
854
|
+
readonly expectedCredentialVersion: number;
|
|
855
|
+
readonly record: StoredCredentialRecordV1;
|
|
856
|
+
readonly fields: ReadonlyMap<string, CredentialEnvelopeV1>;
|
|
857
|
+
readonly supersededFieldsTombstone?: CredentialFieldTombstoneV1;
|
|
858
|
+
}
|
|
859
|
+
interface CommitCredentialVersionInputV2 extends CommitCredentialVersionInputV1 {
|
|
860
|
+
/** Applied in the same durable transaction as the record/version CAS. */
|
|
861
|
+
readonly metadataUpdate: Readonly<{
|
|
862
|
+
state: CredentialLifecycleStateV1;
|
|
863
|
+
displayLabel?: string;
|
|
864
|
+
credentialType?: string;
|
|
865
|
+
maskedLastFourSuffix?: string | null;
|
|
866
|
+
}>;
|
|
867
|
+
}
|
|
868
|
+
interface WorkspaceCredentialLockOptionsV1 {
|
|
869
|
+
/** Cancels only while waiting to acquire the lock; a running mutation is never interrupted. */
|
|
870
|
+
readonly signal?: AbortSignal;
|
|
871
|
+
/** Absolute Unix timestamp in milliseconds by which lock acquisition must finish. */
|
|
872
|
+
readonly deadlineMs?: number;
|
|
873
|
+
/** Relative acquisition bound. The earliest of this and deadlineMs wins. */
|
|
874
|
+
readonly timeoutMs?: number;
|
|
875
|
+
}
|
|
876
|
+
interface CredentialVaultPersistenceV1 {
|
|
877
|
+
/** Serializes workspace-wide lifecycle mutations and supplies a scoped adapter. */
|
|
878
|
+
withWorkspaceLock<T>(workspaceId: string, mutate: (locked: CredentialVaultPersistenceV1) => Promise<T>, options?: WorkspaceCredentialLockOptionsV1): Promise<T>;
|
|
879
|
+
getCredentialMetadata(workspaceId: string, providerId: ProviderId): Promise<StoredCredentialMetadataV1 | undefined>;
|
|
880
|
+
listCredentialMetadata(workspaceId: string): Promise<readonly StoredCredentialMetadataV1[]>;
|
|
881
|
+
/** True when any credential row, key, field/tombstone, rotation, or shred fence remains. */
|
|
882
|
+
hasWorkspaceCredentialArtifacts(workspaceId: string): Promise<boolean>;
|
|
883
|
+
updateCredentialMetadata(workspaceId: string, providerId: ProviderId, update: Readonly<{
|
|
884
|
+
state: CredentialLifecycleStateV1;
|
|
885
|
+
displayLabel?: string;
|
|
886
|
+
credentialType?: string;
|
|
887
|
+
maskedLastFourSuffix?: string | null;
|
|
888
|
+
}>): Promise<StoredCredentialMetadataV1>;
|
|
889
|
+
getCredentialRecord(workspaceId: string, providerId: ProviderId): Promise<StoredCredentialRecordV1 | undefined>;
|
|
890
|
+
putCredentialRecord(workspaceId: string, providerId: ProviderId, record: StoredCredentialRecordV1): Promise<void>;
|
|
891
|
+
/** Atomically CASes the record, fields, and superseded-version tombstones. */
|
|
892
|
+
commitCredentialVersion(input: CommitCredentialVersionInputV1): Promise<void>;
|
|
893
|
+
getWrappedDek(workspaceId: string, dekGeneration: number): Promise<WrappedWorkspaceDekV1 | undefined>;
|
|
894
|
+
putWrappedDek(workspaceId: string, dekGeneration: number, wrapped: WrappedWorkspaceDekV1): Promise<void>;
|
|
895
|
+
deleteWrappedDek(workspaceId: string, dekGeneration: number): Promise<void>;
|
|
896
|
+
listCredentialRecords(workspaceId: string): Promise<readonly WorkspaceCredentialRecordV1[]>;
|
|
897
|
+
listFields(workspaceId: string, providerId: ProviderId, credentialVersion: number): Promise<ReadonlyMap<string, CredentialEnvelopeV1>>;
|
|
898
|
+
/** Atomically replaces one current record's envelopes during DEK rotation. */
|
|
899
|
+
commitDekRotationRecord(input: CommitDekRotationRecordInputV1): Promise<void>;
|
|
900
|
+
getDekRotationState(workspaceId: string): Promise<WorkspaceDekRotationStateV1 | undefined>;
|
|
901
|
+
putDekRotationState(workspaceId: string, state: WorkspaceDekRotationStateV1): Promise<void>;
|
|
902
|
+
getDekRotationReceipt(workspaceId: string, operationId: string): Promise<WorkspaceDekRotationReceiptV1 | undefined>;
|
|
903
|
+
/** Atomically destroys N, clears the active marker, and records the idempotency receipt. */
|
|
904
|
+
finalizeDekRotation(workspaceId: string, state: WorkspaceDekRotationStateV1): Promise<void>;
|
|
905
|
+
clearDekRotationState(workspaceId: string): Promise<void>;
|
|
906
|
+
isWorkspaceCryptoShredded(workspaceId: string): Promise<boolean>;
|
|
907
|
+
/** Atomically tombstones ciphertext, destroys wrapped DEKs, and records the shred fence. */
|
|
908
|
+
cryptoShredWorkspace(workspaceId: string, shreddedAt: string): Promise<void>;
|
|
909
|
+
getField(key: CredentialFieldKeyV1): Promise<CredentialEnvelopeV1 | undefined>;
|
|
910
|
+
putField(key: CredentialFieldKeyV1, envelope: CredentialEnvelopeV1): Promise<void>;
|
|
911
|
+
/** Deletes ciphertext and retains metadata-only tombstones for every field. */
|
|
912
|
+
tombstoneCredentialVersionFields(workspaceId: string, providerId: ProviderId, credentialVersion: number, tombstone: CredentialFieldTombstoneV1): Promise<void>;
|
|
913
|
+
getFieldTombstone(key: CredentialFieldKeyV1): Promise<CredentialFieldTombstoneV1 | undefined>;
|
|
914
|
+
}
|
|
915
|
+
/** Persistence capability required by the V2 recoverable vault protocol. */
|
|
916
|
+
interface CredentialVaultPersistenceV2 extends CredentialVaultPersistenceV1 {
|
|
917
|
+
readonly contractVersion: 'boring.credential-vault-persistence.v2';
|
|
918
|
+
/** Preserves the V2 capability on the transaction-scoped adapter. */
|
|
919
|
+
withWorkspaceLock<T>(workspaceId: string, mutate: (locked: CredentialVaultPersistenceV2) => Promise<T>, options?: WorkspaceCredentialLockOptionsV1): Promise<T>;
|
|
920
|
+
/** Atomically CASes record, fields, tombstones, and authenticated metadata. */
|
|
921
|
+
commitCredentialVersionV2(input: CommitCredentialVersionInputV2): Promise<void>;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/** Single runtime and type-level source of truth for gateway operations persisted in request keys. */
|
|
925
|
+
declare const AGENT_GATEWAY_EFFECTS: readonly ["session.create", "session.rename", "session.archive", "session.delete", "session.prompt", "session.followup", "session.interrupt", "session.stop", "session.queue.clear", "agent.reload", "session.command.execute"];
|
|
926
|
+
type AgentGatewayEffect = typeof AGENT_GATEWAY_EFFECTS[number];
|
|
676
927
|
type AgentRequestTarget = {
|
|
677
928
|
readonly kind: 'agent';
|
|
678
929
|
readonly agentTypeId: string;
|
|
@@ -687,6 +938,31 @@ interface AgentRequestKey {
|
|
|
687
938
|
readonly target: AgentRequestTarget;
|
|
688
939
|
readonly requestId: string;
|
|
689
940
|
}
|
|
941
|
+
type RunId = string;
|
|
942
|
+
interface VerifiedSeatParticipation {
|
|
943
|
+
readonly seatId: string;
|
|
944
|
+
}
|
|
945
|
+
/** Admission-time identity and provenance reference; never a live authorization grant. */
|
|
946
|
+
interface AcceptedWorkContext {
|
|
947
|
+
readonly version: 1;
|
|
948
|
+
readonly identity: {
|
|
949
|
+
readonly runId: RunId;
|
|
950
|
+
readonly requestKey: AgentRequestKey;
|
|
951
|
+
readonly agent: {
|
|
952
|
+
readonly agentTypeId: string;
|
|
953
|
+
};
|
|
954
|
+
readonly participation?: VerifiedSeatParticipation;
|
|
955
|
+
};
|
|
956
|
+
readonly operation: AgentGatewayEffect;
|
|
957
|
+
readonly target: AgentRequestTarget;
|
|
958
|
+
readonly authority: {
|
|
959
|
+
readonly workspaceScopeId: string;
|
|
960
|
+
readonly authSubjectId: string;
|
|
961
|
+
};
|
|
962
|
+
readonly delegation: {
|
|
963
|
+
readonly lineage: readonly RunId[];
|
|
964
|
+
};
|
|
965
|
+
}
|
|
690
966
|
interface AgentStableServiceErrorDTO {
|
|
691
967
|
readonly statusCode: number;
|
|
692
968
|
readonly error: {
|
|
@@ -704,13 +980,17 @@ type AgentRequestFailure = {
|
|
|
704
980
|
};
|
|
705
981
|
interface AgentRequestLedgerRecordBase {
|
|
706
982
|
readonly key: AgentRequestKey;
|
|
983
|
+
readonly acceptedWork: AcceptedWorkContext;
|
|
707
984
|
readonly digest: string;
|
|
708
985
|
readonly updatedAt: number;
|
|
709
986
|
}
|
|
710
987
|
type AgentRequestLedgerRecord = (AgentRequestLedgerRecordBase & {
|
|
711
988
|
readonly state: 'pending-admission';
|
|
989
|
+
/** The last owner stopped before ledger admission acceptance or effect dispatch. */
|
|
990
|
+
readonly retryable?: true;
|
|
712
991
|
}) | (AgentRequestLedgerRecordBase & {
|
|
713
992
|
readonly state: 'admission-accepted';
|
|
993
|
+
/** Append-only admission provenance, separate from current authority. */
|
|
714
994
|
readonly admissionReceipt: string;
|
|
715
995
|
}) | (AgentRequestLedgerRecordBase & {
|
|
716
996
|
readonly state: 'in-flight';
|
|
@@ -727,8 +1007,10 @@ type AgentRequestLedgerRecord = (AgentRequestLedgerRecordBase & {
|
|
|
727
1007
|
interface AgentRequestLedger {
|
|
728
1008
|
/** Direct production projections require transactional durable ownership. */
|
|
729
1009
|
readonly durability: 'durable-transactional' | 'in-memory';
|
|
730
|
-
/**
|
|
731
|
-
prepare(key: AgentRequestKey, digest: string): Promise<AgentRequestLedgerPrepareResult>;
|
|
1010
|
+
/** Atomically create or reclaim explicitly retryable admission across all store users. */
|
|
1011
|
+
prepare(key: AgentRequestKey, digest: string, acceptedWork: AcceptedWorkContext): Promise<AgentRequestLedgerPrepareResult>;
|
|
1012
|
+
/** Release only a pending claim whose owner has stopped before any effect. */
|
|
1013
|
+
markAdmissionRetryable(key: AgentRequestKey): Promise<void>;
|
|
732
1014
|
/** All transitions are compare-and-swap against the exact allowed prior state. */
|
|
733
1015
|
acceptAdmission(key: AgentRequestKey, admissionReceipt: string): Promise<void>;
|
|
734
1016
|
beginEffect(key: AgentRequestKey): Promise<void>;
|
|
@@ -739,7 +1021,7 @@ interface AgentRequestLedger {
|
|
|
739
1021
|
close?(): void | Promise<void>;
|
|
740
1022
|
}
|
|
741
1023
|
interface AgentRequestLedgerPrepareResult {
|
|
742
|
-
readonly ownership: 'created' | 'existing';
|
|
1024
|
+
readonly ownership: 'created' | 'reclaimed' | 'existing';
|
|
743
1025
|
readonly record: AgentRequestLedgerRecord;
|
|
744
1026
|
}
|
|
745
1027
|
type AgentEffectAdmissionResult = {
|
|
@@ -954,8 +1236,21 @@ interface AgentHostEnvironmentScope extends ResolvedEnvironmentScope {
|
|
|
954
1236
|
readonly requestId: string;
|
|
955
1237
|
}) => Promise<readonly RuntimeFilesystemBinding[] | undefined>;
|
|
956
1238
|
}
|
|
1239
|
+
interface AgentHostSessionEnvironmentLease {
|
|
1240
|
+
readonly environmentGenerationId: string;
|
|
1241
|
+
readonly bindingGeneration: number;
|
|
1242
|
+
readonly signal: AbortSignal;
|
|
1243
|
+
acquireTrustedService(input: {
|
|
1244
|
+
readonly leaseId: string;
|
|
1245
|
+
readonly idleTtlMs: number;
|
|
1246
|
+
readonly absoluteTtlMs: number;
|
|
1247
|
+
}): Promise<RuntimeTrustedServiceLeaseV1>;
|
|
1248
|
+
release(): void;
|
|
1249
|
+
}
|
|
957
1250
|
interface AgentHostEnvironmentLease {
|
|
958
1251
|
readonly workspace: Workspace;
|
|
1252
|
+
/** Process execution paired with this exact runtime-owned workspace generation. */
|
|
1253
|
+
readonly sandbox: Sandbox;
|
|
959
1254
|
readonly gitWorkspace: Workspace;
|
|
960
1255
|
readonly fileSearch: FileSearch;
|
|
961
1256
|
readonly filesystemBindings?: readonly RuntimeFilesystemBinding[];
|
|
@@ -978,6 +1273,8 @@ interface AgentHostDescription {
|
|
|
978
1273
|
readonly agents: readonly {
|
|
979
1274
|
readonly agentTypeId: string;
|
|
980
1275
|
readonly label: string;
|
|
1276
|
+
/** Exact package-declared version, when this is a configured Agent. */
|
|
1277
|
+
readonly definitionVersion?: string;
|
|
981
1278
|
/** Computed definition identity digest (instructions + knowledge bytes), when the spec carries one. */
|
|
982
1279
|
readonly definitionDigest?: string;
|
|
983
1280
|
}[];
|
|
@@ -1020,12 +1317,45 @@ interface CreateAgentHostOptions {
|
|
|
1020
1317
|
readonly requestLedger?: AgentRequestLedger;
|
|
1021
1318
|
/** Durable effect ledger path, independent of transcript/session storage. */
|
|
1022
1319
|
readonly requestLedgerPath?: string;
|
|
1320
|
+
/** App-host-owned durable event store, shared with channel outbound tails. */
|
|
1321
|
+
readonly eventStore?: EventStreamStore;
|
|
1023
1322
|
/** Explicit test/dev opt-in for an in-memory ledger. */
|
|
1024
1323
|
readonly inMemoryRequestLedgerMode?: 'test' | 'development';
|
|
1324
|
+
/**
|
|
1325
|
+
* Built-in SQLite terminal-payload retention. Values below 24 hours are
|
|
1326
|
+
* raised to 24 hours; omitted retention keeps terminal payloads indefinitely.
|
|
1327
|
+
* Injected ledgers retain ownership of their own storage policy.
|
|
1328
|
+
*/
|
|
1025
1329
|
readonly requestRetentionMs?: number;
|
|
1026
1330
|
readonly effectAdmission?: AgentEffectAdmission;
|
|
1027
1331
|
readonly shutdownGraceMs?: number;
|
|
1028
1332
|
readonly harnessFactory?: AgentHarnessFactory;
|
|
1333
|
+
/**
|
|
1334
|
+
* [1082 slice B] BYOK credential-vault composition inputs. Enablement is
|
|
1335
|
+
* env-driven (`BORING_CREDENTIAL_KMS_BACKEND`); when enabled the host embeds
|
|
1336
|
+
* durable persistence (#1145) and the Core-owned authority verifier here.
|
|
1337
|
+
* The composition is resolved exactly once, at `createAgentHost` startup:
|
|
1338
|
+
* misconfigured env fails host creation with a stable `CREDENTIAL_*` error,
|
|
1339
|
+
* and all runtime bindings share the single host-scope vault composition.
|
|
1340
|
+
* Absent env → composition absent, behavior identical to env-key-only auth.
|
|
1341
|
+
*/
|
|
1342
|
+
readonly credentials?: AgentHostCredentialOptionsV1;
|
|
1343
|
+
}
|
|
1344
|
+
interface WorkspaceCredentialLifecycleV1 {
|
|
1345
|
+
/** Irreversibly fences and destroys credential key access for one workspace. */
|
|
1346
|
+
cryptoShredWorkspace(workspaceId: string): Promise<void>;
|
|
1347
|
+
}
|
|
1348
|
+
interface AgentHostCredentialOptionsV1 {
|
|
1349
|
+
/** Env-shaped record override; defaults to `process.env`. */
|
|
1350
|
+
readonly env?: Readonly<Record<string, string | undefined>>;
|
|
1351
|
+
/** Durable vault persistence (#1145 Postgres in production). */
|
|
1352
|
+
readonly vaultPersistence?: CredentialVaultPersistenceV2;
|
|
1353
|
+
/** Core-owned authority verifier; pre-binds the credential resolver. */
|
|
1354
|
+
readonly authorityVerifier?: WorkspaceCredentialAuthorityVerifierV1;
|
|
1355
|
+
/** Host authentication adapter for owner-only credential HTTP routes. */
|
|
1356
|
+
readonly authorizeOwnerRequest?: (request: FastifyRequest) => VerifiedWorkspaceCredentialAuthorityV1 | Promise<VerifiedWorkspaceCredentialAuthorityV1>;
|
|
1357
|
+
/** Core deletion composition receives only the narrow irreversible lifecycle seam. */
|
|
1358
|
+
readonly onLifecycleReady?: (lifecycle: WorkspaceCredentialLifecycleV1) => void;
|
|
1029
1359
|
}
|
|
1030
1360
|
interface CreatedAgentHost {
|
|
1031
1361
|
readonly host: AgentHostHandle;
|
|
@@ -1035,7 +1365,13 @@ interface CreatedAgentHost {
|
|
|
1035
1365
|
readonly authorizedScope: AuthorizedAgentScope;
|
|
1036
1366
|
readonly intent: AuthorizedEnvironmentIntent;
|
|
1037
1367
|
}): Promise<AgentHostEnvironmentLease>;
|
|
1368
|
+
/** Trusted composition-only acquisition of the addressed session's exact Environment generation. */
|
|
1369
|
+
acquireSessionEnvironment(input: {
|
|
1370
|
+
readonly authorizedScope: AuthorizedAgentScope;
|
|
1371
|
+
readonly ref: AgentSessionRef;
|
|
1372
|
+
readonly requestId: string;
|
|
1373
|
+
}): Promise<AgentHostSessionEnvironmentLease>;
|
|
1038
1374
|
runWithWorkspaceAgent(input: AgentHostDispatcherRunInput, run: (binding: LeaseBoundWorkspaceAgent) => Promise<void>): Promise<void>;
|
|
1039
1375
|
}
|
|
1040
1376
|
|
|
1041
|
-
export { type
|
|
1377
|
+
export { type MeteringReleaseInput as $, type AgentGatewayEffect as A, type BuiltinRuntimeModeId as B, type CredentialVaultPersistenceV2 as C, type AgentHostEnvironmentScope as D, type EventStreamStore as E, type ResolvedAgentRuntimeScope as F, type AgentRequestKey as G, type AcceptedWorkContext as H, type AgentRequestLedgerPrepareResult as I, type AgentRequestFailure as J, type AgentRequestLedgerRecord as K, type AgentFleetCompiler as L, type ModeContext as M, type AgentRequestTarget as N, type RuntimeFilesystemAccessDecision as O, type ProvisionWorkspaceRuntimeOptions as P, type AgentHostDescription as Q, type RuntimeModeAdapter as R, type StoredCredentialRecordV1 as S, type AgentHostDirectProjectionOptions as T, type AgentHostDispatcherRunInput as U, type AgentHostEnvironmentLease as V, type WorkspaceProvisioningResult as W, type AgentHostHandle as X, type CredentialVaultPersistenceV1 as Y, DEFAULT_AGENT_TYPE_ID as Z, type MeteringErrorLogger as _, type PiPackageSource as a, type MeteringReleaseReason as a0, type MeteringReservationResult as a1, type MeteringReserveInput as a2, type MeteringRunKind as a3, type MeteringRunScope as a4, type MeteringRunStatus as a5, type MeteringSettleInput as a6, type MeteringUsage as a7, type MeteringUsageInput as a8, PI_PACKAGE_RESOURCE_FILTERS as a9, type PiExtensionFactory as aa, type PluginSkillSource as ab, type ResolvedEnvironmentScope as ac, type RuntimeFilesystemBindingOperations as ad, type RuntimeNodePackageSpec as ae, type RuntimeProvisioningContribution as af, type RuntimePythonSpec as ag, type RuntimeTemplateContribution as ah, type WorkspaceCredentialLifecycleV1 as ai, type WorkspaceProvisioningExecResult as aj, compactPiPackages as ak, mergePiPackageSources as al, normalizeMeteringUsage as am, piPackageSourceKey as an, type CredentialMaterialKindV1 as b, type WorkspaceCredentialLockOptionsV1 as c, type StoredCredentialMetadataV1 as d, type RuntimeModeId as e, type AgentRuntimeHostOperations as f, type RuntimeBashStrategy as g, type RuntimeFilesystemStrategy as h, type WorkspaceProvisioningAdapter as i, type AgentInstructionSource as j, type ConfiguredAgentHostAgentSpec as k, type AgentInstructionFileRef as l, type AgentHostAgentSpec as m, type RuntimeBundle as n, type PiHarnessOptions as o, type AgentMeteringSink as p, type AgentHostCredentialOptionsV1 as q, type RuntimeFilesystemBinding as r, type CreatedAgentHost as s, type ResolvedPiHarnessOptions as t, ReadyStatusTracker as u, type CreateAgentHostOptions as v, type CompiledAgentHostAgentSpec as w, type AgentRequestLedger as x, type AgentEffectAdmission as y, type AuthorizedEnvironmentIntent as z };
|
package/docs/AGENT_GATEWAY_V0.md
CHANGED
|
@@ -75,7 +75,9 @@ Note `listAgents` takes `ListAgentsInput`, not a bare `AuthorizedAgentScope`.
|
|
|
75
75
|
|
|
76
76
|
### Output DTOs
|
|
77
77
|
|
|
78
|
-
`AgentSummary` (`agentTypeId`, `label`, `description?`, `definition?{version,digest}`),
|
|
78
|
+
`AgentSummary` (`agentTypeId`, `label`, `description?`, `definition?{version,digest?}`),
|
|
79
|
+
where `version` is the exact package declaration and `digest`, when available,
|
|
80
|
+
is the computed compiled-definition identity (not a re-hash of the response DTO),
|
|
79
81
|
`AgentSessionSummary` (`ref`, `title`, `status`, `createdAt`, `updatedAt`),
|
|
80
82
|
`AgentSessionPage` (`sessions`, `nextCursor?`), and the receipts
|
|
81
83
|
(`CommandReceipt`, `AgentSendReceipt`, `QueueClearReceipt`, `StopReceipt`) are
|
|
@@ -179,11 +181,29 @@ operations.
|
|
|
179
181
|
|
|
180
182
|
The Gateway request ledger is the only idempotency authority. A backend method
|
|
181
183
|
may be invoked again after a crash only through a ledger-admitted request; the
|
|
182
|
-
backend itself promises no deduplication.
|
|
184
|
+
backend itself promises no deduplication. A runtime load failure before the
|
|
185
|
+
effect begins records a retryable state, so the same request key and payload can
|
|
186
|
+
atomically reclaim admission after recovery; completed, rejected, in-flight, and
|
|
187
|
+
outcome-unknown records retain their normal replay behavior. P1-B substitutes the adapter-private
|
|
183
188
|
replay source below `HarnessPiChatService`, not this interface. Later operations
|
|
184
189
|
may extend the interface only in their named slices (`resumePausedToolCall` in
|
|
185
190
|
A3b and `markTurnInterrupted` in A4); neither is part of the current seam.
|
|
186
191
|
|
|
192
|
+
An explicit retryable admission result, or a returned prompt-state guard denial,
|
|
193
|
+
releases its pending claim before any effect. The ledger persists
|
|
194
|
+
`pending-admission` with `retryable: true`; `prepare` must atomically consume
|
|
195
|
+
that marker before returning `ownership: 'reclaimed'`. The original key and
|
|
196
|
+
payload digest stay binding, and overlapping requests still receive
|
|
197
|
+
`AGENT_REQUEST_IN_PROGRESS`. This applies to both ordinary and strict-idle
|
|
198
|
+
prompt guards, with their existing idle/error admission policies.
|
|
199
|
+
|
|
200
|
+
Custom `AgentRequestLedger` implementations must implement
|
|
201
|
+
`markAdmissionRetryable` and atomic reclaim, and refuse `acceptAdmission` until
|
|
202
|
+
the released claim has been reclaimed. A thrown admission/guard error does not
|
|
203
|
+
release ownership. Reopening a durable ledger permits only an explicitly marked
|
|
204
|
+
retry; unmarked pending, admission-accepted, in-flight and outcome-unknown rows
|
|
205
|
+
are never automatically re-executed. This is not general crash reconciliation.
|
|
206
|
+
|
|
187
207
|
CI pins the boundary in three directions: Agent Host production code cannot
|
|
188
208
|
import a Pi runtime, only `harnessBackend/**` can reference the concrete Pi chat
|
|
189
209
|
service, and Workspace/Core/CLI/playground consumers cannot name the private
|