@modelprofile.com/browser-runtime 1.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- export type TBrowserRuntimeErrorCode = 'ABORTED' | 'AUTHORIZATION_DENIED' | 'BUSY' | 'CAPABILITY_EXPIRED' | 'CAPABILITY_INVALID' | 'CAPABILITY_REVOKED' | 'CONFINEMENT_FAILED' | 'EGRESS_DENIED' | 'FENCED' | 'FRAME_TOO_LARGE' | 'INVALID_INPUT' | 'LOCKED' | 'NOT_RUNNING' | 'PROTOCOL_ERROR' | 'QUOTA_EXCEEDED' | 'TIMEOUT';
1
+ export type TBrowserRuntimeErrorCode = 'ABORTED' | 'AUTHORIZATION_DENIED' | 'ATTACHMENT_CONFLICT' | 'BUSY' | 'CAPABILITY_EXPIRED' | 'CAPABILITY_INVALID' | 'CAPABILITY_REVOKED' | 'CONFINEMENT_FAILED' | 'EGRESS_DENIED' | 'FENCED' | 'FRAME_TOO_LARGE' | 'INVALID_INPUT' | 'LOCKED' | 'NOT_RUNNING' | 'PROTOCOL_ERROR' | 'QUOTA_EXCEEDED' | 'RESOURCE_NOT_FOUND' | 'RESOURCE_RETIRED' | 'TIMEOUT';
2
2
  export declare class BrowserRuntimeError extends Error {
3
3
  readonly code: TBrowserRuntimeErrorCode;
4
4
  constructor(code: TBrowserRuntimeErrorCode, internalMessage?: string);
package/dist_ts/errors.js CHANGED
@@ -1,19 +1,22 @@
1
1
  const publicMessages = {
2
2
  ABORTED: 'The operation was aborted.',
3
3
  AUTHORIZATION_DENIED: 'Capability authorization was denied.',
4
- BUSY: 'The browser project is busy.',
4
+ ATTACHMENT_CONFLICT: 'The attachment binding conflicts with the current revision.',
5
+ BUSY: 'The browser resource is busy.',
5
6
  CAPABILITY_EXPIRED: 'The capability has expired.',
6
7
  CAPABILITY_INVALID: 'The capability is invalid.',
7
8
  CAPABILITY_REVOKED: 'The capability has been revoked.',
8
9
  CONFINEMENT_FAILED: 'Browser confinement could not be confirmed.',
9
10
  EGRESS_DENIED: 'The egress target was denied.',
10
- FENCED: 'The browser project is permanently fenced.',
11
+ FENCED: 'The browser resource is permanently fenced.',
11
12
  FRAME_TOO_LARGE: 'The browser frame exceeded its limit.',
12
13
  INVALID_INPUT: 'The request is invalid.',
13
14
  LOCKED: 'The browser runtime is already locked.',
14
15
  NOT_RUNNING: 'The browser runtime is not running.',
15
16
  PROTOCOL_ERROR: 'The framed protocol request is invalid.',
16
17
  QUOTA_EXCEEDED: 'A browser runtime quota was exceeded.',
18
+ RESOURCE_NOT_FOUND: 'The browser resource is not registered.',
19
+ RESOURCE_RETIRED: 'The browser resource has been retired.',
17
20
  TIMEOUT: 'The operation timed out.',
18
21
  };
19
22
  export class BrowserRuntimeError extends Error {
@@ -37,4 +40,4 @@ export const toBrowserRuntimeError = (error) => {
37
40
  }
38
41
  return new BrowserRuntimeError('ABORTED');
39
42
  };
40
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvZXJyb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWtCQSxNQUFNLGNBQWMsR0FBNkM7SUFDL0QsT0FBTyxFQUFFLDRCQUE0QjtJQUNyQyxvQkFBb0IsRUFBRSxzQ0FBc0M7SUFDNUQsSUFBSSxFQUFFLDhCQUE4QjtJQUNwQyxrQkFBa0IsRUFBRSw2QkFBNkI7SUFDakQsa0JBQWtCLEVBQUUsNEJBQTRCO0lBQ2hELGtCQUFrQixFQUFFLGtDQUFrQztJQUN0RCxrQkFBa0IsRUFBRSw2Q0FBNkM7SUFDakUsYUFBYSxFQUFFLCtCQUErQjtJQUM5QyxNQUFNLEVBQUUsNENBQTRDO0lBQ3BELGVBQWUsRUFBRSx1Q0FBdUM7SUFDeEQsYUFBYSxFQUFFLHlCQUF5QjtJQUN4QyxNQUFNLEVBQUUsd0NBQXdDO0lBQ2hELFdBQVcsRUFBRSxxQ0FBcUM7SUFDbEQsY0FBYyxFQUFFLHlDQUF5QztJQUN6RCxjQUFjLEVBQUUsdUNBQXVDO0lBQ3ZELE9BQU8sRUFBRSwwQkFBMEI7Q0FDcEMsQ0FBQztBQUVGLE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxLQUFLO0lBQzVCLElBQUksQ0FBMkI7SUFFL0MsWUFBWSxJQUE4QixFQUFFLGVBQXdCO1FBQ2xFLEtBQUssQ0FBQyxlQUFlLElBQUksY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLElBQUksR0FBRyxxQkFBcUIsQ0FBQztRQUNsQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNuQixDQUFDO0lBRUQsSUFBVyxhQUFhO1FBQ3RCLE9BQU8sY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDO0NBQ0Y7QUFFRCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLEtBQWMsRUFBdUIsRUFBRTtJQUMzRSxJQUFJLEtBQUssWUFBWSxtQkFBbUIsRUFBRSxDQUFDO1FBQ3pDLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELElBQ0UsS0FBSyxZQUFZLEtBQUs7V0FDbkIsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLFlBQVksSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLGNBQWMsQ0FBQyxFQUNqRSxDQUFDO1FBQ0QsT0FBTyxJQUFJLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssY0FBYyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFDRCxPQUFPLElBQUksbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDNUMsQ0FBQyxDQUFDIn0=
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvZXJyb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXFCQSxNQUFNLGNBQWMsR0FBNkM7SUFDL0QsT0FBTyxFQUFFLDRCQUE0QjtJQUNyQyxvQkFBb0IsRUFBRSxzQ0FBc0M7SUFDNUQsbUJBQW1CLEVBQUUsNkRBQTZEO0lBQ2xGLElBQUksRUFBRSwrQkFBK0I7SUFDckMsa0JBQWtCLEVBQUUsNkJBQTZCO0lBQ2pELGtCQUFrQixFQUFFLDRCQUE0QjtJQUNoRCxrQkFBa0IsRUFBRSxrQ0FBa0M7SUFDdEQsa0JBQWtCLEVBQUUsNkNBQTZDO0lBQ2pFLGFBQWEsRUFBRSwrQkFBK0I7SUFDOUMsTUFBTSxFQUFFLDZDQUE2QztJQUNyRCxlQUFlLEVBQUUsdUNBQXVDO0lBQ3hELGFBQWEsRUFBRSx5QkFBeUI7SUFDeEMsTUFBTSxFQUFFLHdDQUF3QztJQUNoRCxXQUFXLEVBQUUscUNBQXFDO0lBQ2xELGNBQWMsRUFBRSx5Q0FBeUM7SUFDekQsY0FBYyxFQUFFLHVDQUF1QztJQUN2RCxrQkFBa0IsRUFBRSx5Q0FBeUM7SUFDN0QsZ0JBQWdCLEVBQUUsd0NBQXdDO0lBQzFELE9BQU8sRUFBRSwwQkFBMEI7Q0FDcEMsQ0FBQztBQUVGLE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxLQUFLO0lBQzVCLElBQUksQ0FBMkI7SUFFL0MsWUFBWSxJQUE4QixFQUFFLGVBQXdCO1FBQ2xFLEtBQUssQ0FBQyxlQUFlLElBQUksY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLElBQUksR0FBRyxxQkFBcUIsQ0FBQztRQUNsQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNuQixDQUFDO0lBRUQsSUFBVyxhQUFhO1FBQ3RCLE9BQU8sY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDO0NBQ0Y7QUFFRCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLEtBQWMsRUFBdUIsRUFBRTtJQUMzRSxJQUFJLEtBQUssWUFBWSxtQkFBbUIsRUFBRSxDQUFDO1FBQ3pDLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELElBQ0UsS0FBSyxZQUFZLEtBQUs7V0FDbkIsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLFlBQVksSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLGNBQWMsQ0FBQyxFQUNqRSxDQUFDO1FBQ0QsT0FBTyxJQUFJLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssY0FBYyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFDRCxPQUFPLElBQUksbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDNUMsQ0FBQyxDQUFDIn0=
@@ -6,6 +6,6 @@ export { BrowserRuntimeFramedClient, BrowserRuntimeFramedServerPeer, } from './c
6
6
  export { BrowserRuntime, BrowserRuntimeLease } from './classes.runtime.js';
7
7
  export { BrowserRuntimeError } from './errors.js';
8
8
  export { createBrowserRuntimeMcpHttpHandler } from './mcp.js';
9
- export type { IAcquireBrowserRuntimeLeaseOptions } from './classes.runtime.js';
9
+ export type { TAcquireBrowserRuntimeLeaseOptions } from './classes.runtime.js';
10
10
  export type { TBrowserRuntimeErrorCode } from './errors.js';
11
- export type { IAttachTrustedFramedPeerOptions, IBrowserActionStateResult, IBrowserArtifactMetadata, IBrowserArtifactStoreOptions, IBrowserCapabilityAuthorizationRequest, IBrowserCapabilityDescriptor, IBrowserClickAction, IBrowserEgressConnectionOptions, IBrowserEgressProxyOptions, IBrowserEgressProxyStats, IBrowserFillAction, IBrowserNavigateAction, IBrowserObservationResult, IBrowserPressAction, IBrowserRuntimeAuditEvent, IBrowserRuntimeFlexToolProviderOptions, IBrowserRuntimeFrameSubscription, IBrowserRuntimeFramedClientOptions, IBrowserRuntimeMcpOptions, IBrowserRuntimeOperationOptions, IBrowserRuntimeOptions, IBrowserRuntimeState, IBrowserRuntimeTabState, IBrowserScreenshotAction, IBrowserScreenshotResult, IBrowserSnapshotAction, IIssueBrowserCapabilityRequest, IIssuedBrowserCapability, IResolvedBrowserFlexCapability, TBrowserActorRole, TBrowserAgentAction, TBrowserAgentActionResult, TBrowserCapabilitySource, TBrowserDnsResolver, TBrowserEgressConnector, TBrowserRuntimeEvent, } from './interfaces.js';
11
+ export type { IAttachTrustedFramedPeerOptions, IApplyBrowserAttachmentBindingRequest, IBrowserAttachmentBinding, IBrowserActionStateResult, IBrowserArtifactMetadata, IBrowserArtifactStoreOptions, IBrowserMcpAuthenticatedBinding, TBrowserCapabilityAuthorizationRequest, TBrowserCapabilityDescriptor, IBrowserClickAction, IBrowserEgressConnectionOptions, IBrowserEgressProxyOptions, IBrowserEgressProxyStats, IBrowserFlexCapabilityBinding, IBrowserFlexSessionId, IBrowserFillAction, IBrowserNavigateAction, IBrowserObservationResult, IBrowserOpenCodeSessionId, IBrowserPressAction, TBrowserRuntimeAuditEvent, TBrowserRuntimeOperationIdentity, IBrowserRuntimeFlexToolProviderOptions, IBrowserRuntimeFrameSubscription, IBrowserRuntimeFramedClientOptions, IBrowserRuntimeMcpOptions, IBrowserRuntimeOperationOptions, IBrowserRuntimeOptions, IBrowserResourceKey, IBrowserResourceRegistration, IBrowserRuntimeState, IBrowserRuntimeTabState, IBrowserScreenshotAction, IBrowserScreenshotResult, IBrowserSnapshotAction, ICreateBrowserResourceRequest, TIssueBrowserCapabilityRequest, TIssuedBrowserCapability, TQualifiedBrowserSessionId, IRegisterBrowserResourceRequest, IResolvedBrowserFlexCapability, TBrowserActorRole, TBrowserAgentAction, TBrowserAgentActionResult, TBrowserCapabilitySource, TBrowserDnsResolver, TBrowserEgressConnector, TBrowserHarnessId, TBrowserRuntimeEvent, } from './interfaces.js';
@@ -1,42 +1,103 @@
1
1
  import type * as plugins from './plugins.js';
2
+ import type { BrowserEgressProxy } from './classes.egressproxy.js';
3
+ import type { BrowserRuntimeFramedClient } from './classes.framed.js';
2
4
  export type TBrowserActorRole = 'human' | 'agent';
3
5
  export type TBrowserCapabilitySource = 'human' | 'flex' | 'mcp';
4
- export interface IBrowserCapabilityAuthorizationRequest {
6
+ export type TBrowserHarnessId = 'opencode' | 'flex';
7
+ export interface IBrowserOpenCodeSessionId {
8
+ harnessId: 'opencode';
9
+ nativeId: string;
10
+ }
11
+ export interface IBrowserFlexSessionId {
12
+ harnessId: 'flex';
13
+ nativeId: string;
14
+ }
15
+ export type TQualifiedBrowserSessionId = IBrowserOpenCodeSessionId | IBrowserFlexSessionId;
16
+ export interface IBrowserResourceKey {
17
+ projectId: string;
18
+ browserResourceId: string;
19
+ }
20
+ export interface IBrowserAttachmentBinding {
21
+ attachmentAuthorityId: string;
22
+ attachmentRevision: number;
23
+ sessionId: TQualifiedBrowserSessionId | null;
24
+ }
25
+ export interface ICreateBrowserResourceRequest {
5
26
  projectId: string;
27
+ attachmentBinding: IBrowserAttachmentBinding;
28
+ }
29
+ export interface IRegisterBrowserResourceRequest extends IBrowserResourceKey {
30
+ attachmentBinding: IBrowserAttachmentBinding;
31
+ }
32
+ export interface IApplyBrowserAttachmentBindingRequest extends IBrowserResourceKey {
33
+ attachmentBinding: IBrowserAttachmentBinding;
34
+ }
35
+ export interface IBrowserResourceRegistration extends IBrowserResourceKey {
36
+ registeredAt: number;
37
+ attachmentBinding: IBrowserAttachmentBinding;
38
+ incarnationStatus: 'absent' | 'running' | 'fenced';
39
+ incarnationGeneration: number;
40
+ retirementPending: boolean;
41
+ }
42
+ export interface IBrowserCapabilityBindingBase extends IBrowserResourceKey {
43
+ attachmentAuthorityId: string;
44
+ attachmentRevision: number;
6
45
  actorId: string;
7
- role: TBrowserActorRole;
8
46
  peerId: string;
9
- source: TBrowserCapabilitySource;
10
- scopeId?: string;
11
- sessionId?: string;
12
47
  }
13
- export interface IIssueBrowserCapabilityRequest extends IBrowserCapabilityAuthorizationRequest {
48
+ export interface IBrowserHumanCapabilityBinding extends IBrowserCapabilityBindingBase {
49
+ role: 'human';
50
+ source: 'human';
51
+ sessionId?: never;
52
+ scopeId?: never;
53
+ channelId?: never;
54
+ }
55
+ export interface IBrowserFlexCapabilityBinding extends IBrowserCapabilityBindingBase {
56
+ role: 'agent';
57
+ source: 'flex';
58
+ sessionId: IBrowserFlexSessionId;
59
+ scopeId: string;
60
+ channelId: string;
61
+ }
62
+ export interface IBrowserMcpCapabilityBinding extends IBrowserCapabilityBindingBase {
63
+ role: 'agent';
64
+ source: 'mcp';
65
+ sessionId: IBrowserOpenCodeSessionId;
66
+ scopeId?: never;
67
+ channelId?: never;
68
+ }
69
+ export type TBrowserCapabilityAuthorizationRequest = IBrowserHumanCapabilityBinding | IBrowserFlexCapabilityBinding | IBrowserMcpCapabilityBinding;
70
+ export type TIssueBrowserCapabilityRequest = TBrowserCapabilityAuthorizationRequest & {
14
71
  expiresInMs?: number;
15
72
  disconnect?: (signal: AbortSignal) => Promise<void> | void;
16
- }
17
- export interface IBrowserCapabilityDescriptor extends IBrowserCapabilityAuthorizationRequest {
73
+ };
74
+ export type TBrowserCapabilityDescriptor = TBrowserCapabilityAuthorizationRequest & {
18
75
  capabilityId: string;
19
76
  expiresAt: number;
20
- }
21
- export interface IIssuedBrowserCapability extends IBrowserCapabilityDescriptor {
77
+ };
78
+ export type TIssuedBrowserCapability = TBrowserCapabilityDescriptor & {
22
79
  capabilityToken: string;
23
- }
80
+ };
24
81
  export interface IResolvedBrowserFlexCapability {
25
82
  capabilityToken: string;
26
83
  }
27
- export interface IBrowserRuntimeAuditEvent {
28
- operationId: string;
29
- capabilityId: string;
30
- projectId: string;
31
- actorId: string;
32
- role: TBrowserActorRole;
33
- source: TBrowserCapabilitySource;
34
- action: string;
35
- phase: 'completed' | 'failed';
36
- startedAt: number;
37
- finishedAt: number;
38
- errorCode?: string;
39
- }
84
+ type TReadonlyBrowserCapabilityAuthorizationRequest = Readonly<IBrowserHumanCapabilityBinding> | (Omit<Readonly<IBrowserFlexCapabilityBinding>, 'sessionId'> & {
85
+ readonly sessionId: Readonly<IBrowserFlexSessionId>;
86
+ }) | (Omit<Readonly<IBrowserMcpCapabilityBinding>, 'sessionId'> & {
87
+ readonly sessionId: Readonly<IBrowserOpenCodeSessionId>;
88
+ });
89
+ export type TBrowserRuntimeOperationIdentity = TReadonlyBrowserCapabilityAuthorizationRequest & {
90
+ readonly operationId: string;
91
+ readonly capabilityId: string;
92
+ readonly leaseId: string;
93
+ readonly action: string;
94
+ readonly startedAt: number;
95
+ };
96
+ export type TBrowserRuntimeAuditEvent = TBrowserRuntimeOperationIdentity & {
97
+ readonly phase: 'completed' | 'failed';
98
+ readonly finishedAt: number;
99
+ readonly errorCode?: string;
100
+ };
40
101
  export interface ILiveBrowserSessionLike {
41
102
  start(options?: plugins.smartpuppeteer.ILiveBrowserOperationOptions): Promise<void>;
42
103
  stop(): Promise<void>;
@@ -64,9 +125,9 @@ export interface ILiveBrowserSessionLike {
64
125
  fill(options: plugins.smartpuppeteer.ILiveBrowserFillOptions, operationOptions?: plugins.smartpuppeteer.ILiveBrowserOperationOptions): Promise<void>;
65
126
  press(options: plugins.smartpuppeteer.ILiveBrowserPressOptions, operationOptions?: plugins.smartpuppeteer.ILiveBrowserOperationOptions): Promise<void>;
66
127
  }
67
- export interface IBrowserConfinementProbeContext {
128
+ export interface IBrowserConfinementProbeContext extends IBrowserResourceKey {
68
129
  session: ILiveBrowserSessionLike;
69
- proxy: import('./classes.egressproxy.js').BrowserEgressProxy;
130
+ proxy: BrowserEgressProxy;
70
131
  signal: AbortSignal;
71
132
  }
72
133
  export interface IBrowserRuntimeEnvironment {
@@ -75,25 +136,31 @@ export interface IBrowserRuntimeEnvironment {
75
136
  }
76
137
  export interface IBrowserRuntimeOptions {
77
138
  runtimeDirectory: string;
78
- authorizeCapability(request: IBrowserCapabilityAuthorizationRequest, signal: AbortSignal): Promise<boolean> | boolean;
79
- audit?(event: IBrowserRuntimeAuditEvent, signal: AbortSignal): Promise<void> | void;
80
- maxProjectSlots?: number;
139
+ authorizeCapability(request: TBrowserCapabilityAuthorizationRequest, signal: AbortSignal): Promise<boolean> | boolean;
140
+ beforeOperation?(operation: TBrowserRuntimeOperationIdentity, signal: AbortSignal): Promise<void> | void;
141
+ audit?(event: TBrowserRuntimeAuditEvent, signal: AbortSignal): Promise<void> | void;
142
+ maxResources?: number;
143
+ maxResourcesPerProject?: number;
144
+ maxRunningResources?: number;
145
+ maxRunningResourcesPerProject?: number;
81
146
  maxCapabilities?: number;
147
+ maxCapabilitiesPerResource?: number;
82
148
  maxCapabilitiesPerProject?: number;
83
149
  capabilityDefaultTtlMs?: number;
84
150
  capabilityMaximumTtlMs?: number;
85
151
  authorizationTimeoutMs?: number;
86
- maxTabsPerProject?: number;
152
+ beforeOperationTimeoutMs?: number;
153
+ maxTabsPerResource?: number;
87
154
  operationTimeoutMs?: number;
88
155
  quiescenceTimeoutMs?: number;
89
156
  terminationGraceMs?: number;
90
157
  terminationForceMs?: number;
91
158
  auditTimeoutMs?: number;
92
159
  confinementProbeTimeoutMs?: number;
93
- idleRetirementMs?: number;
160
+ idleTerminationMs?: number;
94
161
  maxFrameBytes?: number;
95
162
  frameAcknowledgementTimeoutMs?: number;
96
- egress?: Omit<IBrowserEgressProxyOptions, 'projectId'>;
163
+ egress?: Omit<IBrowserEgressProxyOptions, 'projectId' | 'browserResourceId'>;
97
164
  artifacts?: Omit<IBrowserArtifactStoreOptions, 'rootDirectory'>;
98
165
  }
99
166
  export interface IBrowserRuntimeTabState {
@@ -122,9 +189,8 @@ export interface IBrowserRuntimeState {
122
189
  tabId?: string;
123
190
  };
124
191
  }
125
- export interface IBrowserArtifactMetadata {
192
+ export interface IBrowserArtifactMetadata extends IBrowserResourceKey {
126
193
  artifactId: string;
127
- projectId: string;
128
194
  mimeType: string;
129
195
  size: number;
130
196
  createdAt: number;
@@ -133,6 +199,8 @@ export interface IBrowserArtifactMetadata {
133
199
  export interface IBrowserArtifactStoreOptions {
134
200
  rootDirectory: string;
135
201
  maxFileBytes?: number;
202
+ maxArtifactsPerResource?: number;
203
+ maxResourceBytes?: number;
136
204
  maxArtifactsPerProject?: number;
137
205
  maxProjectBytes?: number;
138
206
  maxProjects?: number;
@@ -232,8 +300,7 @@ export interface IBrowserEgressConnectionOptions {
232
300
  signal: AbortSignal;
233
301
  }
234
302
  export type TBrowserEgressConnector = (options: IBrowserEgressConnectionOptions) => plugins.net.Socket;
235
- export interface IBrowserEgressProxyOptions {
236
- projectId: string;
303
+ export interface IBrowserEgressProxyOptions extends IBrowserResourceKey {
237
304
  allowedPorts?: number[];
238
305
  maxConnections?: number;
239
306
  maxActiveRequests?: number;
@@ -255,26 +322,30 @@ export interface IBrowserEgressProxyStats {
255
322
  rejectedRequests: number;
256
323
  activeConnections: number;
257
324
  }
258
- export interface IAttachTrustedFramedPeerOptions {
259
- peerId: string;
260
- scopeId: string;
261
- sessionId: string;
325
+ export interface IAttachTrustedFramedPeerOptions extends Omit<IBrowserFlexCapabilityBinding, 'role' | 'source'> {
326
+ role: 'agent';
327
+ source: 'flex';
262
328
  readable: plugins.stream.Readable;
263
329
  writable: plugins.stream.Writable;
264
330
  }
265
- export interface IBrowserRuntimeFramedClientOptions {
266
- scopeId: string;
267
- sessionId: string;
331
+ export interface IBrowserRuntimeFramedClientOptions extends Omit<IBrowserFlexCapabilityBinding, 'role' | 'source'> {
332
+ role: 'agent';
333
+ source: 'flex';
268
334
  readable: plugins.stream.Readable;
269
335
  writable: plugins.stream.Writable;
270
336
  maxFrameBytes?: number;
271
337
  maxPendingRequests?: number;
272
338
  requestTimeoutMs?: number;
273
339
  }
340
+ export interface IBrowserMcpAuthenticatedBinding extends IBrowserCapabilityBindingBase {
341
+ role: 'agent';
342
+ source: 'mcp';
343
+ sessionId: IBrowserOpenCodeSessionId;
344
+ scopeId?: never;
345
+ channelId?: never;
346
+ }
274
347
  export interface IBrowserRuntimeMcpOptions {
275
- authenticateMcpRequest(request: Request): Promise<{
276
- peerId: string;
277
- }>;
348
+ authenticateMcpRequest(request: Request): Promise<IBrowserMcpAuthenticatedBinding>;
278
349
  trustedOrigins?: string[];
279
350
  allowedHosts?: string[];
280
351
  allowMissingOrigin?: boolean;
@@ -282,6 +353,7 @@ export interface IBrowserRuntimeMcpOptions {
282
353
  maxToolResultBytes?: number;
283
354
  }
284
355
  export interface IBrowserRuntimeFlexToolProviderOptions<TScope> {
285
- client: import('./classes.framed.js').BrowserRuntimeFramedClient;
356
+ client: BrowserRuntimeFramedClient;
286
357
  resolveCapability(context: plugins.flexharness.IFlexToolProviderContext<TScope>): Promise<IResolvedBrowserFlexCapability> | IResolvedBrowserFlexCapability;
287
358
  }
359
+ export {};
@@ -1,9 +1,18 @@
1
1
  import type * as plugins from './plugins.js';
2
- import type { IBrowserConfinementProbeContext, IBrowserRuntimeOptions, IBrowserRuntimeEnvironment, ILiveBrowserSessionLike } from './interfaces.js';
2
+ import type { IBrowserConfinementProbeContext, IBrowserRuntimeFramedClientOptions, IBrowserRuntimeOptions, IBrowserRuntimeEnvironment, ILiveBrowserSessionLike } from './interfaces.js';
3
3
  export declare const browserRuntimeTesting: unique symbol;
4
4
  export interface IBrowserRuntimeTestingOptions extends IBrowserRuntimeOptions {
5
5
  [browserRuntimeTesting]: true;
6
6
  environment: IBrowserRuntimeEnvironment;
7
7
  sessionFactory(options: plugins.smartpuppeteer.ILiveBrowserSessionOptions): ILiveBrowserSessionLike;
8
8
  confinementProbe(context: IBrowserConfinementProbeContext): Promise<void>;
9
+ beforeLeasePublication?(): Promise<void>;
10
+ beforeIdleTermination?(): Promise<void>;
11
+ beforeFrameFailureTermination?(): Promise<void>;
12
+ afterFrameFailureFence?(): Promise<void>;
13
+ beforeFramedPeerLeasePublication?(): Promise<void>;
14
+ }
15
+ export interface IBrowserRuntimeFramedClientTestingOptions extends IBrowserRuntimeFramedClientOptions {
16
+ [browserRuntimeTesting]: true;
17
+ afterAcquireResponse?(): Promise<void>;
9
18
  }
@@ -1,2 +1,2 @@
1
1
  export const browserRuntimeTesting = Symbol('browserRuntimeTesting');
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJuYWwudGVzdGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2ludGVybmFsLnRlc3RpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBUUEsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUMifQ==
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJuYWwudGVzdGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2ludGVybmFsLnRlc3RpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBU0EsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUMifQ==
package/dist_ts/mcp.js CHANGED
@@ -33,19 +33,17 @@ export const createBrowserRuntimeMcpHttpHandler = (runtime, options) => {
33
33
  ? 256 * 1024
34
34
  : validateInteger(options.maxToolResultBytes, 'maxToolResultBytes', 1024, 256 * 1024);
35
35
  const withLease = async (context, action) => {
36
- const peerId = validateBoundedString(context.authInfo?.clientId, 'peerId', 1, 128);
36
+ const binding = parseMcpAuthBinding(context.authInfo?.scopes);
37
37
  const capabilityToken = parseBearerToken(context.request);
38
38
  const signal = AbortSignal.any([context.extra.signal, context.request.signal]);
39
39
  signal.throwIfAborted();
40
- const descriptor = runtime.authorizeCapability(capabilityToken, peerId, 'agent', 'mcp');
40
+ const descriptor = runtime.authorizeCapability(capabilityToken, binding);
41
41
  if (descriptor.capabilityId !== context.authInfo?.token) {
42
42
  throw new BrowserRuntimeError('CAPABILITY_INVALID');
43
43
  }
44
44
  const lease = await runtime.acquireLease({
45
45
  capabilityToken,
46
- peerId,
47
- expectedRole: 'agent',
48
- expectedSource: 'mcp',
46
+ ...binding,
49
47
  signal,
50
48
  });
51
49
  try {
@@ -172,17 +170,16 @@ export const createBrowserRuntimeMcpHttpHandler = (runtime, options) => {
172
170
  maxToolResultBytes,
173
171
  redactError: () => 'Browser tool execution failed.',
174
172
  authorize: async ({ request }) => {
175
- let peerId;
176
173
  let capabilityToken;
177
174
  try {
178
175
  const authentication = await options.authenticateMcpRequest(request);
179
- peerId = validateBoundedString(authentication?.peerId, 'peerId', 1, 128);
176
+ const binding = validateMcpBinding(authentication);
180
177
  capabilityToken = parseBearerToken(request);
181
- const descriptor = runtime.authorizeCapability(capabilityToken, peerId, 'agent', 'mcp');
178
+ const descriptor = runtime.authorizeCapability(capabilityToken, binding);
182
179
  return {
183
180
  token: descriptor.capabilityId,
184
- clientId: peerId,
185
- scopes: ['browser'],
181
+ clientId: binding.peerId,
182
+ scopes: [serializeMcpAuthBinding(binding)],
186
183
  expiresAt: descriptor.expiresAt,
187
184
  };
188
185
  }
@@ -193,4 +190,41 @@ export const createBrowserRuntimeMcpHttpHandler = (runtime, options) => {
193
190
  tools,
194
191
  });
195
192
  };
196
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvbWNwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFckQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pELE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsZUFBZSxHQUNoQixNQUFNLFlBQVksQ0FBQztBQUVwQixNQUFNLGdCQUFnQixHQUFHLENBQUMsT0FBZ0IsRUFBVSxFQUFFO0lBQ3BELE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQzNELElBQUksQ0FBQyxhQUFhLEVBQUUsVUFBVSxDQUFDLFNBQVMsQ0FBQyxJQUFJLGFBQWEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN6RSxNQUFNLElBQUksbUJBQW1CLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBQ0QsT0FBTyxxQkFBcUIsQ0FDMUIsYUFBYSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQ3JDLG1CQUFtQixFQUNuQixFQUFFLEVBQ0YsR0FBRyxDQUNKLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLGtCQUFrQixHQUFHLENBQUMsS0FBYyxFQUFFLElBQVksRUFBd0IsRUFBRTtJQUNoRixJQUFJLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDMUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxFQUFFO1FBQUUsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGVBQWUs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
193
+ const validateMcpBinding = (value) => {
194
+ if (!value || typeof value !== 'object')
195
+ throw new BrowserRuntimeError('CAPABILITY_INVALID');
196
+ const binding = value;
197
+ if (binding.role !== 'agent' || binding.source !== 'mcp') {
198
+ throw new BrowserRuntimeError('CAPABILITY_INVALID');
199
+ }
200
+ const session = binding.sessionId;
201
+ if (session?.harnessId !== 'opencode')
202
+ throw new BrowserRuntimeError('CAPABILITY_INVALID');
203
+ return {
204
+ projectId: validateBoundedString(binding.projectId, 'projectId', 1, 256),
205
+ browserResourceId: validateBoundedString(binding.browserResourceId, 'browserResourceId', 16, 256),
206
+ attachmentAuthorityId: validateBoundedString(binding.attachmentAuthorityId, 'attachmentAuthorityId', 1, 256),
207
+ attachmentRevision: validateInteger(binding.attachmentRevision, 'attachmentRevision', 0, Number.MAX_SAFE_INTEGER),
208
+ actorId: validateBoundedString(binding.actorId, 'actorId', 1, 256),
209
+ role: 'agent',
210
+ peerId: validateBoundedString(binding.peerId, 'peerId', 1, 256),
211
+ source: 'mcp',
212
+ sessionId: {
213
+ harnessId: 'opencode',
214
+ nativeId: validateBoundedString(session.nativeId, 'sessionId.nativeId', 1, 256),
215
+ },
216
+ };
217
+ };
218
+ const serializeMcpAuthBinding = (binding) => plugins.Buffer.from(JSON.stringify(binding), 'utf8').toString('base64url');
219
+ const parseMcpAuthBinding = (scopes) => {
220
+ if (!Array.isArray(scopes) || scopes.length !== 1) {
221
+ throw new BrowserRuntimeError('CAPABILITY_INVALID');
222
+ }
223
+ try {
224
+ return validateMcpBinding(JSON.parse(plugins.Buffer.from(scopes[0], 'base64url').toString('utf8')));
225
+ }
226
+ catch {
227
+ throw new BrowserRuntimeError('CAPABILITY_INVALID');
228
+ }
229
+ };
230
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvbWNwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFLckQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pELE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsZUFBZSxHQUNoQixNQUFNLFlBQVksQ0FBQztBQUVwQixNQUFNLGdCQUFnQixHQUFHLENBQUMsT0FBZ0IsRUFBVSxFQUFFO0lBQ3BELE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQzNELElBQUksQ0FBQyxhQUFhLEVBQUUsVUFBVSxDQUFDLFNBQVMsQ0FBQyxJQUFJLGFBQWEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN6RSxNQUFNLElBQUksbUJBQW1CLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBQ0QsT0FBTyxxQkFBcUIsQ0FDMUIsYUFBYSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQ3JDLG1CQUFtQixFQUNuQixFQUFFLEVBQ0YsR0FBRyxDQUNKLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLGtCQUFrQixHQUFHLENBQUMsS0FBYyxFQUFFLElBQVksRUFBd0IsRUFBRTtJQUNoRixJQUFJLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDMUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxFQUFFO1FBQUUsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGVBQWUs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
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@modelprofile.com/browser-runtime",
3
- "version": "1.0.1",
3
+ "version": "2.1.0",
4
4
  "private": false,
5
- "description": "Parent-owned, project-scoped Chromium runtime with authenticated human and agent control, fail-closed egress, bounded artifacts, and Flex/MCP adapters.",
5
+ "description": "Parent-owned, resource-centric Chromium runtime with revisioned attachment fencing, authenticated human and agent control, fail-closed egress, bounded artifacts, and Flex/MCP adapters.",
6
6
  "main": "dist_ts/index.js",
7
7
  "typings": "dist_ts/index.d.ts",
8
8
  "type": "module",
package/readme.hints.md CHANGED
@@ -4,32 +4,37 @@ Durable implementation findings for `@modelprofile.com/browser-runtime`.
4
4
 
5
5
  ## Ownership and lifecycle
6
6
 
7
- - Capability authorization uses bounded pending reservations. A project slot is inserted only after host authorization succeeds, so denied project IDs cannot consume slot quota. Its transition mutex, generation, lease, active operation, frame subscriber, browser session, proxy, profile, and idle timer form one ownership domain.
8
- - Agent lease admission and every agent operation use try-lock semantics. A transition, lease, or operation returns `BUSY`; work is never queued behind another agent operation.
9
- - Human admission marks a fencing generation, aborts an agent lease and operation, releases the mutex while waiting, and verifies the same generation before publishing the human lease. Work that does not quiesce is escalated through `LiveBrowserSession.terminate()`.
10
- - Profiles are deleted or reused only after confirmed process-group death. An unconfirmed termination permanently fences the slot and leaves the session/profile ownership reachable for a later retirement or `stop()` retry.
11
- - The runtime lock is created with `open(..., 'wx')` and is never treated as stale. A failed start after lock acquisition retains lock ownership so the same runtime object can retry or stop cleanly.
7
+ - Controller durable truth is a logical resource with immutable `projectId`, stable random `browserResourceId`, and a revisioned attachment binding. Runtime state is process-local and must be re-registered after every restart.
8
+ - A resource slot owns only incarnation and arbitration state: its transition mutex, arbitration and incarnation generations, lease, operation, frame subscriber, Chromium session, authenticated egress proxy, private profile, and idle termination timer.
9
+ - `terminateResource()` and idle termination remove only the incarnation. They preserve registration, attachment, capabilities, and artifacts. `retireResource()` permanently fences, revokes, terminates, purges exact-resource artifacts, then unregisters only after all cleanup succeeds. Durable retirement remains Controller truth; Runtime tombstones are bounded and process-local.
10
+ - Failed retirement retains a fenced, retryable registration. Unknown profile, lock, or artifact ownership remains fail closed.
11
+ - Launch quota admission uses synchronous pending reservations across global and per-project running-resource limits.
12
12
 
13
- ## Capability boundary
13
+ ## Attachment and capability boundary
14
14
 
15
- - Capability tokens are returned once. Runtime records retain only SHA-256 digests and compare exact digests with `timingSafeEqual`; project, actor, role, peer, source, optional Flex scope/session, and expiry are immutable server-owned bindings.
16
- - Expiry and revocation abort work, close frame state, release the lease, and invoke the host disconnect callback or close the exact trusted framed peer. Cleanup remains tracked and `stop()` drains it.
17
- - Operation IDs are generated independently from capability, lease, framed request, tab, and artifact IDs. Audit callbacks receive bounded metadata and are time-bounded.
15
+ - Attachment revision is independent from incarnation and arbitration generations. Equal revisions are idempotent only for an identical binding; lower or conflicting equal revisions fail.
16
+ - Any `sessionId: null` binding is detached; revision zero is specifically the initial detached/no-agent-authority state. A newer attachment synchronously closes admission before waiting for the resource mutex, revokes its capabilities, and quiesces its active work. Work that ignores cancellation escalates only that resource incarnation.
17
+ - Agent capabilities require the exact current non-detached qualified session. Human capabilities bind the exact resource, project, attachment authority, and revision but intentionally carry no session ID and may be issued while detached. Any attachment advance revokes both human and agent capabilities.
18
+ - Capability tokens are returned once. Runtime records retain only SHA-256 digests and use `timingSafeEqual`. Authorization is rechecked after asynchronous host authorization, during lease acquisition, and before and after every operation.
19
+ - Capability, audit, and lease identity includes immutable project, resource, attachment authority and revision, actor, peer, role, source, qualified agent session, and Flex scope/channel where applicable.
20
+ - `beforeOperation` reserves the exact resource and lets the host persist policy/audit through an awaited fail-closed gate. Runtime then atomically revalidates lease, attachment, session, arbitration generation, and incarnation before starting the side effect. Terminal audit remains best effort, uses the same operation ID, and runs after bounded cleanup releases or fences the exact reservation.
18
21
 
19
22
  ## Browser confinement
20
23
 
21
- - Production session options are assembled only inside `BrowserRuntime`: sandbox required, random private user data directory, authenticated project proxy, fixed network-reduction arguments, external browser DNS failure rules, denied downloads/file choosers/permissions, and HTTP(S)-only public navigation. Deterministic injection uses a non-root-exported test symbol and is not part of the package API.
22
- - `allowEvaluation` exists only to run the private confinement probe. No runtime lease, framed message, Flex tool, or MCP tool projects evaluation.
23
- - The production probe owns a random loopback origin on a port outside the project allowlist, checks proxy traversal plus zero origin hits, checks synthetic `.invalid` traversal, and checks forced WebRTC policy by observing ICE candidates.
24
+ - Production session options are assembled only inside `BrowserRuntime`: sandbox required, random private per-resource user data directory, one authenticated proxy per running resource, fixed network-reduction arguments, denied downloads/file choosers/permissions, and HTTP(S)-only public navigation.
25
+ - `allowEvaluation` exists only for the private confinement probe. No runtime lease, framed message, Flex tool, or MCP tool exposes evaluation.
26
+ - The production probe verifies loopback denial, synthetic `.invalid` traversal, and forced WebRTC suppression through the resource's proxy.
24
27
 
25
28
  ## Egress and artifacts
26
29
 
27
- - HTTP absolute-form, WebSocket Upgrade, and CONNECT all use the same canonical target resolver. Every DNS answer must be public unicast; one bad answer rejects the entire set. The selected answer is dialed numerically through the connector seam.
28
- - Origin host semantics remain in `Host`; CONNECT leaves end-to-end TLS/SNI untouched. Proxy authorization and inherited hop-by-hop headers never reach upstreams.
29
- - Artifact path components are generated or keyed digests, never caller IDs. The store exclusively owns its root; serialized admission enforces project and aggregate quotas. Writes are private, temporary, synced, and atomically renamed; reads use no-follow handles and verify size plus SHA-256.
30
+ - HTTP absolute-form, WebSocket Upgrade, and CONNECT use one fail-closed target resolver. Every DNS answer must be public unicast and the selected answer is dialed numerically.
31
+ - Egress proxies carry immutable `projectId` and `browserResourceId`; credentials are private and one proxy exists per running resource.
32
+ - Artifact identity is `(projectId, browserResourceId, artifactId)`. Paths use keyed project and resource digests, and quotas apply per resource, per project, and globally.
33
+ - Artifact writes are private, temporary, synced, and atomically renamed. Reads use no-follow handles and verify size plus SHA-256. Human leases can read or delete artifacts only from their exact resource.
30
34
 
31
35
  ## Adapter boundary
32
36
 
33
- - Framed messages contain no project, actor, role, source, scope, session, or peer selectors. The parent supplies peer, Flex scope, and Flex session out of band, and only one attached framed peer may own a peer ID.
34
- - Flex resolves only a token; framed acquisition validates its immutable server-side `flex` source and scope/session bindings. SmartAgent's browser tool is configured with exactly navigate, snapshot, screenshot, click, fill, and press.
35
- - MCP performs independent request authentication before bearer validation. Its tool list contains exactly the same six actions. Every call verifies the immutable authorization identity, acquires and releases an MCP-source agent lease, and combines SmartMCP's tool signal with the Web request signal.
37
+ - Framed messages contain no identity selectors. The parent binds project, resource, attachment authority/revision, actor, peer, role, source, qualified session, Flex scope, and channel out of band.
38
+ - One qualified session can own multiple resource-specific framed channels. Capability revocation owns server-peer disconnect; peer-initiated release/close revokes only that channel's capability without recursively disconnecting itself.
39
+ - Flex resolves only a capability token. SmartAgent exposes exactly navigate, snapshot, screenshot, click, fill, and press.
40
+ - MCP independent authentication returns the complete expected binding. The binding is retained in server-owned auth context and tool schemas expose no resource, session, revision, or authority selector.