@decionis/agent-safe-pipeline 0.1.4 → 0.3.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 (85) hide show
  1. package/README.md +170 -10
  2. package/dist/Index.d.ts +8 -0
  3. package/dist/Index.d.ts.map +1 -1
  4. package/dist/Index.js +7 -0
  5. package/dist/Index.js.map +1 -1
  6. package/dist/audit/AuditRecorder.d.ts +1 -1
  7. package/dist/audit/AuditRecorder.d.ts.map +1 -1
  8. package/dist/audit/AuditRecorder.js.map +1 -1
  9. package/dist/decision/CreateGate.d.ts +123 -0
  10. package/dist/decision/CreateGate.d.ts.map +1 -0
  11. package/dist/decision/CreateGate.js +211 -0
  12. package/dist/decision/CreateGate.js.map +1 -0
  13. package/dist/decision/DecionisGate.d.ts +18 -1
  14. package/dist/decision/DecionisGate.d.ts.map +1 -1
  15. package/dist/decision/DecionisGate.js +31 -3
  16. package/dist/decision/DecionisGate.js.map +1 -1
  17. package/dist/decision/DecisionAuthority.d.ts +26 -0
  18. package/dist/decision/DecisionAuthority.d.ts.map +1 -1
  19. package/dist/decision/DecisionAuthority.js.map +1 -1
  20. package/dist/decision/ImmutableGateDecision.d.ts.map +1 -1
  21. package/dist/decision/ImmutableGateDecision.js +8 -0
  22. package/dist/decision/ImmutableGateDecision.js.map +1 -1
  23. package/dist/decision/Provision.d.ts +33 -0
  24. package/dist/decision/Provision.d.ts.map +1 -0
  25. package/dist/decision/Provision.js +116 -0
  26. package/dist/decision/Provision.js.map +1 -0
  27. package/dist/decision/ShadowGate.d.ts +31 -0
  28. package/dist/decision/ShadowGate.d.ts.map +1 -0
  29. package/dist/decision/ShadowGate.js +79 -0
  30. package/dist/decision/ShadowGate.js.map +1 -0
  31. package/dist/execution/ActionRegistry.d.ts +40 -0
  32. package/dist/execution/ActionRegistry.d.ts.map +1 -1
  33. package/dist/execution/ActionRegistry.js +47 -2
  34. package/dist/execution/ActionRegistry.js.map +1 -1
  35. package/dist/execution/AuthorizationVerifier.d.ts +147 -1
  36. package/dist/execution/AuthorizationVerifier.d.ts.map +1 -1
  37. package/dist/execution/AuthorizationVerifier.js +209 -6
  38. package/dist/execution/AuthorizationVerifier.js.map +1 -1
  39. package/dist/execution/SafeExecutor.d.ts +34 -3
  40. package/dist/execution/SafeExecutor.d.ts.map +1 -1
  41. package/dist/execution/SafeExecutor.js +42 -5
  42. package/dist/execution/SafeExecutor.js.map +1 -1
  43. package/dist/http/ClientIdentification.d.ts +22 -0
  44. package/dist/http/ClientIdentification.d.ts.map +1 -0
  45. package/dist/http/ClientIdentification.js +44 -0
  46. package/dist/http/ClientIdentification.js.map +1 -0
  47. package/dist/http/Credential.d.ts +17 -0
  48. package/dist/http/Credential.d.ts.map +1 -0
  49. package/dist/http/Credential.js +5 -0
  50. package/dist/http/Credential.js.map +1 -0
  51. package/dist/http/StoredCredentials.d.ts +34 -0
  52. package/dist/http/StoredCredentials.d.ts.map +1 -0
  53. package/dist/http/StoredCredentials.js +85 -0
  54. package/dist/http/StoredCredentials.js.map +1 -0
  55. package/dist/intent/CanonicalIntentHasher.d.ts.map +1 -1
  56. package/dist/intent/CanonicalIntentHasher.js +3 -0
  57. package/dist/intent/CanonicalIntentHasher.js.map +1 -1
  58. package/dist/intent/ExecutionIntent.d.ts +13 -1
  59. package/dist/intent/ExecutionIntent.d.ts.map +1 -1
  60. package/dist/intent/ExecutionIntent.js +4 -0
  61. package/dist/intent/ExecutionIntent.js.map +1 -1
  62. package/dist/intent/IntentCapture.d.ts.map +1 -1
  63. package/dist/intent/IntentCapture.js +3 -0
  64. package/dist/intent/IntentCapture.js.map +1 -1
  65. package/dist/report/DecisionReport.d.ts +22 -0
  66. package/dist/report/DecisionReport.d.ts.map +1 -0
  67. package/dist/report/DecisionReport.js +37 -0
  68. package/dist/report/DecisionReport.js.map +1 -0
  69. package/dist/report/DossierReport.d.ts +43 -0
  70. package/dist/report/DossierReport.d.ts.map +1 -0
  71. package/dist/report/DossierReport.js +130 -0
  72. package/dist/report/DossierReport.js.map +1 -0
  73. package/dist/report/HostedOutcome.d.ts +18 -0
  74. package/dist/report/HostedOutcome.d.ts.map +1 -0
  75. package/dist/report/HostedOutcome.js +24 -0
  76. package/dist/report/HostedOutcome.js.map +1 -0
  77. package/dist/testing/Index.d.ts +1 -1
  78. package/dist/testing/Index.d.ts.map +1 -1
  79. package/dist/testing/Index.js +1 -1
  80. package/dist/testing/Index.js.map +1 -1
  81. package/dist/testing/LocalAuthority.d.ts +156 -0
  82. package/dist/testing/LocalAuthority.d.ts.map +1 -1
  83. package/dist/testing/LocalAuthority.js +531 -9
  84. package/dist/testing/LocalAuthority.js.map +1 -1
  85. package/package.json +1 -1
