@cat-factory/gatekeeper-worker 0.4.3 → 0.6.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.
Files changed (101) hide show
  1. package/README.md +100 -13
  2. package/dist/arguments.d.ts +18 -0
  3. package/dist/arguments.d.ts.map +1 -0
  4. package/dist/arguments.js +75 -0
  5. package/dist/arguments.js.map +1 -0
  6. package/dist/capability.d.ts +55 -0
  7. package/dist/capability.d.ts.map +1 -1
  8. package/dist/capability.js +99 -5
  9. package/dist/capability.js.map +1 -1
  10. package/dist/env.d.ts +10 -0
  11. package/dist/env.d.ts.map +1 -1
  12. package/dist/env.js +12 -0
  13. package/dist/env.js.map +1 -1
  14. package/dist/errors.d.ts +32 -1
  15. package/dist/errors.d.ts.map +1 -1
  16. package/dist/errors.js +11 -0
  17. package/dist/errors.js.map +1 -1
  18. package/dist/gatekeeper.d.ts +78 -3
  19. package/dist/gatekeeper.d.ts.map +1 -1
  20. package/dist/gatekeeper.js +127 -13
  21. package/dist/gatekeeper.js.map +1 -1
  22. package/dist/index.d.ts +18 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +19 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/markdown.d.ts +12 -0
  27. package/dist/markdown.d.ts.map +1 -0
  28. package/dist/markdown.js +28 -0
  29. package/dist/markdown.js.map +1 -0
  30. package/dist/os/account.d.ts +27 -0
  31. package/dist/os/account.d.ts.map +1 -0
  32. package/dist/os/account.js +130 -0
  33. package/dist/os/account.js.map +1 -0
  34. package/dist/os/descriptions.d.ts +43 -0
  35. package/dist/os/descriptions.d.ts.map +1 -0
  36. package/dist/os/descriptions.js +100 -0
  37. package/dist/os/descriptions.js.map +1 -0
  38. package/dist/os/discoverability.d.ts +42 -0
  39. package/dist/os/discoverability.d.ts.map +1 -0
  40. package/dist/os/discoverability.js +63 -0
  41. package/dist/os/discoverability.js.map +1 -0
  42. package/dist/os/exports.d.ts +55 -0
  43. package/dist/os/exports.d.ts.map +1 -0
  44. package/dist/os/exports.js +93 -0
  45. package/dist/os/exports.js.map +1 -0
  46. package/dist/os/hook-controller.d.ts +14 -0
  47. package/dist/os/hook-controller.d.ts.map +1 -0
  48. package/dist/os/hook-controller.js +53 -0
  49. package/dist/os/hook-controller.js.map +1 -0
  50. package/dist/os/hooks.d.ts +200 -0
  51. package/dist/os/hooks.d.ts.map +1 -0
  52. package/dist/os/hooks.js +253 -0
  53. package/dist/os/hooks.js.map +1 -0
  54. package/dist/os/protocol.d.ts +193 -0
  55. package/dist/os/protocol.d.ts.map +1 -0
  56. package/dist/os/protocol.js +22 -0
  57. package/dist/os/protocol.js.map +1 -0
  58. package/dist/os/queue.d.ts +99 -0
  59. package/dist/os/queue.d.ts.map +1 -0
  60. package/dist/os/queue.js +240 -0
  61. package/dist/os/queue.js.map +1 -0
  62. package/dist/os/resource-core.d.ts +115 -0
  63. package/dist/os/resource-core.d.ts.map +1 -0
  64. package/dist/os/resource-core.js +172 -0
  65. package/dist/os/resource-core.js.map +1 -0
  66. package/dist/os/resource.d.ts +16 -0
  67. package/dist/os/resource.d.ts.map +1 -0
  68. package/dist/os/resource.js +70 -0
  69. package/dist/os/resource.js.map +1 -0
  70. package/dist/os/resources.d.ts +11 -0
  71. package/dist/os/resources.d.ts.map +1 -0
  72. package/dist/os/resources.js +26 -0
  73. package/dist/os/resources.js.map +1 -0
  74. package/dist/os/session-types.d.ts +6 -0
  75. package/dist/os/session-types.d.ts.map +1 -0
  76. package/dist/os/session-types.js +110 -0
  77. package/dist/os/session-types.js.map +1 -0
  78. package/dist/os/sharing.d.ts +35 -0
  79. package/dist/os/sharing.d.ts.map +1 -0
  80. package/dist/os/sharing.js +135 -0
  81. package/dist/os/sharing.js.map +1 -0
  82. package/dist/os/vendor.d.ts +14 -0
  83. package/dist/os/vendor.d.ts.map +1 -0
  84. package/dist/os/vendor.js +102 -0
  85. package/dist/os/vendor.js.map +1 -0
  86. package/dist/policy/compile.d.ts +38 -0
  87. package/dist/policy/compile.d.ts.map +1 -1
  88. package/dist/policy/compile.js +42 -4
  89. package/dist/policy/compile.js.map +1 -1
  90. package/dist/policy/index.d.ts +1 -1
  91. package/dist/policy/index.d.ts.map +1 -1
  92. package/dist/policy/index.js +1 -1
  93. package/dist/policy/index.js.map +1 -1
  94. package/dist/state.d.ts +80 -1
  95. package/dist/state.d.ts.map +1 -1
  96. package/dist/state.js +234 -6
  97. package/dist/state.js.map +1 -1
  98. package/dist/worker.d.ts.map +1 -1
  99. package/dist/worker.js +28 -6
  100. package/dist/worker.js.map +1 -1
  101. package/package.json +3 -3
