@agenticprimitives/orchestration 0.0.0-alpha.1 → 0.0.0-alpha.2

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 (61) hide show
  1. package/dist/admission.d.ts +87 -0
  2. package/dist/admission.d.ts.map +1 -0
  3. package/dist/admission.js +193 -0
  4. package/dist/admission.js.map +1 -0
  5. package/dist/artifacts.d.ts +137 -0
  6. package/dist/artifacts.d.ts.map +1 -0
  7. package/dist/artifacts.js +232 -0
  8. package/dist/artifacts.js.map +1 -0
  9. package/dist/authority.d.ts +431 -0
  10. package/dist/authority.d.ts.map +1 -0
  11. package/dist/authority.js +2 -0
  12. package/dist/authority.js.map +1 -0
  13. package/dist/durable.d.ts +44 -0
  14. package/dist/durable.d.ts.map +1 -0
  15. package/dist/durable.js +15 -0
  16. package/dist/durable.js.map +1 -0
  17. package/dist/flow-trace.d.ts +105 -0
  18. package/dist/flow-trace.d.ts.map +1 -0
  19. package/dist/flow-trace.js +60 -0
  20. package/dist/flow-trace.js.map +1 -0
  21. package/dist/index.d.ts +20 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +21 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/input.d.ts +165 -0
  26. package/dist/input.d.ts.map +1 -0
  27. package/dist/input.js +33 -0
  28. package/dist/input.js.map +1 -0
  29. package/dist/loop.d.ts +115 -3
  30. package/dist/loop.d.ts.map +1 -1
  31. package/dist/loop.js +656 -30
  32. package/dist/loop.js.map +1 -1
  33. package/dist/metrics.d.ts +35 -0
  34. package/dist/metrics.d.ts.map +1 -0
  35. package/dist/metrics.js +98 -0
  36. package/dist/metrics.js.map +1 -0
  37. package/dist/planner-wire.d.ts +11 -0
  38. package/dist/planner-wire.d.ts.map +1 -0
  39. package/dist/planner-wire.js +53 -0
  40. package/dist/planner-wire.js.map +1 -0
  41. package/dist/planner.d.ts +33 -0
  42. package/dist/planner.d.ts.map +1 -1
  43. package/dist/planner.js.map +1 -1
  44. package/dist/record.d.ts +151 -0
  45. package/dist/record.d.ts.map +1 -0
  46. package/dist/record.js +72 -0
  47. package/dist/record.js.map +1 -0
  48. package/dist/spans.d.ts +200 -0
  49. package/dist/spans.d.ts.map +1 -0
  50. package/dist/spans.js +522 -0
  51. package/dist/spans.js.map +1 -0
  52. package/dist/tool-invoker.d.ts +7 -0
  53. package/dist/tool-invoker.d.ts.map +1 -1
  54. package/dist/trace-context.d.ts +26 -0
  55. package/dist/trace-context.d.ts.map +1 -0
  56. package/dist/trace-context.js +59 -0
  57. package/dist/trace-context.js.map +1 -0
  58. package/dist/types.d.ts +180 -3
  59. package/dist/types.d.ts.map +1 -1
  60. package/dist/types.js.map +1 -1
  61. package/package.json +4 -1