@@ -21,6 +21,14 @@ export function immutableGateDecision(decision) {
21
21
  reasonCodes: Object.freeze([...decision.managedEscalation.reasonCodes]),
22
22
  }),
23
23
  }),
24
+ ...(decision.hosted === undefined
25
+ ? {}
26
+ : {
27
+ hosted: Object.freeze({
28
+ ...decision.hosted,
29
+ reasonCodes: Object.freeze([...decision.hosted.reasonCodes]),
30
+ }),
31
+ }),
24
32
  });
25
33
  }
26
34
  //# sourceMappingURL=ImmutableGateDecision.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImmutableGateDecision.js","sourceRoot":"","sources":["../../src/decision/ImmutableGateDecision.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CAAC,QAAsB;IAC1D,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,GAAG,QAAQ;QACX,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QACrD,aAAa,EACX,QAAQ,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC;QACvF,GAAG,CAAC,QAAQ,CAAC,QAAQ,KAAK,SAAS;YACjC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC;oBACtB,GAAG,QAAQ,CAAC,QAAQ;oBACpB,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,KAAK,SAAS;wBAC/C,CAAC,CAAC,EAAE;wBACJ,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,EAAE,CAAC;iBAC9E,CAAC;aACH,CAAC;QACN,GAAG,CAAC,QAAQ,CAAC,iBAAiB,KAAK,SAAS;YAC1C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC;oBAC/B,GAAG,QAAQ,CAAC,iBAAiB;oBAC7B,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;iBACxE,CAAC;aACH,CAAC;KACP,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"ImmutableGateDecision.js","sourceRoot":"","sources":["../../src/decision/ImmutableGateDecision.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CAAC,QAAsB;IAC1D,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,GAAG,QAAQ;QACX,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QACrD,aAAa,EACX,QAAQ,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC;QACvF,GAAG,CAAC,QAAQ,CAAC,QAAQ,KAAK,SAAS;YACjC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC;oBACtB,GAAG,QAAQ,CAAC,QAAQ;oBACpB,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,KAAK,SAAS;wBAC/C,CAAC,CAAC,EAAE;wBACJ,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,EAAE,CAAC;iBAC9E,CAAC;aACH,CAAC;QACN,GAAG,CAAC,QAAQ,CAAC,iBAAiB,KAAK,SAAS;YAC1C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC;oBAC/B,GAAG,QAAQ,CAAC,iBAAiB;oBAC7B,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;iBACxE,CAAC;aACH,CAAC;QACN,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,SAAS;YAC/B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;oBACpB,GAAG,QAAQ,CAAC,MAAM;oBAClB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;iBAC7D,CAAC;aACH,CAAC;KACP,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { type ClientSource } from "../http/ClientIdentification.js";