@@ -0,0 +1,193 @@
1
+ /** An image the workspace renders beside a vendor, an account or a resource. */
2
+ export interface AvatarImage {
3
+ url: string;
4
+ }
5
+ /**
6
+ * The stable tag an OS admin rule is keyed on, plus the label a human reads.
7
+ *
8
+ * The tag has to survive a rename of the label, because a pre-approval rule an operator wrote
9
+ * months ago is matched by it. Ours is the binding name, which is generated from the operation's
10
+ * own group and method, so it is exactly as stable as the public API is.
11
+ */
12
+ export interface ActionKind {
13
+ tag: string;
14
+ label: string;
15
+ }
16
+ /** What the OS shows about a vendor before any account exists. */
17
+ export interface VendorDescription {
18
+ displayName: string;
19
+ url: string;
20
+ logo?: AvatarImage;
21
+ color?: string;
22
+ tagline?: string;
23
+ description?: string;
24
+ /** True only if the connect flow yields a provider-verified email. Ours does not. */
25
+ providesAuth?: boolean;
26
+ /** True when the vendor can mint an account with no OAuth flow (see `createAccount`). */
27
+ autoProvisionsAccount?: boolean;
28
+ }
29
+ /** A class of thing this vendor can serve, matched against a URL by `urlPattern`. */
30
+ export interface SupportedResource {
31
+ /** A URLPattern string, e.g. `https://cat-factory.example.com/*`. */
32
+ urlPattern: string;
33
+ title: string;
34
+ description: string;
35
+ icon?: AvatarImage;
36
+ /** True when the account must be granted access to this type separately. */
37
+ grantable?: boolean;
38
+ }
39
+ /** What the OS shows about one connected account. */
40
+ export interface AccountDescription {
41
+ displayName?: string;
42
+ /** The canonical, unique name for the account. */
43
+ uniqueName?: string;
44
+ avatar: AvatarImage;
45
+ grantedResourceUrlPatterns?: string[];
46
+ }
47
+ /** What the OS shows about one bound resource, and how it types the session behind it. */
48
+ export interface ResourceDescription {
49
+ /** The resource's canonical URL: visiting it in a browser opens the resource's own UI. */
50
+ url: string;
51
+ title: string;
52
+ snippet: string;
53
+ /** The name the binding is first created with. The user may rename it. */
54
+ suggestedBindingName: string;
55
+ /** A type name exported by this gatekeeper's `getTypeScriptTypes()`. */
56
+ tsType: string;
57
+ }
58
+ /**
59
+ * A read the gadget wants to make, described for the authorizer.
60
+ *
61
+ * `prohibitAllSharing` is the strongest statement available and the one worth getting right: it
62
+ * says the data this read returns may not be shared onward with any observer, whatever their own
63
+ * access is.
64
+ */
65
+ export interface ObservationDescription {
66
+ title: string;
67
+ description: string;
68
+ prohibitAllSharing?: boolean;
69
+ excludeObservers?: string[];
70
+ }
71
+ /** A side effect the gadget wants to make, described for the approver. */
72
+ export interface ActionDescription {
73
+ /** One line, like an email subject, for a list. */
74
+ title: string;
75
+ /** Markdown. Everything an approver needs in order to decide, with nothing held back. */
76
+ description: string;
77
+ /** Whether this gatekeeper implements `revertAction` for this action. */
78
+ implementsRevert: boolean;
79
+ /**
80
+ * Tells the agent not to keep working until this settles. Set by a gatekeeper that does NOT
81
+ * simulate the action's effects, which is ours: there is no provisional run id to hand back.
82
+ */
83
+ awaitDecision?: boolean;
84
+ /** The author's verdict that this action is safe to auto-apply, if the user opted in. */
85
+ autoApprovable?: boolean;
86
+ actionKind?: ActionKind;
87
+ }
88
+ /** The half of the queue that governs reads. */
89
+ export interface ObservationAuthorizer {
90
+ /** Resolves when the read is permitted, and THROWS when it is not. */
91
+ authorizeObservation(description: ObservationDescription): Promise<void>;
92
+ }
93
+ /** What an approver is told about a hook the workspace is being asked to enable. */
94
+ export interface HookDescription {
95
+ title: string;
96
+ description: string;
97
+ }
98
+ /** Where an enabled hook's deliveries land, as the workspace names it. */
99
+ export interface HookTargetMetadata {
100
+ workspaceId: string;
101
+ gadgetId?: number;
102
+ }
103
+ /**
104
+ * What the workspace turns a bound hook on and off through. Implemented on THIS side.
105
+ *
106
+ * A hook is not live when it is bound: the workspace may have to ask a person first, and it calls
107
+ * `enable` if and when they say yes. The initiator it hands over is the ONLY thing worth keeping,
108
+ * and `disable` means every trace of the registration goes.
109
+ */
110
+ export interface HookController {
111
+ enable(initiator: HookInitiator, target: HookTargetMetadata): Promise<void>;
112
+ disable(): Promise<void>;
113
+ }
114
+ /**
115
+ * What an enabled hook is delivered THROUGH: a fresh callback per event, never a stored one.
116
+ *
117
+ * The callback handed to `bindHook` is a loan like every other parameter stub, so the contract
118
+ * gives the initiator instead: ask for a callback when there is something to deliver, and get an
119
+ * approval queue with it, because a delivery is a read of the paired deployment and has to be
120
+ * authorized exactly as `approvals_list()` is.
121
+ */
122
+ export interface HookInitiator {
123
+ startHook(): Promise<{
124
+ callback: unknown;
125
+ approvalQueue: ObservationAuthorizer;
126
+ }>;
127
+ }
128
+ /**
129
+ * What the OS hands to `startSession`: the chokepoint every operation passes through.
130
+ *
131
+ * `submitAction` takes an id this gatekeeper assigns and returns as soon as the action is QUEUED,
132
+ * not when it is decided. The decision arrives later as `applyAction(id)` or `rejectAction(id)` on
133
+ * the resource object.
134
+ */
135
+ export interface ApprovalQueue extends ObservationAuthorizer {
136
+ submitAction(action: number, description: ActionDescription): Promise<void>;
137
+ /**
138
+ * Register a persistent callback, which the workspace holds and may not enable at once.
139
+ *
140
+ * The gatekeeper hands over a CONTROLLER of its own rather than keeping the callback: the
141
+ * callback is a parameter stub whose lifetime ends with this call, and what has to survive is
142
+ * the registration. Enabling arrives later on that controller.
143
+ */
144
+ bindHook(controller: unknown, callback: unknown, description: HookDescription): Promise<void>;
145
+ }
146
+ /** What a `GATEKEEPER_*` service binding reaches. */
147
+ export interface VendorEntrypoint {
148
+ describe(): Promise<VendorDescription>;
149
+ getSupportedResources(options?: {
150
+ userId?: string;
151
+ }): Promise<SupportedResource[]>;
152
+ getTypeScriptTypes(): Promise<string>;
153
+ /** Returns the account stub the workspace persists. Opaque here: it is the OS's to hold. */
154
+ createAccount(): Promise<unknown>;
155
+ }
156
+ /** What the workspace holds for one connected account. */
157
+ export interface AccountEntrypoint {
158
+ describe(): Promise<AccountDescription>;
159
+ getSupportedResources(): Promise<SupportedResource[]>;
160
+ getGatekeeperClassFor(url: string): Promise<{
161
+ class: unknown;
162
+ resource: SupportedResource;
163
+ }>;
164
+ ensureResources(resourceUrlPatterns: string[]): Promise<Record<string, never>>;
165
+ revoke(): Promise<void>;
166
+ getVerifier(): Promise<unknown>;
167
+ getAuthenticatedEmail(): Promise<string | null>;
168
+ reconnect(): Promise<{
169
+ url: string;
170
+ }>;
171
+ }
172
+ /** What one bound resource serves: the session, its types, and the action lifecycle. */
173
+ export interface ResourceObject {
174
+ describe(): Promise<ResourceDescription>;
175
+ getTypeScriptTypes(): Promise<string>;
176
+ startSession(approvalQueue: ApprovalQueue): Promise<unknown>;
177
+ getAutoApprovableActions(): Promise<ActionKind[]>;
178
+ applyAction(action: number): Promise<void>;
179
+ rejectAction(action: number): Promise<void>;
180
+ revertAction(action: number): Promise<{
181
+ message: string;
182
+ canRetry: false;
183
+ }>;
184
+ addObserver(id: string, user: unknown): Promise<void>;
185
+ removeObserver(id: string): Promise<void>;
186
+ }
187
+ /** The identity stub another vendor's gatekeeper is handed. Carries no authority by design. */
188
+ export interface VerifierEntrypoint {
189
+ describe(): Promise<{
190
+ accountId: string;
191
+ }>;
192
+ }
193
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/os/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ // The Cloudflare OS gatekeeper contract, transcribed.
2
+ //
3
+ // The published source (`cloudflare/cloudflare-os`, `packages/workshop-shared/src/gatekeeper.ts`)
4
+ // is the authority for every shape below. It is TRANSCRIBED rather than imported because this
5
+ // package depends on the cat-factory public surface and nothing else: taking a dependency on the
6
+ // partner workspace would make their release cadence this package's build, which is the same
7
+ // coupling the initiative's own CI rule refuses. The cost is that these declarations can fall
8
+ // behind, and the answer to that is the nightly leg (`GATEKEEPER_OS_REF`), which boots a pinned
9
+ // partner commit against this Worker and is allowed to go red on its own.
10
+ //
11
+ // The transcription is deliberately PARTIAL: it carries the members this Worker implements or is
12
+ // handed, and omits the ones it does not (`getAgentCatalog`, `getSlashCommandProvider`,
13
+ // `startAppUi`, the UI frames). An omitted optional member is a capability the OS correctly
14
+ // reports as absent; a transcribed one this Worker did not implement would be a method that
15
+ // exists and lies.
16
+ //
17
+ // Structural typing is what makes this safe. Nothing here is `extends`ed by a class the OS
18
+ // constructs: the OS reaches a bound Worker's entrypoint over native RPC and calls methods by
19
+ // name, so what has to match is the SHAPE. These interfaces exist to make our shape a compile-time
20
+ // claim rather than a hope.
21
+ export {};
22
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/os/protocol.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,kGAAkG;AAClG,8FAA8F;AAC9F,iGAAiG;AACjG,6FAA6F;AAC7F,8FAA8F;AAC9F,gGAAgG;AAChG,0EAA0E;AAC1E,EAAE;AACF,iGAAiG;AACjG,wFAAwF;AACxF,4FAA4F;AAC5F,4FAA4F;AAC5F,mBAAmB;AACnB,EAAE;AACF,2FAA2F;AAC3F,8FAA8F;AAC9F,mGAAmG;AACnG,4BAA4B"}
@@ -0,0 +1,99 @@
1
+ import type { SessionGovernance } from '../capability.js';
2
+ import { type CallSubject } from './descriptions.js';
3
+ import { type HookControllerProps } from './hooks.js';
4
+ import type { ApprovalQueue } from './protocol.js';
5
+ /**
6
+ * One session's view of the ledger: what it may register, and the end of everything it registered.
7
+ *
8
+ * A handle rather than a second store, because the IDS are the object's (see {@link ActionLedger})
9
+ * while the LIFETIME is the session's, and the two facts have to live in one map for a decision
10
+ * naming an id to find the entry it settles.
11
+ */
12
+ export interface LedgerSession {
13
+ /** Register an effect, returning the id to submit it under and the promise the caller awaits. */
14
+ register(label: string, perform: () => Promise<unknown>): {
15
+ id: number;
16
+ settled: Promise<unknown>;
17
+ };
18
+ /**
19
+ * Drop a registration whose submission never reached the queue.
20
+ *
21
+ * Without it a queue that throws would leave an entry the workspace can never decide, and the
22
+ * caller would be told about the submission failure while the ledger silently grew.
23
+ */
24
+ abandon(id: number): void;
25
+ /** The session is over: refuse every action it left undecided and drop them. */
26
+ end(): void;
27
+ }
28
+ /**
29
+ * The submitted-but-undecided actions of one resource object, and the decisions that settle them.
30
+ *
31
+ * Ids are sequential per object rather than per session, because the OS hands them back to the
32
+ * OBJECT (`applyAction` is a method on the resource, not on the session): two sessions minting
33
+ * overlapping ids would settle each other's actions.
34
+ */
35
+ export declare class ActionLedger {
36
+ #private;
37
+ /** Open one session's handle. Ending it is what bounds the entries it registered. */
38
+ openSession(): LedgerSession;
39
+ /**
40
+ * Perform an approved action and hand its result to the waiting caller.
41
+ *
42
+ * The entry is removed BEFORE the effect runs, so a redelivered `applyAction` cannot perform it
43
+ * twice: at-least-once delivery is the normal state of a decision arriving over a network, and
44
+ * the second copy must be a refusal rather than a second write.
45
+ *
46
+ * A failing effect rejects the caller AND throws on to the workspace, which the contract asks
47
+ * for: the person who approved it is the one who gets to retry or discard.
48
+ */
49
+ apply(id: number): Promise<void>;
50
+ /** Reject an action: the awaiting call throws, and nothing is performed. */
51
+ reject(id: number): void;
52
+ /**
53
+ * How many actions are still waiting, across every live session on this object.
54
+ *
55
+ * Here so the ledger's one growth path is observable: an entry is added by a session and removed
56
+ * by a decision, an abandoned submission, or that session ending, and a count that does not
57
+ * return to zero once the sessions are gone is the leak this exists to fail a test on.
58
+ */
59
+ get pendingCount(): number;
60
+ }
61
+ /**
62
+ * Take a reference to the workspace's queue that outlives the call it arrived on.
63
+ *
64
+ * Workers RPC disposes every stub a call received as a PARAMETER the moment that call returns, and
65
+ * `startSession` returns immediately with a session that goes on using the queue for the rest of
66
+ * its life. Without this the first governed read or write would authorize against a stub the
67
+ * runtime had already torn down, and the failure would reach the caller as a broken connection
68
+ * rather than as anything naming the queue. `dup()` is what the RPC contract offers for exactly
69
+ * this case.
70
+ *
71
+ * The check is not defensiveness about a malformed argument: `ResourceCore` is also driven
72
+ * IN-PROCESS, by this package's own suite and by anything embedding it, and there the queue is an
73
+ * ordinary object that was never a stub and has nothing to duplicate.
74
+ *
75
+ * Paired with {@link releaseQueue} and kept beside it, because a duplicate taken here and released
76
+ * anywhere else is a leak that nothing about either half would show on its own.
77
+ */
78
+ export declare function holdQueue(queue: ApprovalQueue): ApprovalQueue;
79
+ /**
80
+ * The governance one session applies, over the queue the workspace handed it at `startSession`.
81
+ *
82
+ * Every method here is a thin translation: what to describe comes from the operation table
83
+ * (`descriptions.ts`), what to do about the answer is the contract's, and the effect itself stays
84
+ * the machinery's. That is what keeps this a facade rather than a second implementation.
85
+ */
86
+ export declare function queueGovernance(deps: {
87
+ queue: ApprovalQueue;
88
+ ledger: LedgerSession;
89
+ subject: CallSubject;
90
+ /**
91
+ * Build the controller for one hook, which is this Worker's own `CatFactoryHookController`
92
+ * export imbued with the registration's identity.
93
+ *
94
+ * Supplied by the caller rather than built here because only the resource object can reach
95
+ * `ctx.exports`, and a session that could not build one is a session on a door with no hooks.
96
+ */
97
+ controllerFor: (props: HookControllerProps) => unknown;
98
+ }): SessionGovernance;
99
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/os/queue.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEzD,OAAO,EAAuC,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACzF,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAclD;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,iGAAiG;IACjG,QAAQ,CACN,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAC9B;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IAC5C;;;;;OAKG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,gFAAgF;IAChF,GAAG,IAAI,IAAI,CAAA;CACZ;AAED;;;;;;GAMG;AACH,qBAAa,YAAY;;IAKvB,qFAAqF;IACrF,WAAW,IAAI,aAAa,CAO3B;IAED;;;;;;;;;OASG;IACG,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQrC;IAED,4EAA4E;IAC5E,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAQvB;IAED;;;;;;OAMG;IACH,IAAI,YAAY,IAAI,MAAM,CAEzB;CAiDF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CAG7D;AAaD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,KAAK,EAAE,aAAa,CAAA;IACpB,MAAM,EAAE,aAAa,CAAA;IACrB,OAAO,EAAE,WAAW,CAAA;IACpB;;;;;;OAMG;IACH,aAAa,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAA;CACvD,GAAG,iBAAiB,CAgGpB"}
@@ -0,0 +1,240 @@
1
+ // The approval queue, threaded onto the session's one `invoke` seam.
2
+ //
3
+ // This is the half of the published contract that runs in the opposite direction from our approval
4
+ // INBOX, and the two must not be confused. The inbox carries the PLATFORM's parked runs outward to
5
+ // the OS, so a person can answer them. The queue carries the OS's governance INWARD over every call
6
+ // an agent makes, so nothing is read or written without the workspace's kernel having authorized
7
+ // it. A Gatekeeper needs both, and having one is no reason to skip the other.
8
+ //
9
+ // The action lifecycle is genuinely asynchronous, and the shape follows from that:
10
+ //
11
+ // 1. A mutating call assigns the next action id and records the effect in memory, UNPERFORMED.
12
+ // 2. It submits the description and awaits a decision that does not come back from `submitAction`.
13
+ // 3. `applyAction(id)` performs the effect and resolves the awaiting call with its result;
14
+ // `rejectAction(id)` rejects it.
15
+ //
16
+ // The pending set is in MEMORY, on purpose. The awaiting caller is a suspended RPC into this object,
17
+ // so the object cannot be evicted while an action is pending, and if the RPC dies there is nobody
18
+ // left to resolve: persisting the effect would only let a later `applyAction` perform a write whose
19
+ // result nothing reads and whose caller was told nothing. An action that outlives its session is a
20
+ // SIMULATING gatekeeper's problem, and simulation is deliberately not what this one does
21
+ // (`awaitDecision: true` says so on every action it submits).
22
+ //
23
+ // So an entry's LIFETIME IS ITS SESSION'S, and nothing else bounds it. A TTL would be the wrong
24
+ // bound twice over: the thing being waited on is a person deciding, which has no deadline worth
25
+ // guessing, and expiring an entry would settle an action the workspace can still legitimately
26
+ // apply. What DOES end is the session: when the workspace drops it, every action it submitted is
27
+ // refused and dropped together, so the ledger of a long-lived resource object holds pending work
28
+ // for live sessions only. Without that, an approval card nobody ever answered pinned its entry for
29
+ // the object's whole lifetime, and `#take`'s "the session that submitted it has ended" was a
30
+ // sentence nothing made true.
31
+ import { describeError, GatekeeperError } from '../errors.js';
32
+ import { describeAction, describeObservation } from './descriptions.js';
33
+ import { describeHook, HOOK_TOPICS } from './hooks.js';
34
+ /**
35
+ * The submitted-but-undecided actions of one resource object, and the decisions that settle them.
36
+ *
37
+ * Ids are sequential per object rather than per session, because the OS hands them back to the
38
+ * OBJECT (`applyAction` is a method on the resource, not on the session): two sessions minting
39
+ * overlapping ids would settle each other's actions.
40
+ */
41
+ export class ActionLedger {
42
+ #nextId = 1;
43
+ #nextSession = 1;
44
+ #pending = new Map();
45
+ /** Open one session's handle. Ending it is what bounds the entries it registered. */
46
+ openSession() {
47
+ const session = this.#nextSession++;
48
+ return {
49
+ register: (label, perform) => this.#register(session, label, perform),
50
+ abandon: (id) => this.#pending.delete(id),
51
+ end: () => this.#endSession(session),
52
+ };
53
+ }
54
+ /**
55
+ * Perform an approved action and hand its result to the waiting caller.
56
+ *
57
+ * The entry is removed BEFORE the effect runs, so a redelivered `applyAction` cannot perform it
58
+ * twice: at-least-once delivery is the normal state of a decision arriving over a network, and
59
+ * the second copy must be a refusal rather than a second write.
60
+ *
61
+ * A failing effect rejects the caller AND throws on to the workspace, which the contract asks
62
+ * for: the person who approved it is the one who gets to retry or discard.
63
+ */
64
+ async apply(id) {
65
+ const action = this.#take(id, 'apply');
66
+ try {
67
+ action.resolve(await action.perform());
68
+ }
69
+ catch (error) {
70
+ action.reject(error);
71
+ throw error;
72
+ }
73
+ }
74
+ /** Reject an action: the awaiting call throws, and nothing is performed. */
75
+ reject(id) {
76
+ const action = this.#take(id, 'reject');
77
+ action.reject(new GatekeeperError('action_rejected', `The workspace rejected this action (${action.label}), so it was not performed.`));
78
+ }
79
+ /**
80
+ * How many actions are still waiting, across every live session on this object.
81
+ *
82
+ * Here so the ledger's one growth path is observable: an entry is added by a session and removed
83
+ * by a decision, an abandoned submission, or that session ending, and a count that does not
84
+ * return to zero once the sessions are gone is the leak this exists to fail a test on.
85
+ */
86
+ get pendingCount() {
87
+ return this.#pending.size;
88
+ }
89
+ #register(session, label, perform) {
90
+ const id = this.#nextId++;
91
+ const settled = new Promise((resolve, reject) => {
92
+ this.#pending.set(id, { perform, resolve, reject, label, session });
93
+ });
94
+ return { id, settled };
95
+ }
96
+ /**
97
+ * End one session: every action it submitted and nobody decided is refused, and nothing is
98
+ * performed.
99
+ *
100
+ * The awaiting caller is told, rather than left on a promise that can no longer settle: the
101
+ * session it called through is gone, so no `applyAction` can ever reach its effect again.
102
+ */
103
+ #endSession(session) {
104
+ // Deleting the entry the iterator is standing on is defined behaviour for a Map, so this
105
+ // walks the live one rather than a snapshot of it.
106
+ for (const [id, action] of this.#pending) {
107
+ if (action.session !== session)
108
+ continue;
109
+ this.#pending.delete(id);
110
+ action.reject(new GatekeeperError('session_ended', `The session that submitted this action (${action.label}) ended before the workspace ` +
111
+ 'decided it, so it was not performed.'));
112
+ }
113
+ }
114
+ #take(id, verb) {
115
+ const action = this.#pending.get(id);
116
+ if (action === undefined) {
117
+ throw new GatekeeperError('unknown_action', `No action ${id} is pending on this resource, so there is nothing to ${verb}. It was ` +
118
+ 'already decided, or the session that submitted it has ended.');
119
+ }
120
+ this.#pending.delete(id);
121
+ return action;
122
+ }
123
+ }
124
+ /**
125
+ * Take a reference to the workspace's queue that outlives the call it arrived on.
126
+ *
127
+ * Workers RPC disposes every stub a call received as a PARAMETER the moment that call returns, and
128
+ * `startSession` returns immediately with a session that goes on using the queue for the rest of
129
+ * its life. Without this the first governed read or write would authorize against a stub the
130
+ * runtime had already torn down, and the failure would reach the caller as a broken connection
131
+ * rather than as anything naming the queue. `dup()` is what the RPC contract offers for exactly
132
+ * this case.
133
+ *
134
+ * The check is not defensiveness about a malformed argument: `ResourceCore` is also driven
135
+ * IN-PROCESS, by this package's own suite and by anything embedding it, and there the queue is an
136
+ * ordinary object that was never a stub and has nothing to duplicate.
137
+ *
138
+ * Paired with {@link releaseQueue} and kept beside it, because a duplicate taken here and released
139
+ * anywhere else is a leak that nothing about either half would show on its own.
140
+ */
141
+ export function holdQueue(queue) {
142
+ const stub = queue;
143
+ return typeof stub.dup === 'function' ? stub.dup() : queue;
144
+ }
145
+ /**
146
+ * Release this session's hold on the workspace's queue.
147
+ *
148
+ * The other half of {@link holdQueue}: a duplicate nobody disposes holds the workspace's end of
149
+ * the connection open for the resource object's whole lifetime. The optional call is the
150
+ * in-process case again, where nothing was duplicated and there is nothing to give back.
151
+ */
152
+ function releaseQueue(queue) {
153
+ ;
154
+ queue[Symbol.dispose]?.();
155
+ }
156
+ /**
157
+ * The governance one session applies, over the queue the workspace handed it at `startSession`.
158
+ *
159
+ * Every method here is a thin translation: what to describe comes from the operation table
160
+ * (`descriptions.ts`), what to do about the answer is the contract's, and the effect itself stays
161
+ * the machinery's. That is what keeps this a facade rather than a second implementation.
162
+ */
163
+ export function queueGovernance(deps) {
164
+ return {
165
+ async observe(binding, args) {
166
+ await deps.queue.authorizeObservation(describeObservation(binding, args, deps.subject));
167
+ },
168
+ async observeLocal(title, detail) {
169
+ await deps.queue.authorizeObservation({
170
+ title: `${title} (${deps.subject.deployment})`,
171
+ description: `${detail}\n\nServed from this Gatekeeper's own record of what the paired deployment ` +
172
+ `at ${deps.subject.deployment} delivered, for account \`${deps.subject.accountId}\` at ` +
173
+ `policy tier \`${deps.subject.tier}\`.`,
174
+ });
175
+ },
176
+ async act(binding, args, perform) {
177
+ const { id, settled } = deps.ledger.register(binding.summary, perform);
178
+ try {
179
+ await deps.queue.submitAction(id, describeAction(binding, args, deps.subject));
180
+ }
181
+ catch (error) {
182
+ // The submission failed, so no decision will ever arrive for this id. Dropping the
183
+ // registration is what stops the caller waiting on a promise nothing can settle.
184
+ deps.ledger.abandon(id);
185
+ throw error;
186
+ }
187
+ return (await settled);
188
+ },
189
+ /**
190
+ * Hand the workspace a controller and the callback, and keep NEITHER.
191
+ *
192
+ * Everything about the registration rides the controller's props, so this call leaves no
193
+ * state behind: the workspace may take days to approve the hook, or never approve it, and a
194
+ * row written here would be a registration for something nobody enabled. What comes back is
195
+ * nothing at all, because there is nothing to report yet; `hooks_bound()` answers once the
196
+ * workspace has enabled it.
197
+ */
198
+ async subscribe(topic, callback) {
199
+ // Reachable only in process, and kept for exactly that: an embedding suite hands over a
200
+ // plain object, where a missing method is a mistake worth naming. It CANNOT catch a
201
+ // workspace whose queue predates hooks, because a stub answers every property (the same
202
+ // fact `callBack` turns on), so `typeof` reads `function` for a method the far side does not
203
+ // implement. That case arrives below, as a failure from the far side.
204
+ if (typeof deps.queue.bindHook !== 'function') {
205
+ throw new GatekeeperError('hooks_unavailable', 'The approval queue this session was opened with offers no bindHook(), so this ' +
206
+ 'workspace cannot hold a callback for us. Read `approvals_list()` and ' +
207
+ '`runs_watched()` instead: they carry exactly what a hook would push.');
208
+ }
209
+ const props = {
210
+ hookId: `hook_${crypto.randomUUID().replaceAll('-', '')}`,
211
+ topic,
212
+ accountId: deps.subject.accountId,
213
+ tier: deps.subject.tier,
214
+ deployment: deps.subject.deployment,
215
+ };
216
+ try {
217
+ await deps.queue.bindHook(deps.controllerFor(props), callback, describeHook(topic, deps.subject));
218
+ }
219
+ catch (error) {
220
+ // A workspace whose queue has no `bindHook` and a person who declined the registration
221
+ // both surface here, and this Gatekeeper cannot tell them apart: the contract offers no
222
+ // way to ask whether hooks are servable, and the two failures cross the wire the same way.
223
+ // So the cause is reported VERBATIM rather than sorted into a guess, because it is the one
224
+ // thing that distinguishes them and the two need opposite fixes.
225
+ throw new GatekeeperError('hook_bind_refused', `This workspace did not take the ${HOOK_TOPICS[topic].sessionMethod}() binding ` +
226
+ `(${describeError(error)}). Either its approval queue serves no hooks, or the ` +
227
+ 'registration was declined. `approvals_list()` and `runs_watched()` answer exactly ' +
228
+ 'what the hook would have pushed, and go on doing so.');
229
+ }
230
+ },
231
+ close() {
232
+ // Order matters: the actions are refused while the queue is still ours to hold, so an
233
+ // awaiting caller is told the session ended rather than left on a promise whose only route
234
+ // to a decision has already been released.
235
+ deps.ledger.end();
236
+ releaseQueue(deps.queue);
237
+ },
238
+ };
239
+ }
240
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/os/queue.ts"],"names":[],"mappings":"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"}