@@ -0,0 +1,26 @@
1
+ /** The parsed `traceparent`. Ids are lowercase hex, W3C-sized (16-byte trace, 8-byte span). */
2
+ export interface TraceContextV1 {
3
+ traceId: string;
4
+ parentSpanId: string;
5
+ /** The `traceparent` flags byte (`01` = sampled). Carried, never acted on. */
6
+ flags: string;
7
+ /** The `tracestate` header verbatim, when one arrived. Opaque to this substrate except its own `ap` member. */
8
+ tracestate?: string;
9
+ }
10
+ /** Parse a `traceparent` header per W3C Trace Context level 2: version `00` (a higher version is read with
11
+ * the same first four fields), non-zero trace and span ids. Anything else is `null` — never a partial. */
12
+ export declare function parseTraceparent(header: string | null | undefined): Omit<TraceContextV1, 'tracestate'> | null;
13
+ /** The `traceparent` this run puts on an OUTBOUND hop: our trace, the current span as the parent. */
14
+ export declare function formatTraceparent(traceId: string, spanId: string, opts?: {
15
+ sampled?: boolean;
16
+ }): string;
17
+ /** `tracestate` with this substrate's member set (`ap=<value>`) at the front — W3C: a vendor updating its
18
+ * member moves it to the left, the list is capped at 32 members, and foreign members are kept verbatim. */
19
+ export declare function withTracestateMember(existing: string | null | undefined, key: string, value: string): string;
20
+ /** This substrate's member of a `tracestate`, when present. */
21
+ export declare function tracestateMember(state: string | null | undefined, key: string): string | null;
22
+ /** What an inbound request carried, as the run records it — or `null` when it carried nothing usable. */
23
+ export declare function traceContextOf(headers: {
24
+ get(name: string): string | null;
25
+ }): TraceContextV1 | null;
26
+ //# sourceMappingURL=trace-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-context.d.ts","sourceRoot":"","sources":["../src/trace-context.ts"],"names":[],"mappings":"AAUA,+FAA+F;AAC/F,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,+GAA+G;IAC/G,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID;2GAC2G;AAC3G,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,GAAG,IAAI,CAU7G;AAED,qGAAqG;AACrG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CAG3G;AAED;4GAC4G;AAC5G,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK5G;AAED,+DAA+D;AAC/D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM7F;AAED,yGAAyG;AACzG,wBAAgB,cAAc,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,cAAc,GAAG,IAAI,CAKnG"}
@@ -0,0 +1,59 @@
1
+ // W3C TRACE CONTEXT — spec 390 W2. The wire form of "these hops are one causal operation": `traceparent`
2
+ // (version-traceId-parentSpanId-flags) and `tracestate` (vendor members). Pure; nothing here touches a
3
+ // header object, a fetch or a store — the app reads and writes the headers and hands strings in.
4
+ //
5
+ // CORRELATION, NEVER TRUST. A `traceparent` that arrives with a request joins the run's spans to the
6
+ // caller's trace. That is all it does. Admission does not read it, a verdict does not read it, and a
7
+ // forged one can at most mis-file a trace — the authority twin in `trace-context.test.ts` proves the
8
+ // verdicts of a run are identical with and without one. An absent or malformed header means the run's
9
+ // ids DERIVE from its references (spec 381 W2): a fact about the input, not an escalation (ADR-0013).
10
+ const TRACEPARENT = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
11
+ /** Parse a `traceparent` header per W3C Trace Context level 2: version `00` (a higher version is read with
12
+ * the same first four fields), non-zero trace and span ids. Anything else is `null` — never a partial. */
13
+ export function parseTraceparent(header) {
14
+ const raw = (header ?? '').trim().toLowerCase();
15
+ // A future version may append fields after the flags; read the first four and ignore the rest.
16
+ const head = raw.startsWith('00-') ? raw : raw.replace(/^([0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}).*$/, '$1');
17
+ const m = TRACEPARENT.exec(head);
18
+ if (!m)
19
+ return null;
20
+ const [, version, traceId, parentSpanId, flags] = m;
21
+ if (version === 'ff')
22
+ return null; // reserved
23
+ if (/^0+$/.test(traceId) || /^0+$/.test(parentSpanId))
24
+ return null;
25
+ return { traceId: traceId, parentSpanId: parentSpanId, flags: flags };
26
+ }
27
+ /** The `traceparent` this run puts on an OUTBOUND hop: our trace, the current span as the parent. */
28
+ export function formatTraceparent(traceId, spanId, opts = {}) {
29
+ if (!/^[0-9a-f]{32}$/.test(traceId) || !/^[0-9a-f]{16}$/.test(spanId))
30
+ throw new Error(`traceparent needs a 32-hex trace id and a 16-hex span id, got ${traceId}/${spanId}`);
31
+ return `00-${traceId}-${spanId}-${opts.sampled === false ? '00' : '01'}`;
32
+ }
33
+ /** `tracestate` with this substrate's member set (`ap=<value>`) at the front — W3C: a vendor updating its
34
+ * member moves it to the left, the list is capped at 32 members, and foreign members are kept verbatim. */
35
+ export function withTracestateMember(existing, key, value) {
36
+ if (!/^[a-z][a-z0-9_\-*/]{0,255}$/.test(key))
37
+ throw new Error(`tracestate key must be a W3C key, got ${JSON.stringify(key)}`);
38
+ const v = value.replace(/[^\x20-\x7e]/g, '').replace(/[,=]/g, '_').trim();
39
+ const others = (existing ?? '').split(',').map((s) => s.trim()).filter((s) => s && !s.startsWith(`${key}=`));
40
+ return [`${key}=${v}`, ...others].slice(0, 32).join(',');
41
+ }
42
+ /** This substrate's member of a `tracestate`, when present. */
43
+ export function tracestateMember(state, key) {
44
+ for (const m of (state ?? '').split(',')) {
45
+ const t = m.trim();
46
+ if (t.startsWith(`${key}=`))
47
+ return t.slice(key.length + 1);
48
+ }
49
+ return null;
50
+ }
51
+ /** What an inbound request carried, as the run records it — or `null` when it carried nothing usable. */
52
+ export function traceContextOf(headers) {
53
+ const parent = parseTraceparent(headers.get('traceparent'));
54
+ if (!parent)
55
+ return null;
56
+ const state = (headers.get('tracestate') ?? '').trim();
57
+ return { ...parent, ...(state ? { tracestate: state.slice(0, 512) } : {}) };
58
+ }
59
+ //# sourceMappingURL=trace-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-context.js","sourceRoot":"","sources":["../src/trace-context.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -11,6 +11,7 @@ export interface Intent {
11
11
  context?: Record<string, unknown>;
