@anchrd/intel-contract 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/dist/contract/flow.d.ts +22 -0
- package/dist/contract/flow.js +33 -5
- package/dist/contract/share.d.ts +35 -0
- package/dist/contract/share.js +28 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,10 +95,15 @@ edge and the tool ends up in the chain. The graph is then refused with
|
|
|
95
95
|
`Node <id> is a link and must be attached to a step` — in `title`, per the first item above. A step
|
|
96
96
|
may hold several links; one link belongs to exactly one step.
|
|
97
97
|
|
|
98
|
-
### A flow is not a node, and
|
|
98
|
+
### A flow is not a node, and has its own grant calls
|
|
99
99
|
|
|
100
|
-
`node_grant_create` addresses nodes. A flow
|
|
101
|
-
|
|
100
|
+
`node_grant_create` addresses nodes; `flow_grant_create` addresses flows. A flow is reached by both:
|
|
101
|
+
the folder it is filed in passes its grants down, and a grant may sit on the flow itself. The two
|
|
102
|
+
add up — the flow grant never replaces what the folder passes down.
|
|
103
|
+
|
|
104
|
+
⚠️ A grant on one flow reaches **that flow** and nothing else — not the folder, and not the flows it
|
|
105
|
+
calls. `ShareResult` says so: `unrunnable` names the sub-flows the new principal could not start,
|
|
106
|
+
by title where you may see them and by count where you may not.
|
|
102
107
|
|
|
103
108
|
### Import takes its idempotency key as a header
|
|
104
109
|
|
package/dist/contract/flow.d.ts
CHANGED
|
@@ -899,6 +899,21 @@ export declare const FlowPublishCall: z.ZodObject<{
|
|
|
899
899
|
available: z.ZodBoolean;
|
|
900
900
|
}, z.core.$strict>;
|
|
901
901
|
export type FlowPublishCall = z.infer<typeof FlowPublishCall>;
|
|
902
|
+
/**
|
|
903
|
+
* What a tool step will be allowed to reach once this version is published (#517).
|
|
904
|
+
*
|
|
905
|
+
* ⚠️ It is in the preview because publishing FREEZES it: from that moment the step's surface is
|
|
906
|
+
* pinned, and a function the provider adds later is not inherited. An author who cannot see the
|
|
907
|
+
* surface before confirming is asked to freeze something they were never shown.
|
|
908
|
+
*/
|
|
909
|
+
export declare const FlowPublishTool: z.ZodObject<{
|
|
910
|
+
nodeId: z.ZodString;
|
|
911
|
+
nodeLabel: z.ZodString;
|
|
912
|
+
server: z.ZodString;
|
|
913
|
+
allow: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
914
|
+
available: z.ZodBoolean;
|
|
915
|
+
}, z.core.$strict>;
|
|
916
|
+
export type FlowPublishTool = z.infer<typeof FlowPublishTool>;
|
|
902
917
|
export declare const FlowPublishPreview: z.ZodObject<{
|
|
903
918
|
flowId: z.ZodString;
|
|
904
919
|
versionId: z.ZodString;
|
|
@@ -917,6 +932,13 @@ export declare const FlowPublishPreview: z.ZodObject<{
|
|
|
917
932
|
freezes: z.ZodBoolean;
|
|
918
933
|
available: z.ZodBoolean;
|
|
919
934
|
}, z.core.$strict>>;
|
|
935
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
936
|
+
nodeId: z.ZodString;
|
|
937
|
+
nodeLabel: z.ZodString;
|
|
938
|
+
server: z.ZodString;
|
|
939
|
+
allow: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
940
|
+
available: z.ZodBoolean;
|
|
941
|
+
}, z.core.$strict>>;
|
|
920
942
|
}, z.core.$strict>;
|
|
921
943
|
export type FlowPublishPreview = z.infer<typeof FlowPublishPreview>;
|
|
922
944
|
export declare const RelationNodeKind: z.ZodEnum<{
|
package/dist/contract/flow.js
CHANGED
|
@@ -86,8 +86,18 @@ export const FlowNode = z.discriminatedUnion("kind", [
|
|
|
86
86
|
* step's instruction and can only be known while the flow runs.
|
|
87
87
|
*
|
|
88
88
|
* `allow: null` means every function of that server. A list narrows it, and every entry has to
|
|
89
|
-
* belong to `server` — checked below, because a name from another server would
|
|
90
|
-
*
|
|
89
|
+
* belong to `server` — checked below, because a name from another server would make the step ask
|
|
90
|
+
* for something the portal routes somewhere else entirely.
|
|
91
|
+
*
|
|
92
|
+
* ⚠️ `allow` is an INSTRUCTION to the agent, not a boundary Intel enforces (#518). Intel is a
|
|
93
|
+
* library: it says what is to be done, it does not execute. A flow is carried out by an agent
|
|
94
|
+
* that reaches the portal with its OWN token, and that agent may call the portal directly —
|
|
95
|
+
* Intel never sees the call. What bounds it is the agent's own portal grant, checked by the
|
|
96
|
+
* portal on every call; what `allow` does is tell the agent which of those functions this step
|
|
97
|
+
* is meant to use, the same way an instruction step tells it what to write.
|
|
98
|
+
*
|
|
99
|
+
* That is not a gap to be closed by adding a check here. Enforcing it would mean routing every
|
|
100
|
+
* call through Intel and making it the executor — the one thing this product is not.
|
|
91
101
|
*
|
|
92
102
|
* ⚠️ There is deliberately no `arguments` field any more. Arguments are produced at run time and
|
|
93
103
|
* validated against the tool's own `inputSchema` from a live `tools/list`; a stored copy would be
|
|
@@ -405,14 +415,32 @@ export const FlowPublishCall = z.strictObject({
|
|
|
405
415
|
// The callee has a published version to be called at all. `false` is what publishing will refuse.
|
|
406
416
|
available: z.boolean(),
|
|
407
417
|
});
|
|
418
|
+
/**
|
|
419
|
+
* What a tool step will be allowed to reach once this version is published (#517).
|
|
420
|
+
*
|
|
421
|
+
* ⚠️ It is in the preview because publishing FREEZES it: from that moment the step's surface is
|
|
422
|
+
* pinned, and a function the provider adds later is not inherited. An author who cannot see the
|
|
423
|
+
* surface before confirming is asked to freeze something they were never shown.
|
|
424
|
+
*/
|
|
425
|
+
export const FlowPublishTool = z.strictObject({
|
|
426
|
+
nodeId: FlowNodeId,
|
|
427
|
+
nodeLabel: z.string().min(1).max(160),
|
|
428
|
+
server: ToolServerHandle,
|
|
429
|
+
// `null` is "every function of that server". A list is what the step narrowed itself to, and it
|
|
430
|
+
// is spelled out rather than counted: the whole point of the preview is that a human can read it.
|
|
431
|
+
allow: z.array(ToolName).nullable(),
|
|
432
|
+
// The server is reachable for the person publishing. `false` is what publishing will refuse.
|
|
433
|
+
available: z.boolean(),
|
|
434
|
+
});
|
|
408
435
|
export const FlowPublishPreview = z.strictObject({
|
|
409
436
|
flowId: IntelId,
|
|
410
437
|
versionId: IntelId,
|
|
411
438
|
calls: z.array(FlowPublishCall),
|
|
439
|
+
tools: z.array(FlowPublishTool),
|
|
412
440
|
});
|
|
413
|
-
// A flow
|
|
414
|
-
//
|
|
415
|
-
//
|
|
441
|
+
// A flow's own sharing schemas live in `share.ts` beside the node's (#530): `ShareFlowInput`,
|
|
442
|
+
// `RevokeFlowGrantInput`, `ListFlowGrantsInput`. They are there rather than here because a grant is
|
|
443
|
+
// one subject with two kinds of target, not two features — and `ShareResult` answers for both.
|
|
416
444
|
// What accesses what, for one level of the shared tree (#19). A folder answers it for its contents,
|
|
417
445
|
// a single flow for itself. Documents and flows are two kinds of thing that share one tree
|
|
418
446
|
// (ADR-0004 §1), so the graph carries both and says which of them it is.
|
package/dist/contract/share.d.ts
CHANGED
|
@@ -20,6 +20,10 @@ export declare const ListGrantsInput: z.ZodObject<{
|
|
|
20
20
|
resourceId: z.ZodString;
|
|
21
21
|
}, z.core.$strict>;
|
|
22
22
|
export type ListGrantsInput = z.infer<typeof ListGrantsInput>;
|
|
23
|
+
export declare const ListFlowGrantsInput: z.ZodObject<{
|
|
24
|
+
flowId: z.ZodString;
|
|
25
|
+
}, z.core.$strict>;
|
|
26
|
+
export type ListFlowGrantsInput = z.infer<typeof ListFlowGrantsInput>;
|
|
23
27
|
export declare const ResourceGrant: z.ZodObject<{
|
|
24
28
|
id: z.ZodString;
|
|
25
29
|
resourceId: z.ZodString;
|
|
@@ -70,6 +74,33 @@ export declare const RevokeGrantInput: z.ZodObject<{
|
|
|
70
74
|
idempotencyKey: z.ZodString;
|
|
71
75
|
}, z.core.$strict>;
|
|
72
76
|
export type RevokeGrantInput = z.infer<typeof RevokeGrantInput>;
|
|
77
|
+
export declare const ShareFlowInput: z.ZodObject<{
|
|
78
|
+
flowId: z.ZodString;
|
|
79
|
+
principal: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
80
|
+
type: z.ZodLiteral<"user">;
|
|
81
|
+
id: z.ZodString;
|
|
82
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
83
|
+
type: z.ZodLiteral<"email">;
|
|
84
|
+
email: z.ZodEmail;
|
|
85
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
86
|
+
type: z.ZodLiteral<"organization">;
|
|
87
|
+
}, z.core.$strict>], "type">;
|
|
88
|
+
verb: z.ZodEnum<{
|
|
89
|
+
read: "read";
|
|
90
|
+
write: "write";
|
|
91
|
+
execute: "execute";
|
|
92
|
+
share: "share";
|
|
93
|
+
}>;
|
|
94
|
+
expiresAt: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
|
95
|
+
idempotencyKey: z.ZodString;
|
|
96
|
+
}, z.core.$strict>;
|
|
97
|
+
export type ShareFlowInput = z.infer<typeof ShareFlowInput>;
|
|
98
|
+
export declare const RevokeFlowGrantInput: z.ZodObject<{
|
|
99
|
+
flowId: z.ZodString;
|
|
100
|
+
grantId: z.ZodString;
|
|
101
|
+
idempotencyKey: z.ZodString;
|
|
102
|
+
}, z.core.$strict>;
|
|
103
|
+
export type RevokeFlowGrantInput = z.infer<typeof RevokeFlowGrantInput>;
|
|
73
104
|
export declare const UnreadableNodes: z.ZodObject<{
|
|
74
105
|
titles: z.ZodArray<z.ZodString>;
|
|
75
106
|
hidden: z.ZodNumber;
|
|
@@ -102,6 +133,10 @@ export declare const ShareResult: z.ZodObject<{
|
|
|
102
133
|
titles: z.ZodArray<z.ZodString>;
|
|
103
134
|
hidden: z.ZodNumber;
|
|
104
135
|
}, z.core.$strict>;
|
|
136
|
+
unrunnable: z.ZodDefault<z.ZodObject<{
|
|
137
|
+
titles: z.ZodArray<z.ZodString>;
|
|
138
|
+
hidden: z.ZodNumber;
|
|
139
|
+
}, z.core.$strict>>;
|
|
105
140
|
}, z.core.$strict>;
|
|
106
141
|
export type ShareResult = z.infer<typeof ShareResult>;
|
|
107
142
|
export declare const ResourceGrantList: z.ZodObject<{
|
package/dist/contract/share.js
CHANGED
|
@@ -17,6 +17,12 @@ export const SharePrincipal = z.discriminatedUnion("type", [
|
|
|
17
17
|
export const ListGrantsInput = z.strictObject({
|
|
18
18
|
resourceId: IntelId.describe("Node whose direct grants to list. Access inherited from a folder above is not a grant on this node and is not listed here."),
|
|
19
19
|
});
|
|
20
|
+
// The same three shapes for a flow (#530). Separate inputs rather than a widened `resourceId`,
|
|
21
|
+
// because the id names a different table and a caller that passes the wrong kind should be told so
|
|
22
|
+
// by the route it called rather than by a lookup that finds nothing.
|
|
23
|
+
export const ListFlowGrantsInput = z.strictObject({
|
|
24
|
+
flowId: IntelId.describe("Flow whose direct grants to list. Access inherited from the folder it is filed in is not a grant on this flow and is not listed here."),
|
|
25
|
+
});
|
|
20
26
|
export const ResourceGrant = z.strictObject({
|
|
21
27
|
id: IntelId,
|
|
22
28
|
resourceId: IntelId,
|
|
@@ -40,6 +46,20 @@ export const RevokeGrantInput = z.strictObject({
|
|
|
40
46
|
grantId: IntelId.describe("The grant to withdraw, from node_grant_list."),
|
|
41
47
|
idempotencyKey: IdempotencyKey,
|
|
42
48
|
});
|
|
49
|
+
export const ShareFlowInput = z.strictObject({
|
|
50
|
+
flowId: IntelId.describe("Flow to grant access to. A grant here reaches this flow and nothing else — not the folder it is filed in, and not the flows it calls."),
|
|
51
|
+
principal: SharePrincipal.describe("Who gets the access: a Gate user by id, someone by verified email address, or the whole organization."),
|
|
52
|
+
verb: ResourceVerb.describe("What they may do. Each verb is granted on its own and none implies another: `read` opens the flow, `write` edits it, `execute` runs it, `share` passes access on."),
|
|
53
|
+
expiresAt: IsoDateTime.nullable()
|
|
54
|
+
.default(null)
|
|
55
|
+
.describe("When the grant stops working, or `null` for one that does not expire on its own."),
|
|
56
|
+
idempotencyKey: IdempotencyKey,
|
|
57
|
+
});
|
|
58
|
+
export const RevokeFlowGrantInput = z.strictObject({
|
|
59
|
+
flowId: IntelId.describe("Flow the grant sits on. Named alongside the grant id so access is decided on the flow."),
|
|
60
|
+
grantId: IntelId.describe("The grant to withdraw, from flow_grant_list."),
|
|
61
|
+
idempotencyKey: IdempotencyKey,
|
|
62
|
+
});
|
|
43
63
|
// What a grant does not cover, reported to whoever just made it. A flow in the shared folder may
|
|
44
64
|
// read a document outside it, and the run is re-authorized against the person running it — so the
|
|
45
65
|
// grant can be complete and the flow still stop for them (ADR-0004 §4).
|
|
@@ -53,9 +73,17 @@ export const UnreadableNodes = z.strictObject({
|
|
|
53
73
|
// The grant is in the answer, so the warning cannot be mistaken for a refusal: it is written first
|
|
54
74
|
// and described afterwards. Blocking would force everyone who uses a central policy document to
|
|
55
75
|
// duplicate it, which is the opposite of what one tree is for (ADR-0004 §4).
|
|
76
|
+
//
|
|
77
|
+
// ⚠️ `unrunnable` is the second half of the same sentence and belongs to the flow grant (#530). A
|
|
78
|
+
// grant on a folder covered every flow beneath it, so there was nothing to say; a grant on one flow
|
|
79
|
+
// reaches that flow and stops, and the sub-flows it calls are then somebody else's to grant. It
|
|
80
|
+
// carries the shape of `UnreadableNodes` because it answers the same question — what this grant
|
|
81
|
+
// does NOT reach, named where the sharer may see it and counted where they may not — and it is
|
|
82
|
+
// empty for every node grant.
|
|
56
83
|
export const ShareResult = z.strictObject({
|
|
57
84
|
grant: ResourceGrant,
|
|
58
85
|
unreadable: UnreadableNodes,
|
|
86
|
+
unrunnable: UnreadableNodes.default({ titles: [], hidden: 0 }),
|
|
59
87
|
});
|
|
60
88
|
// `applicableVerbs` travels with the list because the answer is the business layer's, not the
|
|
61
89
|
// screen's: a document has nothing to execute, so `execute` is not offered on one (ADR-0004 §2).
|