2
+ export interface ProvisionOptions {
3
+ /** The authority to provision from; HTTPS, or loopback when allowed. */
4
+ readonly baseUrl: string;
5
+ readonly allowInsecureLoopback?: boolean;
6
+ readonly fetch?: typeof fetch;
7
+ readonly timeoutMs?: number;
8
+ readonly source?: ClientSource;
9
+ /** Shown to the person who later claims the workspace. */
10
+ readonly agentName?: string;
11
+ }
12
+ export interface ProvisionedWorkspace {
13
+ readonly orgId: string;
14
+ /** The key, seen here and nowhere else; the caller stores it. */
15
+ readonly rawKey: string;
16
+ readonly provisional: true;
17
+ /** The caps on the anonymous lane, as the authority stated them. */
18
+ readonly limits: Readonly<Record<string, unknown>>;
19
+ /** How a person attaches themselves to the workspace, as the authority stated it. */
20
+ readonly claim: Readonly<Record<string, unknown>>;
21
+ }
22
+ export declare class ProvisionError extends Error {
23
+ readonly code: "PROVISION_LIMIT_REACHED" | "PROVISION_REFUSED" | "PROVISION_UNAVAILABLE" | "PROVISION_RESPONSE_INVALID" | "PROVISION_TIMED_OUT";
24
+ readonly status: number | null;
25
+ /** Seconds to wait before another attempt, when the authority said. */
26
+ readonly retryAfterSeconds: number | null;
27
+ constructor(code: "PROVISION_LIMIT_REACHED" | "PROVISION_REFUSED" | "PROVISION_UNAVAILABLE" | "PROVISION_RESPONSE_INVALID" | "PROVISION_TIMED_OUT", status: number | null,
28
+ /** Seconds to wait before another attempt, when the authority said. */
29
+ retryAfterSeconds?: number | null);
30
+ }
31
+ /** Mints a provisional workspace, or throws a `ProvisionError` that names why. */
32
+ export declare function provisionWorkspace(options: ProvisionOptions): Promise<ProvisionedWorkspace>;
33
+ //# sourceMappingURL=Provision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Provision.d.ts","sourceRoot":"","sources":["../../src/decision/Provision.ts"],"names":[],"mappings":"AAcA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/E,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,qFAAqF;IACrF,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACnD;AAoBD,qBAAa,cAAe,SAAQ,KAAK;aAErB,IAAI,EAChB,yBAAyB,GACzB,mBAAmB,GACnB,uBAAuB,GACvB,4BAA4B,GAC5B,qBAAqB;aACT,MAAM,EAAE,MAAM,GAAG,IAAI;IACrC,uEAAuE;aACvD,iBAAiB,EAAE,MAAM,GAAG,IAAI;gBARhC,IAAI,EAChB,yBAAyB,GACzB,mBAAmB,GACnB,uBAAuB,GACvB,4BAA4B,GAC5B,qBAAqB,EACT,MAAM,EAAE,MAAM,GAAG,IAAI;IACrC,uEAAuE;IACvD,iBAAiB,GAAE,MAAM,GAAG,IAAW;CAK1D;AAQD,kFAAkF;AAClF,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA8DjG"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * A free Decionis key, issued in the run itself. `POST
3
+ * /v1/public/agents/provision` mints a provisional workspace with no
4
+ * account, no email and no card: an organization id, a key returned exactly
5
+ * once, an allowance of governed decisions, and the way a person later
6
+ * claims it. Every dossier such a workspace mints is signed with the
7
+ * `provisional_anonymous` issuer tier, so a verifier can always tell it
8
+ * from an owned organization's record. The call carries the client
9
+ * identification the hosted gate carries, so the authority can say which
10
+ * repository, example and surface the workspace came from.
11
+ */
12
+ import { z } from "zod";
13
+ import { AuthorityBaseUrl } from "../http/AuthorityBaseUrl.js";
14
+ import { BoundedResponseBody } from "../http/BoundedResponseBody.js";
15
+ import { userAgent } from "../http/ClientIdentification.js";
16
+ const MAX_RESPONSE_BYTES = 64 * 1024;
17
+ const DEFAULT_TIMEOUT_MS = 8_000;
18
+ const MAX_AGENT_NAME = 64;
19
+ /**
20
+ * Mirrors `AgentProvisionResponse`: the four fields the caller needs are
21
+ * required; the rest of the contract is open and rides along as it came.
22
+ */
23
+ const ProvisionResponseSchema = z
24
+ .object({
25
+ org_id: z.string().uuid(),
26
+ raw_key: z.string().min(1).max(4_096),
27
+ provisional: z.literal(true),
28
+ limits: z.record(z.string(), z.unknown()).default({}),
29
+ claim: z.record(z.string(), z.unknown()).default({}),
30
+ })
31
+ .passthrough();
32
+ export class ProvisionError extends Error {
33
+ code;
34
+ status;
35
+ retryAfterSeconds;
36
+ constructor(code, status,
37
+ /** Seconds to wait before another attempt, when the authority said. */
38
+ retryAfterSeconds = null) {
39
+ super(code);
40
+ this.code = code;
41
+ this.status = status;
42
+ this.retryAfterSeconds = retryAfterSeconds;
43
+ this.name = "ProvisionError";
44
+ }
45
+ }
46
+ function retryAfter(response) {
47
+ const value = response.headers.get("retry-after");
48
+ if (value === null || !/^\d{1,7}$/.test(value.trim()))
49
+ return null;
50
+ return Number(value.trim());
51
+ }
52
+ /** Mints a provisional workspace, or throws a `ProvisionError` that names why. */
53
+ export async function provisionWorkspace(options) {
54
+ const baseUrl = AuthorityBaseUrl.normalize(options.baseUrl, options.allowInsecureLoopback ?? false);
55
+ const doFetch = options.fetch ?? fetch;
56
+ const controller = new AbortController();
57
+ const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
58
+ const agentName = options.agentName?.slice(0, MAX_AGENT_NAME);
59
+ let response;
60
+ try {
61
+ response = await doFetch(`${baseUrl}/v1/public/agents/provision`, {
62
+ method: "POST",
63
+ headers: {
64
+ "content-type": "application/json",
65
+ accept: "application/json",
66
+ "user-agent": userAgent(options.source),
67
+ },
68
+ body: JSON.stringify(agentName === undefined ? {} : { agent_name: agentName }),
69
+ redirect: "error",
70
+ signal: controller.signal,
71
+ });
72
+ }
73
+ catch {
74
+ clearTimeout(timer);
75
+ throw new ProvisionError(controller.signal.aborted ? "PROVISION_TIMED_OUT" : "PROVISION_UNAVAILABLE", null);
76
+ }
77
+ let text;
78
+ try {
79
+ text = await BoundedResponseBody.read(response, MAX_RESPONSE_BYTES);
80
+ }
81
+ catch {
82
+ text = null;
83
+ }
84
+ finally {
85
+ clearTimeout(timer);
86
+ }
87
+ if (response.status === 429) {
88
+ throw new ProvisionError("PROVISION_LIMIT_REACHED", 429, retryAfter(response));
89
+ }
90
+ if (response.status >= 500) {
91
+ throw new ProvisionError("PROVISION_UNAVAILABLE", response.status, retryAfter(response));
92
+ }
93
+ if (response.status !== 201 && response.status !== 200) {
94
+ throw new ProvisionError("PROVISION_REFUSED", response.status);
95
+ }
96
+ if (text === null)
97
+ throw new ProvisionError("PROVISION_RESPONSE_INVALID", response.status);
98
+ let body;
99
+ try {
100
+ body = JSON.parse(text);
101
+ }
102
+ catch {
103
+ throw new ProvisionError("PROVISION_RESPONSE_INVALID", response.status);
104
+ }
105
+ const parsed = ProvisionResponseSchema.safeParse(body);
106
+ if (!parsed.success)
107
+ throw new ProvisionError("PROVISION_RESPONSE_INVALID", response.status);
108
+ return {
109
+ orgId: parsed.data.org_id,
110
+ rawKey: parsed.data.raw_key,
111
+ provisional: true,
112
+ limits: parsed.data.limits,
113
+ claim: parsed.data.claim,
114
+ };
115
+ }
116
+ //# sourceMappingURL=Provision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Provision.js","sourceRoot":"","sources":["../../src/decision/Provision.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { CapturedIntent } from "../intent/ExecutionIntent.js";
2
+ import { type DecisionAuthority, type DecisionEvaluationMode, type DecisionEvaluationOptions, type DecisionEvidence, type GateDecision } from "./DecisionAuthority.js";
3
+ /**
4
+ * Runs a local authority and a hosted Decionis gate against the same intent.
5
+ *
6
+ * `SHADOW`: the local decision governs execution exactly as it would alone,
7
+ * and the hosted evaluation rides along as `hosted` for display and audit. A
8
+ * hosted failure is recorded and changes nothing, so setting a key cannot
9
+ * break an integration that works today.
10
+ *
11
+ * `ENFORCEMENT`: the hosted decision governs, because only its grant can be
12
+ * claimed by the enforcement verifier. The local authority can still tighten
13
+ * it: when the local verdict is strictly more restrictive, that decision is
14
+ * returned instead, and it carries no hosted grant.
15
+ *
16
+ * Neither mode returns a decision less restrictive than the local authority's.
17
+ */
18
+ export declare class ShadowGate implements DecisionAuthority {
19
+ private readonly local;
20
+ private readonly hosted;
21
+ private readonly mode;
22
+ readonly evaluationMode?: DecisionEvaluationMode;
23
+ constructor(local: DecisionAuthority, hosted: DecisionAuthority, mode: DecisionEvaluationMode);
24
+ evaluate(captured: CapturedIntent, evidence?: DecisionEvidence, options?: DecisionEvaluationOptions): Promise<GateDecision>;
25
+ /**
26
+ * The hosted side never rejects and never answers about another intent:
27
+ * either would let a network fault or a misbound service reach execution.
28
+ */
29
+ private hostedDecision;
30
+ }
31
+ //# sourceMappingURL=ShadowGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShadowGate.d.ts","sourceRoot":"","sources":["../../src/decision/ShadowGate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EAErB,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAUhC;;;;;;;;;;;;;;GAcG;AACH,qBAAa,UAAW,YAAW,iBAAiB;IAIhD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IALvB,SAAgB,cAAc,CAAC,EAAE,sBAAsB,CAAC;gBAGrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,sBAAsB;IASlC,QAAQ,CACnB,QAAQ,EAAE,cAAc,EACxB,QAAQ,CAAC,EAAE,gBAAgB,EAC3B,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,YAAY,CAAC;IAuBxB;;;OAGG;YACW,cAAc;CAgB7B"}
@@ -0,0 +1,79 @@
1
+ import { FailClosedDecision, } from "./DecisionAuthority.js";
2
+ import { immutableGateDecision } from "./ImmutableGateDecision.js";
3
+ /** Higher is more restrictive. The Decionis contract has no fourth verdict. */
4
+ const RESTRICTIVENESS = Object.freeze({
5
+ ALLOW: 0,
6
+ ESCALATE: 1,
7
+ BLOCK: 2,
8
+ });
9
+ /**
10
+ * Runs a local authority and a hosted Decionis gate against the same intent.
11
+ *
12
+ * `SHADOW`: the local decision governs execution exactly as it would alone,
13
+ * and the hosted evaluation rides along as `hosted` for display and audit. A
14
+ * hosted failure is recorded and changes nothing, so setting a key cannot
15
+ * break an integration that works today.
16
+ *
17
+ * `ENFORCEMENT`: the hosted decision governs, because only its grant can be
18
+ * claimed by the enforcement verifier. The local authority can still tighten
19
+ * it: when the local verdict is strictly more restrictive, that decision is
20
+ * returned instead, and it carries no hosted grant.
21
+ *
22
+ * Neither mode returns a decision less restrictive than the local authority's.
23
+ */
24
+ export class ShadowGate {
25
+ local;
26
+ hosted;
27
+ mode;
28
+ evaluationMode;
29
+ constructor(local, hosted, mode) {
30
+ this.local = local;
31
+ this.hosted = hosted;
32
+ this.mode = mode;
33
+ if (mode !== "SHADOW" && mode !== "ENFORCEMENT") {
34
+ throw new Error("DECIONIS_GATE_MODE_INVALID");
35
+ }
36
+ const declared = mode === "ENFORCEMENT" ? mode : local.evaluationMode;
37
+ if (declared !== undefined)
38
+ this.evaluationMode = declared;
39
+ }
40
+ async evaluate(captured, evidence, options = {}) {
41
+ const [local, hosted] = await Promise.all([
42
+ this.local.evaluate(captured, evidence, options),
43
+ this.hostedDecision(captured, evidence, options),
44
+ ]);
45
+ const governs = this.mode === "ENFORCEMENT" &&
46
+ RESTRICTIVENESS[hosted.verdict] >= RESTRICTIVENESS[local.verdict];
47
+ return immutableGateDecision({
48
+ ...(governs ? hosted : local),
49
+ hosted: {
50
+ mode: this.mode,
51
+ governs,
52
+ verdict: hosted.verdict,
53
+ decisionId: hosted.decisionId,
54
+ dossierId: hosted.dossierId,
55
+ reasonCodes: hosted.reasonCodes,
56
+ failClosed: hosted.failClosed,
57
+ verificationUrl: hosted.verificationUrl ?? null,
58
+ },
59
+ });
60
+ }
61
+ /**
62
+ * The hosted side never rejects and never answers about another intent:
63
+ * either would let a network fault or a misbound service reach execution.
64
+ */
65
+ async hostedDecision(captured, evidence, options) {
66
+ let decision;
67
+ try {
68
+ decision = await this.hosted.evaluate(captured, evidence, options);
69
+ }
70
+ catch {
71
+ return FailClosedDecision.create(captured.intentHash, "AUTHORITY_UNAVAILABLE");
72
+ }
73
+ if (decision.intentHash !== captured.intentHash) {
74
+ return FailClosedDecision.create(captured.intentHash, "AUTHORITY_BINDING_MISMATCH");
75
+ }
76
+ return decision;
77
+ }
78
+ }
79
+ //# sourceMappingURL=ShadowGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShadowGate.js","sourceRoot":"","sources":["../../src/decision/ShadowGate.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,GAOnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,+EAA+E;AAC/E,MAAM,eAAe,GAA8C,MAAM,CAAC,MAAM,CAAC;IAC/E,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;CACT,CAAC,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,UAAU;IAIF;IACA;IACA;IALH,cAAc,CAA0B;IAExD,YACmB,KAAwB,EACxB,MAAyB,EACzB,IAA4B;QAF5B,UAAK,GAAL,KAAK,CAAmB;QACxB,WAAM,GAAN,MAAM,CAAmB;QACzB,SAAI,GAAJ,IAAI,CAAwB;QAE7C,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC;QACtE,IAAI,QAAQ,KAAK,SAAS;YAAE,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;IAC7D,CAAC;IAEM,KAAK,CAAC,QAAQ,CACnB,QAAwB,EACxB,QAA2B,EAC3B,UAAqC,EAAE;QAEvC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC;YAChD,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC;SACjD,CAAC,CAAC;QACH,MAAM,OAAO,GACX,IAAI,CAAC,IAAI,KAAK,aAAa;YAC3B,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpE,OAAO,qBAAqB,CAAC;YAC3B,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;YAC7B,MAAM,EAAE;gBACN,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO;gBACP,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,IAAI;aAChD;SACF,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,cAAc,CAC1B,QAAwB,EACxB,QAAsC,EACtC,OAAkC;QAElC,IAAI,QAAsB,CAAC;QAC3B,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC;YAChD,OAAO,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,4BAA4B,CAAC,CAAC;QACtF,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
@@ -15,6 +15,14 @@ export interface ActionExecutionContext<TParameters> {
15
15
  export interface ProviderDispatch {
16
16
  readonly idempotencyKey: string;
17
17
  run<TResult>(operation: (idempotencyKey: string) => Promise<TResult> | TResult): Promise<TResult>;
18
+ /**
19
+ * The provider's signed effect receipt, when it returned one with its
20
+ * answer, verbatim. It is carried on the attempt to the finalization, where
21
+ * the verifier forwards it to the authority to verify and record; this
22
+ * package never reads it. Only meaningful inside `run`: a receipt before
23
+ * the dispatch describes nothing.
24
+ */
25
+ receipt(token: string): void;
18
26
  }
19
27
  export interface ActionReconciliationContext<TParameters> {
20
28
  readonly intent: CapturedIntent;
@@ -38,11 +46,43 @@ export interface ActionHandler<TParameters, TResult> {
38
46
  export type ActionExecutionAttempt = {
39
47
  readonly status: "COMPLETED";
40
48
  readonly result: unknown;
49
+ readonly receipt: string | null;
41
50
  } | {
42
51
  readonly status: "FAILED_BEFORE_DISPATCH";
52
+ } | {
53
+ readonly status: "REFUSED_AFTER_DISPATCH";
54
+ readonly reason: string;
55
+ readonly receipt: string | null;
43
56
  } | {
44
57
  readonly status: "UNKNOWN_AFTER_DISPATCH";
58
+ readonly receipt: string | null;
45
59
  };
60
+ /**
61
+ * What a handler throws when the provider refused, definitively, after the
62
+ * dispatch boundary was crossed.
63
+ *
64
+ * Without this, a handler has two ways to report a refusal and neither is
65
+ * true. Returning normally says the side effect happened. Throwing says the
66
+ * outcome is unknown, which invites a reconciliation of something that never
67
+ * needed one. This says the third thing: the request reached the provider,
68
+ * the provider said no, and nothing was effected.
69
+ *
70
+ * Only the provider's own deterministic refusal belongs here — a 4xx with a
71
+ * body that says which rule refused it. A timeout, a 5xx, a dropped
72
+ * connection or an unreadable answer is not a refusal, and throwing this for
73
+ * one of those would turn "nobody knows" into "definitely not", which is the
74
+ * one direction this boundary must never move in.
75
+ *
76
+ * Thrown before the dispatch, it is a handler failure like any other: a
77
+ * refusal cannot be claimed for a request that was never sent.
78
+ */
79
+ export declare class ProviderRefusal extends Error {
80
+ /** The provider's own reason, as a code; never its response body. */
81
+ readonly reason: string;
82
+ constructor(
83
+ /** The provider's own reason, as a code; never its response body. */
84
+ reason: string);
85
+ }
46
86
  export declare class ActionRegistry {
47
87
  private readonly actions;
48
88
  private readonly pendingReconciliations;
@@ -1 +1 @@
1
- {"version":3,"file":"ActionRegistry.d.ts","sourceRoot":"","sources":["../../src/execution/ActionRegistry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ActionRegistry.d.ts","sourceRoot":"","sources":["../../src/execution/ActionRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAExE,MAAM,WAAW,sBAAsB,CAAC,WAAW;IACjD,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClG;;;;;;OAMG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,2BAA2B,CAAC,WAAW;IACtD,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,sBAAsB,CAAC,OAAO,IACtC;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC1D;IAAE,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;CAAE,GACnC;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAEnC,MAAM,WAAW,aAAa,CAAC,WAAW,EAAE,OAAO;IACjD,QAAQ,CAAC,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAClD,OAAO,CAAC,OAAO,EAAE,sBAAsB,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAClF,gFAAgF;IAChF,SAAS,CAAC,CACR,OAAO,EAAE,2BAA2B,CAAC,WAAW,CAAC,GAChD,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;CAC/E;AAUD,MAAM,MAAM,sBAAsB,GAC9B;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3F;IAAE,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAA;CAAE,GAC7C;IACE,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,GACD;IAAE,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAEnF;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IAEtC,qEAAqE;aACrD,MAAM,EAAE,MAAM;;IAD9B,qEAAqE;IACrD,MAAM,EAAE,MAAM;CAKjC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAGnC;IACJ,OAAO,CAAC,MAAM,CAAS;IAEhB,QAAQ,CAAC,WAAW,EAAE,OAAO,EAClC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,GAC3C,IAAI;IAOA,IAAI,IAAI,IAAI;IAKZ,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAI5B,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IASlC,OAAO,CAClB,QAAQ,EAAE,cAAc,EACxB,aAAa,EAAE,qBAAqB,GACnC,OAAO,CAAC,OAAO,CAAC;IAMN,cAAc,CACzB,QAAQ,EAAE,cAAc,EACxB,aAAa,EAAE,qBAAqB,GACnC,OAAO,CAAC,sBAAsB,CAAC;IAgDrB,SAAS,CACpB,QAAQ,EAAE,cAAc,EACxB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IA+B3C,OAAO,CAAC,mBAAmB;CAiB5B"}
@@ -1,3 +1,32 @@
1
+ /**
2
+ * What a handler throws when the provider refused, definitively, after the
3
+ * dispatch boundary was crossed.
4
+ *
5
+ * Without this, a handler has two ways to report a refusal and neither is
6
+ * true. Returning normally says the side effect happened. Throwing says the
7
+ * outcome is unknown, which invites a reconciliation of something that never
8
+ * needed one. This says the third thing: the request reached the provider,
9
+ * the provider said no, and nothing was effected.
10
+ *
11
+ * Only the provider's own deterministic refusal belongs here — a 4xx with a
12
+ * body that says which rule refused it. A timeout, a 5xx, a dropped
13
+ * connection or an unreadable answer is not a refusal, and throwing this for
14
+ * one of those would turn "nobody knows" into "definitely not", which is the
15
+ * one direction this boundary must never move in.
16
+ *
17
+ * Thrown before the dispatch, it is a handler failure like any other: a
18
+ * refusal cannot be claimed for a request that was never sent.
19
+ */
20
+ export class ProviderRefusal extends Error {
21
+ reason;
22
+ constructor(
23
+ /** The provider's own reason, as a code; never its response body. */
24
+ reason) {
25
+ super(reason);
26
+ this.reason = reason;
27
+ this.name = "ProviderRefusal";
28
+ }
29
+ }
1
30
  export class ActionRegistry {
2
31
  actions = new Map();
3
32
  pendingReconciliations = new Map();
@@ -43,6 +72,7 @@ export class ActionRegistry {
43
72
  if (!result.success)
44
73
  throw new Error("ACTION_PARAMETERS_INVALID");
45
74
  let dispatched = false;
75
+ let receipt = null;
46
76
  const dispatch = Object.freeze({
47
77
  idempotencyKey: captured.intent.idempotencyKey,
48
78
  run: async (operation) => {
@@ -51,6 +81,11 @@ export class ActionRegistry {
51
81
  dispatched = true;
52
82
  return await operation(captured.intent.idempotencyKey);
53
83
  },
84
+ receipt: (token) => {
85
+ if (!dispatched)
86
+ throw new Error("PROVIDER_RECEIPT_BEFORE_DISPATCH");
87
+ receipt = token;
88
+ },
54
89
  });
55
90
  try {
56
91
  return {
@@ -61,10 +96,20 @@ export class ActionRegistry {
61
96
  authorization,
62
97
  dispatch,
63
98
  }),
99
+ receipt,
64
100
  };
65
101
  }
66
- catch {
67
- return { status: dispatched ? "UNKNOWN_AFTER_DISPATCH" : "FAILED_BEFORE_DISPATCH" };
102
+ catch (error) {
103
+ // A refusal the provider made is only a refusal if the request reached
104
+ // it. Before the dispatch it is a handler failure, because nothing was
105
+ // sent for anyone to refuse. A receipt can accompany either answer
106
+ // after the dispatch: a provider's signed refusal is evidence too.
107
+ if (dispatched && error instanceof ProviderRefusal) {
108
+ return { status: "REFUSED_AFTER_DISPATCH", reason: error.reason, receipt };
109
+ }
110
+ return dispatched
111
+ ? { status: "UNKNOWN_AFTER_DISPATCH", receipt }
112
+ : { status: "FAILED_BEFORE_DISPATCH" };
68
113
  }
69
114
  }
70
115
  async reconcile(captured, idempotencyKey) {
@@ -1 +1 @@
1
- {"version":3,"file":"ActionRegistry.js","sourceRoot":"","sources":["../../src/execution/ActionRegistry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ActionRegistry.js","sourceRoot":"","sources":["../../src/execution/ActionRegistry.ts"],"names":[],"mappings":"AAmEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAGtB;IAFlB;IACE,qEAAqE;IACrD,MAAc;QAE9B,KAAK,CAAC,MAAM,CAAC,CAAC;QAFE,WAAM,GAAN,MAAM,CAAQ;QAG9B,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,OAAO,cAAc;IACR,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC9C,sBAAsB,GAAG,IAAI,GAAG,EAG9C,CAAC;IACI,MAAM,GAAG,KAAK,CAAC;IAEhB,QAAQ,CACb,MAAc,EACd,OAA4C;QAE5C,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC3D,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC3E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAA2B,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,IAAI;QACT,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,MAAc;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAEM,QAAQ,CAAC,QAAwB;QACtC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;YAC5E,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,OAAO,CAClB,QAAwB,EACxB,aAAoC;QAEpC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACnE,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAEM,KAAK,CAAC,cAAc,CACzB,QAAwB,EACxB,aAAoC;QAEpC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC9E,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAClE,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,IAAI,OAAO,GAAkB,IAAI,CAAC;QAClC,MAAM,QAAQ,GAAqB,MAAM,CAAC,MAAM,CAAC;YAC/C,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc;YAC9C,GAAG,EAAE,KAAK,EACR,SAAiE,EAC/C,EAAE;gBACpB,IAAI,UAAU;oBAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;gBACrE,UAAU,GAAG,IAAI,CAAC;gBAClB,OAAO,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YACzD,CAAC;YACD,OAAO,EAAE,CAAC,KAAa,EAAQ,EAAE;gBAC/B,IAAI,CAAC,UAAU;oBAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBACrE,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,OAAO;gBACL,MAAM,EAAE,WAAW;gBACnB,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC;oBAC5B,MAAM,EAAE,QAAQ;oBAChB,UAAU,EAAE,MAAM,CAAC,IAAI;oBACvB,aAAa;oBACb,QAAQ;iBACT,CAAC;gBACF,OAAO;aACR,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,uEAAuE;YACvE,uEAAuE;YACvE,mEAAmE;YACnE,mEAAmE;YACnE,IAAI,UAAU,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;gBACnD,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAC7E,CAAC;YACD,OAAO,UAAU;gBACf,CAAC,CAAC,EAAE,MAAM,EAAE,wBAAwB,EAAE,OAAO,EAAE;gBAC/C,CAAC,CAAC,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;QAC3C,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,SAAS,CACpB,QAAwB,EACxB,cAAsB;QAEtB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChE,IAAI,cAAc,KAAK,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAClF,IAAI,CAAC,UAAU,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACtE,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAElE,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,UAAU,SAAS,cAAc,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrD,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,MAAM,OAAO,CAAC;QAEhD,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,EAAE;aACrC,IAAI,CAAC,KAAK,IAAI,EAAE,CACf,IAAI,CAAC,mBAAmB,CACtB,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC;YACxB,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,UAAU,CAAC,IAAI;YAC3B,cAAc;SACf,CAAC,CACH,CACF;aACA,KAAK,CAAC,GAAoC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;aACrE,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QACrD,OAAO,MAAM,cAAc,CAAC;IAC9B,CAAC;IAEO,mBAAmB,CAAC,KAAc;QACxC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACxE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC/B,CAAC;QACD,MAAM,MAAM,GAAG,KAAgC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YAChF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3D,CAAC;QACD,IACE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,cAAc,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC;YACvE,IAAI,CAAC,MAAM,KAAK,CAAC,EACjB,CAAC;YACD,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC/B,CAAC;CACF"}