12
12
  }
13
13
  /** A capability the agent MAY compose. The planner picks from these; the loop refuses any other tool id. */
14
+ export type OutcomeClass = 'lookup' | 'submission' | 'authoritative';
14
15
  export interface ToolSpec {
15
16
  /** Stable tool id (matches the invoker's dispatch key, e.g. an MCP tool name). */
16
17
  id: string;
@@ -18,6 +19,114 @@ export interface ToolSpec {
18
19
  description: string;
19
20
  /** Optional JSON-Schema for the tool's args (the LLM planner uses it as the tool-use input schema). */
20
21
  inputSchema?: Record<string, unknown>;
22
+ /**
23
+ * Spec 350 §3.1 — the capability this tool EXERCISES (ADR-0051 id). Declared on the TOOL, never on the
24
+ * plan: a planner that emits a step for this tool cannot describe its way out of needing authority.
25
+ * Absent ⇒ informational, no mandate needed. `resourceArg` names the arg that holds the resource the
26
+ * step acts on (the org, the token) so the verifier can bound it.
27
+ *
28
+ * `authorityArg` names the arg holding the party whose AUTHORITY the step needs — which is not always
29
+ * the resource. Chartering a team acts on the workspace and needs the workspace's authority (the same
30
+ * address); paying acts on a TOKEN and needs the PAYER's authority (a different one). Absent ⇒ the
31
+ * resource, then whoever was addressed. Getting this wrong asks a person to grant authority as an
32
+ * ERC-20 contract, which nothing can sign.
33
+ */
34
+ capability?: {
35
+ id: string;
36
+ action: string;
37
+ resourceArg?: string;
38
+ authorityArg?: string;
39
+ };
40
+ /**
41
+ * Spec 366 — the argument naming the agent this act is ABOUT and is ANSWERED BY. When it resolves to an
42
+ * agent other than the one addressed, the step is not run here: it is routed to that agent's own
43
+ * harness, which verifies the asker's standing itself and answers under its own playbook. Declared on
44
+ * the tool (from the contract), never inferred from the sentence. Absent ⇒ the addressee answers.
45
+ */
46
+ subject?: string;
47
+ /**
48
+ * Spec 367 W1 — the IMPERATIVES that name this act ("send", "pay", "create a team"). A sentence that opens
49
+ * with one is an instruction, and plan admission refuses a plan for it that contains no act. Declared
50
+ * beside the capability (from the contract's utterances when compiled). A READ may claim a verb too ("ask
51
+ * <agent> …", spec 379): an instruction opening with a verb a lookup in the plan claims is discharged by
52
+ * that lookup — the verb names a consultation, not an act.
53
+ */
54
+ verbs?: string[];
55
+ /** Spec 371 — the FACT WORDS a question uses to name what this read answers ("balance", "how much").
56
+ * A read's twin of an act's `verbs`: question admission requires the plan to include the tool that
57
+ * answers a fact the sentence names. Behaviour, never authority. */
58
+ answers?: string[];
59
+ /** Spec 371 — the domain author's sentence for this read's result (`{{field}}`; once per `items[]`
60
+ * element when the result carries a list). Rendered instead of composed: the person's unit. */
61
+ answer?: string;
62
+ /**
63
+ * Spec 367 §6 — WHAT A SUCCESSFUL STEP OF THIS TOOL ESTABLISHES about the requested outcome:
64
+ * lookup who or what was meant (a roster, a relationship) — never that anything was done
65
+ * submission acceptance or pending execution (an invitation recorded, a request asked) — not the outcome
66
+ * authoritative the outcome itself, with its evidence (a mined transfer, a written record)
67
+ * Admission asks whether some step's class CAN discharge an instruction; fulfillment asks what the
68
+ * evidence DID establish, and the reply may claim only that. Absent ⇒ lookup for a tool with no
69
+ * capability, authoritative for one with. Declared on the contract; never lowered by a plan.
70
+ */
71
+ establishes?: OutcomeClass;
72
+ /** The tool's risk tier (`tool-policy.RiskTier`). Meaningful only with `capability`; defaults to `low`. */
73
+ risk?: import('@agenticprimitives/tool-policy').RiskTier;
74
+ /**
75
+ * SELF-ACTING: this capability touches ONLY the run's own principal's records, so the SESSION that
76
+ * proved who is asking is the authority and no mandate is verified.
77
+ *
78
+ * WHY THE MODEL NEEDED THIS. Until now every capability step required a presented mandate, so the
79
+ * only way to express "change your own email" was to demand a signature the Home's own form does not
80
+ * ask for — teaching people that talking to their agent is the expensive way to do the same thing.
81
+ * The alternative was worse: declaring such a tool informational, which would have hidden a WRITE
82
+ * from the authority plane entirely.
83
+ *
84
+ * WHAT IT IS NOT. It is not "low risk", and it is not a way to skip a gate. It is a claim about the
85
+ * TARGET — that there is no second party whose authority could be needed, because the actor, the
86
+ * owner and the beneficiary are the same principal. An invoker for such a tool MUST take its subject
87
+ * from the run's principal and never from an argument; the moment it can be pointed at someone else's
88
+ * record, this flag is a lie and the capability needs a mandate like everything else.
89
+ *
90
+ * It is declared on the BUILT-IN tool and never merged from a contract (a contract may describe an
91
+ * act, never weaken its gate — spec 361 §3), and the receipt records `self` as the basis so a reader
92
+ * can tell an act authorized by a session from one authorized by a signature.
93
+ */
94
+ selfAuthorized?: true;
95
+ /**
96
+ * Spec 363 W5 — the DECISION POINTS this capability consults, by id.
97
+ *
98
+ * Behaviour, never authority: consulting one lets the substrate answer a question ("which of your
99
+ * accounts pays?") from a modelled fact instead of interrupting, and every answer cites the rule that
100
+ * gave it. A capability that names none asks, which is the default and the safe one.
101
+ *
102
+ * The loop does not read this — normalisation does, where decisions are made. It rides the ToolSpec
103
+ * because that is where a CONTRACT's declaration lands (`mergeContractTool`), and a decision a domain
104
+ * author did not ask for should not happen because some app-side branch remembered a capability id.
105
+ */
106
+ decisions?: readonly string[];
107
+ /** Compensation for a run that fails AFTER this tool executed: the tool to invoke, with args derived
108
+ * from the original args (+ the result under `$result`). Declared, never improvised. */
109
+ compensation?: {
110
+ toolId: string;
111
+ args: Record<string, unknown>;
112
+ };
113
+ /** An irreversible action: imposes `fresh-authorization` whatever the tier. */
114
+ irreversible?: boolean;
115
+ /** Spec 358 W4 — this tool's result ENUMERATES the objects of a domain relation (an ontology IRI,
116
+ * e.g. aporg:memberAgent). Declaring it is what makes the result fan-out-able: a `forEach` over a
117
+ * result whose tool declares nothing is refused, because an array being array-shaped says nothing
118
+ * about whether iterating it is meaningful — a search page is not a payee list. */
119
+ enumerates?: {
120
+ relation: string;
121
+ };
122
+ /** Spec 361 — the interaction binding a playbook contract declared (editor/review/result names + a
123
+ * navigation route key). DATA carried for surfaces to resolve; the loop never reads it. */
124
+ interaction?: {
125
+ editor?: string;
126
+ review?: string;
127
+ result?: string;
128
+ navigationTarget?: string;
129
+ };
21
130
  }
22
131
  /** One step of a plan: invoke `toolId` with `args`; optionally bind the result under `ref` for later steps. */
23
132
  export interface PlanStep {
@@ -25,6 +134,37 @@ export interface PlanStep {
25
134
  args: Record<string, unknown>;
26
135
  /** Name to store this step's result under; later steps reference it via `{ $ref: name }` in their args. */
27
136
  ref?: string;
137
+ /** Spec 350 — optional stable id (defaults to `s<index>`); the receipt and the idempotency key carry it. */
138
+ id?: string;
139
+ /** Spec 376 — the AGENT that runs this step, when it is not this harness: a hand-off. The step runs
140
+ * there under a CHILD mandate attenuated from the one this run presented; this run records the
141
+ * hand-off and resumes on what comes back. Absent ⇒ this harness. */
142
+ executor?: string;
143
+ /** Caller-supplied idempotency key for a retry of THIS step; defaults to `${runRef}:${stepId}`. */
144
+ idempotencyKey?: string;
145
+ /** Spec 358 W4 — fan this step out over an ARRAY a prior step produced (`ref` is a `name.path` into
146
+ * that step's result). Each element becomes its OWN step — its own receipt, its own idempotency key,
147
+ * and its own pass through the verifier: a mandate per item, never one verdict stretched over N.
148
+ * `$item` / `{ $item: 'path' }` placeholders in `args` are substituted per element. Fail-closed: the
149
+ * producing step's tool must declare `enumerates`, and the relation must be bound fan-out-able. */
150
+ forEach?: {
151
+ ref: string;
152
+ };
153
+ /** Spec 370 P3 — run only AFTER these steps (by id) have completed. Steps with no edge between them and
154
+ * no `$ref` into each other's results are independent; the loop runs independent INFORMATIONAL steps
155
+ * concurrently, each through its own gates. A step that exercises a capability never runs beside
156
+ * another: two userOps from one account race on its nonce, and one verdict is one step's. */
157
+ after?: string[];
158
+ /** Spec 370 P3 — a DECLARED branch: run this step only when a prior result satisfies the condition.
159
+ * `ref` is a `name.path` into a prior step's result; `exists` = present and, for an array, non-empty;
160
+ * `equals` = deep-equal to the value. A step whose condition fails is SKIPPED, with a receipt saying so —
161
+ * the plan does not need a second planner call to take a branch. Undecidable at admission (a ref no
162
+ * earlier step produces) is refused, never guessed. */
163
+ when?: {
164
+ ref: string;
165
+ exists?: boolean;
166
+ equals?: unknown;
167
+ };
28
168
  }
29
169
  /** The ordered tool composition the planner produced for an intent. */
30
170
  export interface Plan {
@@ -38,8 +178,21 @@ export interface StepObservation {
38
178
  ok: boolean;
39
179
  result?: unknown;
40
180
  error?: string;
181
+ /** Spec 370 P1 — the step's stable reference (`id` or `s<index>`), so a checkpoint can name what ran. */
182
+ stepRef?: string;
183
+ /** Spec 370 P1 — this observation was REPLAYED from a checkpoint on a resume: nothing was invoked and
184
+ * nothing re-verified, because there was no new attempt (spec 362 §0.1, gate 4). */
185
+ replayed?: boolean;
186
+ /** Spec 370 P3 — the step's `when` did not hold: nothing ran, and the receipt says so. */
187
+ skipped?: boolean;
41
188
  }
42
- export type RunOutcome = 'completed' | 'failed';
189
+ /** `denied`: an authority decision refused a step (never re-planned around — a denial is not a tool
190
+ * failure). `suspended`: an approval is pending OR a tool asked the person for an input (`prompt`);
191
+ * resume later, through the verifier again. `authority-required`: the plan needs a mandate the caller did
192
+ * not present — nothing was verified, nothing ran; the caller may come back WITH one (opt-in via
193
+ * `onMissingMandate: 'report'`; the default is still to throw). It is 401, never 403: no authority was
194
+ * judged, so this is not a denial and must never be reported as one. */
195
+ export type RunOutcome = 'completed' | 'failed' | 'denied' | 'suspended' | 'authority-required';
43
196
  /** The result of running an intent to completion (or fail-closed). */
44
197
  export interface RunResult {
45
198
  outcome: RunOutcome;
@@ -49,11 +202,35 @@ export interface RunResult {
49
202
  steps: StepObservation[];
50
203
  /** The last successful step's result — the composed answer returned to the caller. */
51
204
  result?: unknown;
52
- /** Set when `outcome === 'failed'`. */
205
+ /** Set when `outcome === 'failed'` or `'denied'`. */
53
206
  error?: string;
207
+ /** Spec 350 — the run's reference (the A2A taskId when run inside `A2aTaskDO`). */
208
+ runRef: string;
209
+ /** Every step's receipt, informational ones included. The sink (if any) has the same list. */
210
+ receipts: import('./authority.js').StepReceipt[];
211
+ /** Set when `outcome === 'suspended'`: what to hand back to resume. */
212
+ resumeToken?: string;
213
+ /** Set when `outcome === 'suspended'` because a tool asked the person for something (spec 350 §3.4).
214
+ * The surface renders it; the answers come back as `RunIntentOpts.supplied` on the resume. */
215
+ prompt?: import('./input.js').InputRequestV1;
216
+ /** Set when `outcome === 'authority-required'`: the step the plan reached that needs a mandate. The
217
+ * caller turns it into a requirement in ITS vocabulary (`harness.mandateRequirementForStep`) — this
218
+ * layer names the step, never the grant. */
219
+ required?: {
220
+ stepRef: string;
221
+ toolId: string;
222
+ capability: {
223
+ id: string;
224
+ action: string;
225
+ resource?: string;
226
+ authority?: string;
227
+ };
228
+ risk: import('./authority.js').ResolvedStep['risk'];
229
+ args: Record<string, unknown>;
230
+ };
54
231
  }
55
232
  /** Stable error codes the loop / planners raise (fail-closed; never a silent empty success). */
56
- export type OrchestrationErrorCode = 'no_plan' | 'unknown_tool' | 'empty_plan' | 'max_steps' | 'planner_failed';
233
+ export type OrchestrationErrorCode = 'no_plan' | 'unknown_tool' | 'empty_plan' | 'max_steps' | 'planner_failed' | 'no_authority_port' | 'no_approval_port' | 'no_mandate_presented' | 'keyring_needs_selector' | 'fan_out_unbound' | 'fan_out_not_array' | 'fan_out_refused' | 'fan_out_over_limit';
57
234
  export declare class OrchestrationError extends Error {
58
235
  readonly code: OrchestrationErrorCode;
59
236
  constructor(code: OrchestrationErrorCode, message: string);
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,YAAY,EAAG,kCAA2C,CAAC;AACxE,eAAO,MAAM,cAAc,EAAG,SAAkB,CAAC;AACjD,eAAO,MAAM,QAAQ,EAAG,gCAAyC,CAAC;AAElE,sGAAsG;AACtG,MAAM,WAAW,MAAM;IACrB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,wGAAwG;IACxG,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,4GAA4G;AAC5G,MAAM,WAAW,QAAQ;IACvB,kFAAkF;IAClF,EAAE,EAAE,MAAM,CAAC;IACX,uGAAuG;IACvG,WAAW,EAAE,MAAM,CAAC;IACpB,uGAAuG;IACvG,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED,+GAA+G;AAC/G,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,2GAA2G;IAC3G,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,uEAAuE;AACvE,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEhD,sEAAsE;AACtE,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,UAAU,CAAC;IACpB,mEAAmE;IACnE,IAAI,EAAE,IAAI,CAAC;IACX,yEAAyE;IACzE,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,sFAAsF;IACtF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,gGAAgG;AAChG,MAAM,MAAM,sBAAsB,GAC9B,SAAS,GACT,cAAc,GACd,YAAY,GACZ,WAAW,GACX,gBAAgB,CAAC;AAErB,qBAAa,kBAAmB,SAAQ,KAAK;aAEzB,IAAI,EAAE,sBAAsB;gBAA5B,IAAI,EAAE,sBAAsB,EAC5C,OAAO,EAAE,MAAM;CAKlB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,EAAE;AACF,+FAA+F;AAC/F,2GAA2G;AAC3G,6GAA6G;AAC7G,6GAA6G;AAC7G,+GAA+G;AAE/G,MAAM,CAAC,MAAM,YAAY,GAAG,kCAA2C,CAAC;AACxE,MAAM,CAAC,MAAM,cAAc,GAAG,SAAkB,CAAC;AACjD,MAAM,CAAC,MAAM,QAAQ,GAAG,gCAAyC,CAAC;AAoElE,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAEzB;IADlB,YACkB,IAA4B,EAC5C,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAwB;QAI5C,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,EAAE;AACF,+FAA+F;AAC/F,2GAA2G;AAC3G,6GAA6G;AAC7G,6GAA6G;AAC7G,+GAA+G;AAE/G,MAAM,CAAC,MAAM,YAAY,GAAG,kCAA2C,CAAC;AACxE,MAAM,CAAC,MAAM,cAAc,GAAG,SAAkB,CAAC;AACjD,MAAM,CAAC,MAAM,QAAQ,GAAG,gCAAyC,CAAC;AAoOlE,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAEzB;IADlB,YACkB,IAA4B,EAC5C,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAwB;QAI5C,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticprimitives/orchestration",
3
- "version": "0.0.0-alpha.1",
3
+ "version": "0.0.0-alpha.2",
4
4
  "description": "The Ring-0 agentic orchestration core (ADR-0044): the intent→plan→execute→observe loop, the Planner + ToolInvoker ports, and a deterministic rule-based planner. A first-party app expresses a goal; the loop plans which tools compose to satisfy it and runs them through an injected invoker. Pure leaf — no transport, no LLM SDK, no chain; the concrete LLM binding lives behind the Planner port in orchestration-anthropic.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -41,6 +41,9 @@
41
41
  "intent",
42
42
  "agentic-loop"
43
43
  ],
44
+ "dependencies": {
45
+ "@agenticprimitives/tool-policy": "1.0.0-alpha.23"
46
+ },
44
47
  "scripts": {
45
48
  "build": "tsc -p tsconfig.build.json",
46
49
  "typecheck": "tsc -p tsconfig.json --noEmit",