@decionis/agent-safe-pipeline 0.4.0 → 0.5.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 +29 -0
- package/dist/Index.d.ts +9 -0
- package/dist/Index.d.ts.map +1 -1
- package/dist/Index.js +9 -0
- package/dist/Index.js.map +1 -1
- package/dist/execution/ActionRegistry.d.ts +12 -0
- package/dist/execution/ActionRegistry.d.ts.map +1 -1
- package/dist/execution/ActionRegistry.js +14 -0
- package/dist/execution/ActionRegistry.js.map +1 -1
- package/dist/execution/GovernedExecutionRunner.d.ts +14 -0
- package/dist/execution/GovernedExecutionRunner.d.ts.map +1 -1
- package/dist/execution/GovernedExecutionRunner.js +46 -1
- package/dist/execution/GovernedExecutionRunner.js.map +1 -1
- package/dist/execution/NativeExecutor.d.ts +20 -1
- package/dist/execution/NativeExecutor.d.ts.map +1 -1
- package/dist/execution/NativeExecutor.js.map +1 -1
- package/dist/intent/CanonicalIntentHasher.d.ts.map +1 -1
- package/dist/intent/CanonicalIntentHasher.js +11 -0
- package/dist/intent/CanonicalIntentHasher.js.map +1 -1
- package/dist/intent/ExecutionIntent.d.ts +55 -4
- package/dist/intent/ExecutionIntent.d.ts.map +1 -1
- package/dist/intent/ExecutionIntent.js +40 -0
- package/dist/intent/ExecutionIntent.js.map +1 -1
- package/dist/intent/ExecutionSignals.d.ts +9 -1
- package/dist/intent/ExecutionSignals.d.ts.map +1 -1
- package/dist/intent/ExecutionSignals.js +9 -0
- package/dist/intent/ExecutionSignals.js.map +1 -1
- package/dist/intent/IntentBindingSchema.d.ts +6 -0
- package/dist/intent/IntentBindingSchema.d.ts.map +1 -1
- package/dist/intent/IntentBindingSchema.js +10 -0
- package/dist/intent/IntentBindingSchema.js.map +1 -1
- package/dist/intent/IntentCapture.d.ts.map +1 -1
- package/dist/intent/IntentCapture.js +18 -4
- package/dist/intent/IntentCapture.js.map +1 -1
- package/dist/intent/TargetPrecondition.d.ts +36 -0
- package/dist/intent/TargetPrecondition.d.ts.map +1 -0
- package/dist/intent/TargetPrecondition.js +57 -0
- package/dist/intent/TargetPrecondition.js.map +1 -0
- package/dist/manifest/ActionManifest.d.ts +112 -0
- package/dist/manifest/ActionManifest.d.ts.map +1 -0
- package/dist/manifest/ActionManifest.js +182 -0
- package/dist/manifest/ActionManifest.js.map +1 -0
- package/dist/plan/GovernedPlan.d.ts +109 -0
- package/dist/plan/GovernedPlan.d.ts.map +1 -0
- package/dist/plan/GovernedPlan.js +187 -0
- package/dist/plan/GovernedPlan.js.map +1 -0
- package/dist/plan/PlanState.d.ts +94 -0
- package/dist/plan/PlanState.d.ts.map +1 -0
- package/dist/plan/PlanState.js +240 -0
- package/dist/plan/PlanState.js.map +1 -0
- package/dist/plan/PlanStepReference.d.ts +16 -0
- package/dist/plan/PlanStepReference.d.ts.map +1 -0
- package/dist/plan/PlanStepReference.js +25 -0
- package/dist/plan/PlanStepReference.js.map +1 -0
- package/dist/profile/ApiProfile.d.ts +354 -0
- package/dist/profile/ApiProfile.d.ts.map +1 -0
- package/dist/profile/ApiProfile.js +755 -0
- package/dist/profile/ApiProfile.js.map +1 -0
- package/dist/profile/ApiProfiles.d.ts +16 -0
- package/dist/profile/ApiProfiles.d.ts.map +1 -0
- package/dist/profile/ApiProfiles.js +29 -0
- package/dist/profile/ApiProfiles.js.map +1 -0
- package/dist/profile/BuiltInApiProfiles.d.ts +9 -0
- package/dist/profile/BuiltInApiProfiles.d.ts.map +1 -0
- package/dist/profile/BuiltInApiProfiles.js +494 -0
- package/dist/profile/BuiltInApiProfiles.js.map +1 -0
- package/dist/profile/McpToolProfile.d.ts +129 -0
- package/dist/profile/McpToolProfile.d.ts.map +1 -0
- package/dist/profile/McpToolProfile.js +270 -0
- package/dist/profile/McpToolProfile.js.map +1 -0
- package/dist/testing/Index.d.ts +3 -1
- package/dist/testing/Index.d.ts.map +1 -1
- package/dist/testing/Index.js +2 -0
- package/dist/testing/Index.js.map +1 -1
- package/dist/testing/LocalAssumptionBreaches.d.ts +96 -0
- package/dist/testing/LocalAssumptionBreaches.d.ts.map +1 -0
- package/dist/testing/LocalAssumptionBreaches.js +109 -0
- package/dist/testing/LocalAssumptionBreaches.js.map +1 -0
- package/dist/testing/LocalAuthority.d.ts +158 -5
- package/dist/testing/LocalAuthority.d.ts.map +1 -1
- package/dist/testing/LocalAuthority.js +302 -18
- package/dist/testing/LocalAuthority.js.map +1 -1
- package/dist/testing/LocalPlans.d.ts +43 -0
- package/dist/testing/LocalPlans.d.ts.map +1 -0
- package/dist/testing/LocalPlans.js +124 -0
- package/dist/testing/LocalPlans.js.map +1 -0
- package/package.json +5 -4
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ActionRegistry } from "../execution/ActionRegistry.js";
|
|
3
|
+
import { type JsonObject } from "../intent/JsonValue.js";
|
|
4
|
+
import { ApiProfile } from "../profile/ApiProfile.js";
|
|
5
|
+
import { type McpToolProfile } from "../profile/McpToolProfile.js";
|
|
6
|
+
/**
|
|
7
|
+
* `agent-safe.actions/1`: the action space an executor can run, as one
|
|
8
|
+
* document. Each entry is an action an intent can name, where it comes from
|
|
9
|
+
* (a family registered in code, an API profile's writes, an MCP profile's
|
|
10
|
+
* tools), the JSON Schema its parameters are admitted against, the target
|
|
11
|
+
* scopes it acts on, and the effect it produces when its source says.
|
|
12
|
+
*
|
|
13
|
+
* The authority reads it as the inventory a policy release has to cover:
|
|
14
|
+
* Decionis refuses a release that leaves a manifest action matched by no
|
|
15
|
+
* rule but its default. The contract is Decionis's (`ActionManifest` in its
|
|
16
|
+
* OpenAPI); this is the producer.
|
|
17
|
+
*/
|
|
18
|
+
export declare const ACTION_MANIFEST_CONTRACT = "agent-safe.actions/1";
|
|
19
|
+
/** The most actions one manifest lists, and the most target scopes one action names. */
|
|
20
|
+
export declare const MAX_MANIFEST_ACTIONS = 500;
|
|
21
|
+
export declare const MAX_ACTION_TARGETS = 64;
|
|
22
|
+
export declare const ActionManifestSourceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
23
|
+
kind: z.ZodLiteral<"registry">;
|
|
24
|
+
family: z.ZodString;
|
|
25
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
26
|
+
kind: z.ZodLiteral<"api">;
|
|
27
|
+
profile: z.ZodString;
|
|
28
|
+
operations: z.ZodArray<z.ZodString>;
|
|
29
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
30
|
+
kind: z.ZodLiteral<"mcp">;
|
|
31
|
+
profile: z.ZodString;
|
|
32
|
+
tool: z.ZodString;
|
|
33
|
+
}, z.core.$strict>], "kind">;
|
|
34
|
+
export declare const ActionManifestEntrySchema: z.ZodObject<{
|
|
35
|
+
action: z.ZodString;
|
|
36
|
+
source: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
37
|
+
kind: z.ZodLiteral<"registry">;
|
|
38
|
+
family: z.ZodString;
|
|
39
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
40
|
+
kind: z.ZodLiteral<"api">;
|
|
41
|
+
profile: z.ZodString;
|
|
42
|
+
operations: z.ZodArray<z.ZodString>;
|
|
43
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
44
|
+
kind: z.ZodLiteral<"mcp">;
|
|
45
|
+
profile: z.ZodString;
|
|
46
|
+
tool: z.ZodString;
|
|
47
|
+
}, z.core.$strict>], "kind">;
|
|
48
|
+
parameters: z.ZodType<JsonObject, unknown, z.core.$ZodTypeInternals<JsonObject, unknown>>;
|
|
49
|
+
targets: z.ZodArray<z.ZodString>;
|
|
50
|
+
effect_type: z.ZodNullable<z.ZodString>;
|
|
51
|
+
}, z.core.$strict>;
|
|
52
|
+
export declare const ActionManifestSchema: z.ZodObject<{
|
|
53
|
+
manifest: z.ZodLiteral<"agent-safe.actions/1">;
|
|
54
|
+
actions: z.ZodArray<z.ZodObject<{
|
|
55
|
+
action: z.ZodString;
|
|
56
|
+
source: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
57
|
+
kind: z.ZodLiteral<"registry">;
|
|
58
|
+
family: z.ZodString;
|
|
59
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
60
|
+
kind: z.ZodLiteral<"api">;
|
|
61
|
+
profile: z.ZodString;
|
|
62
|
+
operations: z.ZodArray<z.ZodString>;
|
|
63
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
64
|
+
kind: z.ZodLiteral<"mcp">;
|
|
65
|
+
profile: z.ZodString;
|
|
66
|
+
tool: z.ZodString;
|
|
67
|
+
}, z.core.$strict>], "kind">;
|
|
68
|
+
parameters: z.ZodType<JsonObject, unknown, z.core.$ZodTypeInternals<JsonObject, unknown>>;
|
|
69
|
+
targets: z.ZodArray<z.ZodString>;
|
|
70
|
+
effect_type: z.ZodNullable<z.ZodString>;
|
|
71
|
+
}, z.core.$strict>>;
|
|
72
|
+
}, z.core.$strict>;
|
|
73
|
+
export type ActionManifestSource = z.infer<typeof ActionManifestSourceSchema>;
|
|
74
|
+
export type ActionManifestEntry = z.infer<typeof ActionManifestEntrySchema>;
|
|
75
|
+
export type ActionManifestDocument = z.infer<typeof ActionManifestSchema>;
|
|
76
|
+
/** What a registry cannot say about an action and its family can: where it acts, and its effect. */
|
|
77
|
+
export interface ActionAnnotation {
|
|
78
|
+
readonly targets: readonly string[];
|
|
79
|
+
readonly effectType: string | null;
|
|
80
|
+
}
|
|
81
|
+
export declare class ActionManifestError extends Error {
|
|
82
|
+
readonly code: "ACTION_MANIFEST_DUPLICATE_ACTION" | "ACTION_MANIFEST_INVALID";
|
|
83
|
+
readonly detail: string;
|
|
84
|
+
constructor(code: "ACTION_MANIFEST_DUPLICATE_ACTION" | "ACTION_MANIFEST_INVALID", detail: string);
|
|
85
|
+
}
|
|
86
|
+
export declare class ActionManifest {
|
|
87
|
+
/**
|
|
88
|
+
* A parameters schema as JSON Schema: the input side, since that is what an
|
|
89
|
+
* intent carries, and a check zod cannot express (a refinement, a custom
|
|
90
|
+
* type) as an open schema rather than a refusal to describe the action.
|
|
91
|
+
*/
|
|
92
|
+
static parametersJsonSchema(schema: z.ZodType): JsonObject;
|
|
93
|
+
/** A sealed registry's actions, each annotated by the family that registered it. */
|
|
94
|
+
static fromRegistry(registry: ActionRegistry, family: string, annotate: (action: string) => ActionAnnotation): ActionManifestEntry[];
|
|
95
|
+
/**
|
|
96
|
+
* An API profile's write actions, one entry each, with every operation that
|
|
97
|
+
* becomes it and that operation's method and path template as a target. A
|
|
98
|
+
* read is never an intent, so it is not in the action space.
|
|
99
|
+
*/
|
|
100
|
+
static fromApiProfile(profile: ApiProfile, parametersSchema: z.ZodType): ActionManifestEntry[];
|
|
101
|
+
/** An MCP profile's tools, one entry each, admitted against the tool's declared arguments. */
|
|
102
|
+
static fromMcpProfile(profile: McpToolProfile): ActionManifestEntry[];
|
|
103
|
+
/**
|
|
104
|
+
* The document: every entry once, in code-point order of its action, held
|
|
105
|
+
* to the contract. An action two sources both produce is refused by name,
|
|
106
|
+
* since a grant names an action and only one handler can run under it.
|
|
107
|
+
*/
|
|
108
|
+
static document(entries: readonly ActionManifestEntry[]): ActionManifestDocument;
|
|
109
|
+
/** `sha256:` over the RFC 8785 form: what a signed release manifest records as `actionManifestDigest`. */
|
|
110
|
+
static digest(document: ActionManifestDocument): `sha256:${string}`;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=ActionManifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionManifest.d.ts","sourceRoot":"","sources":["../../src/manifest/ActionManifest.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,EAAoB,KAAK,UAAU,EAAkB,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAEL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,8BAA8B,CAAC;AAEtC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAE/D,wFAAwF;AACxF,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAOrC,eAAO,MAAM,0BAA0B;;;;;;;;;;;4BAqBrC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;kBAYpC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;kBAe7B,CAAC;AAEL,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC9E,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC5E,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE1E,oGAAoG;AACpG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,IAAI,EAAE,kCAAkC,GAAG,yBAAyB;aACpE,MAAM,EAAE,MAAM;gBADd,IAAI,EAAE,kCAAkC,GAAG,yBAAyB,EACpE,MAAM,EAAE,MAAM;CAKjC;AAED,qBAAa,cAAc;IACzB;;;;OAIG;WACW,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,UAAU;IAUjE,oFAAoF;WACtE,YAAY,CACxB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,gBAAgB,GAC7C,mBAAmB,EAAE;IAaxB;;;;OAIG;WACW,cAAc,CAC1B,OAAO,EAAE,UAAU,EACnB,gBAAgB,EAAE,CAAC,CAAC,OAAO,GAC1B,mBAAmB,EAAE;IAsBxB,8FAA8F;WAChF,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,mBAAmB,EAAE;IAa5E;;;;OAIG;WACW,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,GAAG,sBAAsB;IAsBvF,0GAA0G;WAC5F,MAAM,CAAC,QAAQ,EAAE,sBAAsB,GAAG,UAAU,MAAM,EAAE;CAI3E"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { CanonicalIntentHasher } from "../intent/CanonicalIntentHasher.js";
|
|
4
|
+
import { JsonObjectSchema } from "../intent/JsonValue.js";
|
|
5
|
+
import { ApiOperationSchema, ApiProfile, ApiProfileDefinitionSchema, } from "../profile/ApiProfile.js";
|
|
6
|
+
import { McpProfileDefinitionSchema, McpToolSchema, } from "../profile/McpToolProfile.js";
|
|
7
|
+
/**
|
|
8
|
+
* `agent-safe.actions/1`: the action space an executor can run, as one
|
|
9
|
+
* document. Each entry is an action an intent can name, where it comes from
|
|
10
|
+
* (a family registered in code, an API profile's writes, an MCP profile's
|
|
11
|
+
* tools), the JSON Schema its parameters are admitted against, the target
|
|
12
|
+
* scopes it acts on, and the effect it produces when its source says.
|
|
13
|
+
*
|
|
14
|
+
* The authority reads it as the inventory a policy release has to cover:
|
|
15
|
+
* Decionis refuses a release that leaves a manifest action matched by no
|
|
16
|
+
* rule but its default. The contract is Decionis's (`ActionManifest` in its
|
|
17
|
+
* OpenAPI); this is the producer.
|
|
18
|
+
*/
|
|
19
|
+
export const ACTION_MANIFEST_CONTRACT = "agent-safe.actions/1";
|
|
20
|
+
/** The most actions one manifest lists, and the most target scopes one action names. */
|
|
21
|
+
export const MAX_MANIFEST_ACTIONS = 500;
|
|
22
|
+
export const MAX_ACTION_TARGETS = 64;
|
|
23
|
+
const actionName = z
|
|
24
|
+
.string()
|
|
25
|
+
.max(120)
|
|
26
|
+
.regex(/^[a-z][a-z0-9._:-]*$/);
|
|
27
|
+
export const ActionManifestSourceSchema = z.discriminatedUnion("kind", [
|
|
28
|
+
/** A family registered in code, by the name its registration goes by. */
|
|
29
|
+
z.strictObject({
|
|
30
|
+
kind: z.literal("registry"),
|
|
31
|
+
family: z
|
|
32
|
+
.string()
|
|
33
|
+
.max(40)
|
|
34
|
+
.regex(/^[a-z][a-z0-9]*$/),
|
|
35
|
+
}),
|
|
36
|
+
/** An API profile's writes: the operations, in profile order, that become this action. */
|
|
37
|
+
z.strictObject({
|
|
38
|
+
kind: z.literal("api"),
|
|
39
|
+
profile: ApiProfileDefinitionSchema.shape.id,
|
|
40
|
+
operations: z.array(ApiOperationSchema.shape.id).min(1).max(200),
|
|
41
|
+
}),
|
|
42
|
+
/** An MCP profile's tool that becomes this action. */
|
|
43
|
+
z.strictObject({
|
|
44
|
+
kind: z.literal("mcp"),
|
|
45
|
+
profile: McpProfileDefinitionSchema.shape.id,
|
|
46
|
+
tool: McpToolSchema.shape.tool,
|
|
47
|
+
}),
|
|
48
|
+
]);
|
|
49
|
+
export const ActionManifestEntrySchema = z.strictObject({
|
|
50
|
+
action: actionName,
|
|
51
|
+
source: ActionManifestSourceSchema,
|
|
52
|
+
/** The JSON Schema (draft 2020-12, without `$schema`) the intent's parameters are admitted against. */
|
|
53
|
+
parameters: JsonObjectSchema,
|
|
54
|
+
/** Scope templates with `{name}` placeholders; none when the proposal names the target. */
|
|
55
|
+
targets: z.array(z.string().min(1).max(500)).max(MAX_ACTION_TARGETS),
|
|
56
|
+
/** The effect the action produces, when its source declares one. */
|
|
57
|
+
effect_type: z
|
|
58
|
+
.string()
|
|
59
|
+
.regex(/^[A-Z][A-Z0-9_]{0,119}$/)
|
|
60
|
+
.nullable(),
|
|
61
|
+
});
|
|
62
|
+
export const ActionManifestSchema = z
|
|
63
|
+
.strictObject({
|
|
64
|
+
manifest: z.literal(ACTION_MANIFEST_CONTRACT),
|
|
65
|
+
actions: z.array(ActionManifestEntrySchema).min(1).max(MAX_MANIFEST_ACTIONS),
|
|
66
|
+
})
|
|
67
|
+
.superRefine((value, context) => {
|
|
68
|
+
// Strictly ascending is sorted and unique at once: one action, one entry.
|
|
69
|
+
for (let index = 1; index < value.actions.length; index += 1) {
|
|
70
|
+
if (value.actions[index - 1].action >= value.actions[index].action)
|
|
71
|
+
context.addIssue({
|
|
72
|
+
code: "custom",
|
|
73
|
+
path: ["actions", index, "action"],
|
|
74
|
+
message: "actions are listed once each, in code-point order",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
export class ActionManifestError extends Error {
|
|
79
|
+
code;
|
|
80
|
+
detail;
|
|
81
|
+
constructor(code, detail) {
|
|
82
|
+
super(code);
|
|
83
|
+
this.code = code;
|
|
84
|
+
this.detail = detail;
|
|
85
|
+
this.name = "ActionManifestError";
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export class ActionManifest {
|
|
89
|
+
/**
|
|
90
|
+
* A parameters schema as JSON Schema: the input side, since that is what an
|
|
91
|
+
* intent carries, and a check zod cannot express (a refinement, a custom
|
|
92
|
+
* type) as an open schema rather than a refusal to describe the action.
|
|
93
|
+
*/
|
|
94
|
+
static parametersJsonSchema(schema) {
|
|
95
|
+
const generated = z.toJSONSchema(schema, {
|
|
96
|
+
target: "draft-2020-12",
|
|
97
|
+
io: "input",
|
|
98
|
+
unrepresentable: "any",
|
|
99
|
+
});
|
|
100
|
+
delete generated["$schema"];
|
|
101
|
+
return generated;
|
|
102
|
+
}
|
|
103
|
+
/** A sealed registry's actions, each annotated by the family that registered it. */
|
|
104
|
+
static fromRegistry(registry, family, annotate) {
|
|
105
|
+
return registry.describe().map(({ action, parametersSchema }) => {
|
|
106
|
+
const annotation = annotate(action);
|
|
107
|
+
return {
|
|
108
|
+
action,
|
|
109
|
+
source: { kind: "registry", family },
|
|
110
|
+
parameters: ActionManifest.parametersJsonSchema(parametersSchema),
|
|
111
|
+
targets: [...annotation.targets],
|
|
112
|
+
effect_type: annotation.effectType,
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* An API profile's write actions, one entry each, with every operation that
|
|
118
|
+
* becomes it and that operation's method and path template as a target. A
|
|
119
|
+
* read is never an intent, so it is not in the action space.
|
|
120
|
+
*/
|
|
121
|
+
static fromApiProfile(profile, parametersSchema) {
|
|
122
|
+
const parameters = ActionManifest.parametersJsonSchema(parametersSchema);
|
|
123
|
+
return profile.actions().map((action) => {
|
|
124
|
+
const operations = profile.definition.operations.filter((operation) => !ApiProfile.isRead(operation) && operation.action === action);
|
|
125
|
+
return {
|
|
126
|
+
action,
|
|
127
|
+
source: {
|
|
128
|
+
kind: "api",
|
|
129
|
+
profile: profile.id,
|
|
130
|
+
operations: operations.map((operation) => operation.id),
|
|
131
|
+
},
|
|
132
|
+
parameters,
|
|
133
|
+
targets: [
|
|
134
|
+
...new Set(operations.map((operation) => `${operation.method} ${operation.path}`)),
|
|
135
|
+
],
|
|
136
|
+
effect_type: null,
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/** An MCP profile's tools, one entry each, admitted against the tool's declared arguments. */
|
|
141
|
+
static fromMcpProfile(profile) {
|
|
142
|
+
return profile.tools().map((name) => {
|
|
143
|
+
const tool = profile.tool(name);
|
|
144
|
+
return {
|
|
145
|
+
action: tool.action,
|
|
146
|
+
source: { kind: "mcp", profile: profile.id, tool: tool.tool },
|
|
147
|
+
parameters: ActionManifest.parametersJsonSchema(profile.argumentsSchema(name)),
|
|
148
|
+
targets: [tool.target],
|
|
149
|
+
effect_type: null,
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The document: every entry once, in code-point order of its action, held
|
|
155
|
+
* to the contract. An action two sources both produce is refused by name,
|
|
156
|
+
* since a grant names an action and only one handler can run under it.
|
|
157
|
+
*/
|
|
158
|
+
static document(entries) {
|
|
159
|
+
const seen = new Set();
|
|
160
|
+
for (const entry of entries) {
|
|
161
|
+
if (seen.has(entry.action))
|
|
162
|
+
throw new ActionManifestError("ACTION_MANIFEST_DUPLICATE_ACTION", entry.action);
|
|
163
|
+
seen.add(entry.action);
|
|
164
|
+
}
|
|
165
|
+
const parsed = ActionManifestSchema.safeParse({
|
|
166
|
+
manifest: ACTION_MANIFEST_CONTRACT,
|
|
167
|
+
actions: [...entries].sort((a, b) => (a.action < b.action ? -1 : 1)),
|
|
168
|
+
});
|
|
169
|
+
if (!parsed.success)
|
|
170
|
+
throw new ActionManifestError("ACTION_MANIFEST_INVALID", parsed.error.issues
|
|
171
|
+
.slice(0, 3)
|
|
172
|
+
.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`)
|
|
173
|
+
.join("; "));
|
|
174
|
+
return parsed.data;
|
|
175
|
+
}
|
|
176
|
+
/** `sha256:` over the RFC 8785 form: what a signed release manifest records as `actionManifestDigest`. */
|
|
177
|
+
static digest(document) {
|
|
178
|
+
const canonical = CanonicalIntentHasher.stringify(document);
|
|
179
|
+
return `sha256:${createHash("sha256").update(canonical, "utf8").digest("hex")}`;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=ActionManifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionManifest.js","sourceRoot":"","sources":["../../src/manifest/ActionManifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { AgentProposal } from "../intent/ExecutionIntent.js";
|
|
3
|
+
import { type JsonObject } from "../intent/JsonValue.js";
|
|
4
|
+
import { type PlanStepReference } from "./PlanStepReference.js";
|
|
5
|
+
/**
|
|
6
|
+
* A governed plan: one change carried out as several governed operations,
|
|
7
|
+
* each proposed, decided, granted, claimed and finalized on its own.
|
|
8
|
+
*
|
|
9
|
+
* The plan is a governance object, not an orchestrator. It names the steps,
|
|
10
|
+
* which step depends on which and how (the coupling), and what stays
|
|
11
|
+
* admissible once a step has failed. Registering it with the authority
|
|
12
|
+
* authorizes no step: the authority derives each step's plan facts from its
|
|
13
|
+
* own finalization records, and policy decides each step with those facts in
|
|
14
|
+
* front of it. ADR 0008 is the design.
|
|
15
|
+
*/
|
|
16
|
+
export declare const GOVERNED_PLAN_VERSION = "agent-safe.plan/1";
|
|
17
|
+
/** What a predecessor's outcome means for the step that depends on it. */
|
|
18
|
+
export declare const PLAN_COUPLINGS: readonly ["independent", "ordered", "all_or_escalate"];
|
|
19
|
+
export declare const MAX_PLAN_STEPS = 32;
|
|
20
|
+
export declare const MAX_PLAN_EDGES = 64;
|
|
21
|
+
export declare const PlanStepSchema: z.ZodObject<{
|
|
22
|
+
step_id: z.ZodString;
|
|
23
|
+
action: z.ZodString;
|
|
24
|
+
target: z.ZodString;
|
|
25
|
+
parameters: z.ZodOptional<z.ZodType<JsonObject, unknown, z.core.$ZodTypeInternals<JsonObject, unknown>>>;
|
|
26
|
+
compensates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
27
|
+
}, z.core.$strict>;
|
|
28
|
+
export declare const PlanEdgeSchema: z.ZodObject<{
|
|
29
|
+
from: z.ZodString;
|
|
30
|
+
to: z.ZodString;
|
|
31
|
+
coupling: z.ZodEnum<{
|
|
32
|
+
independent: "independent";
|
|
33
|
+
ordered: "ordered";
|
|
34
|
+
all_or_escalate: "all_or_escalate";
|
|
35
|
+
}>;
|
|
36
|
+
}, z.core.$strict>;
|
|
37
|
+
/** What stays admissible once a step has FAILED. */
|
|
38
|
+
export declare const PartialCommitRuleSchema: z.ZodObject<{
|
|
39
|
+
admissible: z.ZodArray<z.ZodString>;
|
|
40
|
+
otherwise: z.ZodEnum<{
|
|
41
|
+
ESCALATE: "ESCALATE";
|
|
42
|
+
BLOCK: "BLOCK";
|
|
43
|
+
}>;
|
|
44
|
+
}, z.core.$strict>;
|
|
45
|
+
export declare const GovernedPlanSchema: z.ZodObject<{
|
|
46
|
+
version: z.ZodLiteral<"agent-safe.plan/1">;
|
|
47
|
+
plan_id: z.ZodString;
|
|
48
|
+
tenant_id: z.ZodString;
|
|
49
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
50
|
+
step_id: z.ZodString;
|
|
51
|
+
action: z.ZodString;
|
|
52
|
+
target: z.ZodString;
|
|
53
|
+
parameters: z.ZodOptional<z.ZodType<JsonObject, unknown, z.core.$ZodTypeInternals<JsonObject, unknown>>>;
|
|
54
|
+
compensates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
55
|
+
}, z.core.$strict>>;
|
|
56
|
+
edges: z.ZodArray<z.ZodObject<{
|
|
57
|
+
from: z.ZodString;
|
|
58
|
+
to: z.ZodString;
|
|
59
|
+
coupling: z.ZodEnum<{
|
|
60
|
+
independent: "independent";
|
|
61
|
+
ordered: "ordered";
|
|
62
|
+
all_or_escalate: "all_or_escalate";
|
|
63
|
+
}>;
|
|
64
|
+
}, z.core.$strict>>;
|
|
65
|
+
partial_commit: z.ZodObject<{
|
|
66
|
+
admissible: z.ZodArray<z.ZodString>;
|
|
67
|
+
otherwise: z.ZodEnum<{
|
|
68
|
+
ESCALATE: "ESCALATE";
|
|
69
|
+
BLOCK: "BLOCK";
|
|
70
|
+
}>;
|
|
71
|
+
}, z.core.$strict>;
|
|
72
|
+
}, z.core.$strict>;
|
|
73
|
+
export type PlanCoupling = (typeof PLAN_COUPLINGS)[number];
|
|
74
|
+
export type PlanStep = z.infer<typeof PlanStepSchema>;
|
|
75
|
+
export type PlanEdge = z.infer<typeof PlanEdgeSchema>;
|
|
76
|
+
export type PartialCommitRule = z.infer<typeof PartialCommitRuleSchema>;
|
|
77
|
+
export type GovernedPlan = z.infer<typeof GovernedPlanSchema>;
|
|
78
|
+
/**
|
|
79
|
+
* The plan's digest: SHA-256 over its canonical JSON (sorted keys), the form
|
|
80
|
+
* every digest in the intent contract uses. The plan is parsed first, so two
|
|
81
|
+
* spellings of one plan that the schema accepts differ only where the plan
|
|
82
|
+
* itself differs.
|
|
83
|
+
*/
|
|
84
|
+
export declare function planDigest(plan: GovernedPlan): `sha256:${string}`;
|
|
85
|
+
export type PlanStepMismatch = "PLAN_STEP_UNKNOWN" | "PLAN_STEP_ACTION_MISMATCH" | "PLAN_STEP_TARGET_OUT_OF_SCOPE" | "PLAN_STEP_PARAMETER_MISMATCH";
|
|
86
|
+
export type PlanStepMatch = {
|
|
87
|
+
readonly ok: true;
|
|
88
|
+
readonly reference: PlanStepReference;
|
|
89
|
+
} | {
|
|
90
|
+
readonly ok: false;
|
|
91
|
+
readonly code: PlanStepMismatch;
|
|
92
|
+
};
|
|
93
|
+
/** Whether a target is inside a step's scope: exact, or under a trailing-`*` prefix. */
|
|
94
|
+
export declare function planTargetInScope(scope: string, target: string): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Matches a proposal to one step of a plan and, when it fits, returns the
|
|
97
|
+
* reference the trusted executor stamps into the intent. A different action,
|
|
98
|
+
* a target outside the step's scope, or a parameter that differs from one the
|
|
99
|
+
* step pins is refused here, before anything is captured. The authority makes
|
|
100
|
+
* the same match itself; this one only fails fast.
|
|
101
|
+
*/
|
|
102
|
+
export declare function matchPlanStep(plan: GovernedPlan, stepId: string, proposal: AgentProposal): PlanStepMatch;
|
|
103
|
+
/** The reason an action is outside a step, or null when it fits. */
|
|
104
|
+
export declare function planStepMismatch(step: PlanStep, action: {
|
|
105
|
+
readonly action: string;
|
|
106
|
+
readonly target: string;
|
|
107
|
+
readonly parameters: JsonObject;
|
|
108
|
+
}): Exclude<PlanStepMismatch, "PLAN_STEP_UNKNOWN"> | null;
|
|
109
|
+
//# sourceMappingURL=GovernedPlan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GovernedPlan.d.ts","sourceRoot":"","sources":["../../src/plan/GovernedPlan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAoB,KAAK,UAAU,EAAkB,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAkC,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhG;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAEzD,0EAA0E;AAC1E,eAAO,MAAM,cAAc,wDAAyD,CAAC;AAErF,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,cAAc,KAAK,CAAC;AAiBjC,eAAO,MAAM,cAAc;;;;;;kBAUhB,CAAC;AAEZ,eAAO,MAAM,cAAc;;;;;;;;kBAMhB,CAAC;AAEZ,oDAAoD;AACpD,eAAO,MAAM,uBAAuB;;;;;;kBAKzB,CAAC;AAEZ,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAa3B,CAAC;AAEL,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAC3D,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAyD9D;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,UAAU,MAAM,EAAE,CAIjE;AAED,MAAM,MAAM,gBAAgB,GACxB,mBAAmB,GACnB,2BAA2B,GAC3B,+BAA+B,GAC/B,8BAA8B,CAAC;AAEnC,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE5D,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAExE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,aAAa,GACtB,aAAa,CAaf;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAA;CAAE,GAC5F,OAAO,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,IAAI,CAavD"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { CanonicalIntentHasher } from "../intent/CanonicalIntentHasher.js";
|
|
4
|
+
import { JsonObjectSchema } from "../intent/JsonValue.js";
|
|
5
|
+
import { PlanIdSchema, PlanStepIdSchema } from "./PlanStepReference.js";
|
|
6
|
+
/**
|
|
7
|
+
* A governed plan: one change carried out as several governed operations,
|
|
8
|
+
* each proposed, decided, granted, claimed and finalized on its own.
|
|
9
|
+
*
|
|
10
|
+
* The plan is a governance object, not an orchestrator. It names the steps,
|
|
11
|
+
* which step depends on which and how (the coupling), and what stays
|
|
12
|
+
* admissible once a step has failed. Registering it with the authority
|
|
13
|
+
* authorizes no step: the authority derives each step's plan facts from its
|
|
14
|
+
* own finalization records, and policy decides each step with those facts in
|
|
15
|
+
* front of it. ADR 0008 is the design.
|
|
16
|
+
*/
|
|
17
|
+
export const GOVERNED_PLAN_VERSION = "agent-safe.plan/1";
|
|
18
|
+
/** What a predecessor's outcome means for the step that depends on it. */
|
|
19
|
+
export const PLAN_COUPLINGS = ["independent", "ordered", "all_or_escalate"];
|
|
20
|
+
export const MAX_PLAN_STEPS = 32;
|
|
21
|
+
export const MAX_PLAN_EDGES = 64;
|
|
22
|
+
const MAX_COMPENSATED_STEPS = 8;
|
|
23
|
+
const actionName = z
|
|
24
|
+
.string()
|
|
25
|
+
.min(1)
|
|
26
|
+
.max(120)
|
|
27
|
+
.regex(/^[a-z][a-z0-9._:-]*$/);
|
|
28
|
+
/** An exact target, or a prefix followed by one trailing `*`. */
|
|
29
|
+
const targetScope = z
|
|
30
|
+
.string()
|
|
31
|
+
.min(1)
|
|
32
|
+
.max(500)
|
|
33
|
+
.refine((value) => !value.slice(0, -1).includes("*") && value !== "*", {
|
|
34
|
+
message: "PLAN_TARGET_SCOPE_INVALID",
|
|
35
|
+
});
|
|
36
|
+
export const PlanStepSchema = z
|
|
37
|
+
.object({
|
|
38
|
+
step_id: PlanStepIdSchema,
|
|
39
|
+
action: actionName,
|
|
40
|
+
target: targetScope,
|
|
41
|
+
/** Parameters the step pins: each must equal the proposal's, canonically. */
|
|
42
|
+
parameters: JsonObjectSchema.optional(),
|
|
43
|
+
/** Present only on a compensation step: the steps whose failure it may follow. */
|
|
44
|
+
compensates: z.array(PlanStepIdSchema).min(1).max(MAX_COMPENSATED_STEPS).optional(),
|
|
45
|
+
})
|
|
46
|
+
.strict();
|
|
47
|
+
export const PlanEdgeSchema = z
|
|
48
|
+
.object({
|
|
49
|
+
from: PlanStepIdSchema,
|
|
50
|
+
to: PlanStepIdSchema,
|
|
51
|
+
coupling: z.enum(PLAN_COUPLINGS),
|
|
52
|
+
})
|
|
53
|
+
.strict();
|
|
54
|
+
/** What stays admissible once a step has FAILED. */
|
|
55
|
+
export const PartialCommitRuleSchema = z
|
|
56
|
+
.object({
|
|
57
|
+
admissible: z.array(PlanStepIdSchema).max(MAX_PLAN_STEPS),
|
|
58
|
+
otherwise: z.enum(["ESCALATE", "BLOCK"]),
|
|
59
|
+
})
|
|
60
|
+
.strict();
|
|
61
|
+
export const GovernedPlanSchema = z
|
|
62
|
+
.object({
|
|
63
|
+
version: z.literal(GOVERNED_PLAN_VERSION),
|
|
64
|
+
plan_id: PlanIdSchema,
|
|
65
|
+
tenant_id: z.string().uuid(),
|
|
66
|
+
steps: z.array(PlanStepSchema).min(1).max(MAX_PLAN_STEPS),
|
|
67
|
+
edges: z.array(PlanEdgeSchema).max(MAX_PLAN_EDGES),
|
|
68
|
+
partial_commit: PartialCommitRuleSchema,
|
|
69
|
+
})
|
|
70
|
+
.strict()
|
|
71
|
+
.superRefine((plan, issues) => {
|
|
72
|
+
const problem = planStructureProblem(plan);
|
|
73
|
+
if (problem !== null)
|
|
74
|
+
issues.addIssue({ code: "custom", message: problem });
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* The first structural problem with a plan, or null. The checks are the ones
|
|
78
|
+
* a dependency graph needs to mean anything: every edge joins two known,
|
|
79
|
+
* distinct steps once; there is no cycle; and a compensation step stands
|
|
80
|
+
* outside the graph, compensating ordinary steps only.
|
|
81
|
+
*/
|
|
82
|
+
function planStructureProblem(plan) {
|
|
83
|
+
const steps = new Map();
|
|
84
|
+
for (const step of plan.steps) {
|
|
85
|
+
if (steps.has(step.step_id))
|
|
86
|
+
return "PLAN_STEP_DUPLICATE";
|
|
87
|
+
steps.set(step.step_id, step);
|
|
88
|
+
}
|
|
89
|
+
const isCompensation = (id) => steps.get(id)?.compensates !== undefined;
|
|
90
|
+
for (const step of plan.steps) {
|
|
91
|
+
for (const compensated of step.compensates ?? []) {
|
|
92
|
+
if (!steps.has(compensated) || isCompensation(compensated)) {
|
|
93
|
+
return "PLAN_COMPENSATION_INVALID";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const seen = new Set();
|
|
98
|
+
const successors = new Map();
|
|
99
|
+
for (const edge of plan.edges) {
|
|
100
|
+
if (!steps.has(edge.from) || !steps.has(edge.to))
|
|
101
|
+
return "PLAN_EDGE_UNKNOWN_STEP";
|
|
102
|
+
if (edge.from === edge.to)
|
|
103
|
+
return "PLAN_EDGE_SELF";
|
|
104
|
+
if (isCompensation(edge.from) || isCompensation(edge.to))
|
|
105
|
+
return "PLAN_COMPENSATION_INVALID";
|
|
106
|
+
const key = `${edge.from}\n${edge.to}`;
|
|
107
|
+
if (seen.has(key))
|
|
108
|
+
return "PLAN_EDGE_DUPLICATE";
|
|
109
|
+
seen.add(key);
|
|
110
|
+
successors.set(edge.from, [...(successors.get(edge.from) ?? []), edge.to]);
|
|
111
|
+
}
|
|
112
|
+
for (const id of plan.partial_commit.admissible) {
|
|
113
|
+
if (!steps.has(id) || isCompensation(id))
|
|
114
|
+
return "PLAN_PARTIAL_UNKNOWN_STEP";
|
|
115
|
+
}
|
|
116
|
+
// Kahn's algorithm: a graph with a cycle leaves steps no order can reach.
|
|
117
|
+
const indegree = new Map([...steps.keys()].map((id) => [id, 0]));
|
|
118
|
+
for (const edge of plan.edges)
|
|
119
|
+
indegree.set(edge.to, (indegree.get(edge.to) ?? 0) + 1);
|
|
120
|
+
const ready = [...indegree].filter(([, count]) => count === 0).map(([id]) => id);
|
|
121
|
+
let ordered = 0;
|
|
122
|
+
while (ready.length > 0) {
|
|
123
|
+
const id = ready.pop();
|
|
124
|
+
ordered += 1;
|
|
125
|
+
for (const next of successors.get(id) ?? []) {
|
|
126
|
+
const remaining = (indegree.get(next) ?? 0) - 1;
|
|
127
|
+
indegree.set(next, remaining);
|
|
128
|
+
if (remaining === 0)
|
|
129
|
+
ready.push(next);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return ordered === steps.size ? null : "PLAN_CYCLE";
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The plan's digest: SHA-256 over its canonical JSON (sorted keys), the form
|
|
136
|
+
* every digest in the intent contract uses. The plan is parsed first, so two
|
|
137
|
+
* spellings of one plan that the schema accepts differ only where the plan
|
|
138
|
+
* itself differs.
|
|
139
|
+
*/
|
|
140
|
+
export function planDigest(plan) {
|
|
141
|
+
const parsed = GovernedPlanSchema.parse(plan);
|
|
142
|
+
const canonical = CanonicalIntentHasher.stringify(parsed);
|
|
143
|
+
return `sha256:${createHash("sha256").update(canonical, "utf8").digest("hex")}`;
|
|
144
|
+
}
|
|
145
|
+
/** Whether a target is inside a step's scope: exact, or under a trailing-`*` prefix. */
|
|
146
|
+
export function planTargetInScope(scope, target) {
|
|
147
|
+
return scope.endsWith("*") ? target.startsWith(scope.slice(0, -1)) : target === scope;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Matches a proposal to one step of a plan and, when it fits, returns the
|
|
151
|
+
* reference the trusted executor stamps into the intent. A different action,
|
|
152
|
+
* a target outside the step's scope, or a parameter that differs from one the
|
|
153
|
+
* step pins is refused here, before anything is captured. The authority makes
|
|
154
|
+
* the same match itself; this one only fails fast.
|
|
155
|
+
*/
|
|
156
|
+
export function matchPlanStep(plan, stepId, proposal) {
|
|
157
|
+
const step = plan.steps.find((candidate) => candidate.step_id === stepId);
|
|
158
|
+
if (step === undefined)
|
|
159
|
+
return { ok: false, code: "PLAN_STEP_UNKNOWN" };
|
|
160
|
+
const mismatch = planStepMismatch(step, {
|
|
161
|
+
action: proposal.action,
|
|
162
|
+
target: proposal.target,
|
|
163
|
+
parameters: proposal.parameters,
|
|
164
|
+
});
|
|
165
|
+
if (mismatch !== null)
|
|
166
|
+
return { ok: false, code: mismatch };
|
|
167
|
+
return {
|
|
168
|
+
ok: true,
|
|
169
|
+
reference: { plan_id: plan.plan_id, plan_digest: planDigest(plan), step_id: step.step_id },
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/** The reason an action is outside a step, or null when it fits. */
|
|
173
|
+
export function planStepMismatch(step, action) {
|
|
174
|
+
if (action.action !== step.action)
|
|
175
|
+
return "PLAN_STEP_ACTION_MISMATCH";
|
|
176
|
+
if (!planTargetInScope(step.target, action.target))
|
|
177
|
+
return "PLAN_STEP_TARGET_OUT_OF_SCOPE";
|
|
178
|
+
for (const [name, pinned] of Object.entries(step.parameters ?? {})) {
|
|
179
|
+
const proposed = action.parameters[name];
|
|
180
|
+
if (proposed === undefined ||
|
|
181
|
+
CanonicalIntentHasher.stringify(proposed) !== CanonicalIntentHasher.stringify(pinned)) {
|
|
182
|
+
return "PLAN_STEP_PARAMETER_MISMATCH";
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=GovernedPlan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GovernedPlan.js","sourceRoot":"","sources":["../../src/plan/GovernedPlan.ts"],"names":[],"mappings":"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"}
|