@decidio/sdk 0.6.2 → 0.6.4
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/CHANGELOG.md +36 -3
- package/README.md +6 -5
- package/dist/cli.js +16 -5
- package/dist/demo-gate.js +9 -0
- package/dist/guard.js +2 -2
- package/dist/index.d.ts +6 -1
- package/dist/index.js +21 -3
- package/openapi.yaml +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,41 @@
|
|
|
1
1
|
# Changelog — @decidio/sdk
|
|
2
2
|
|
|
3
|
-
Release notes for the client SDK. The Python package `decidio` ships the same
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Release notes for the client SDK. The Python package `decidio` ships under the same version; the core -
|
|
4
|
+
the gate, signing, receipts and the verifier - is conformance-locked between the two, while the command line's
|
|
5
|
+
first-run surfaces (the fork, `--demo`, the code sign-in) are TypeScript-first and named as such in the parity
|
|
6
|
+
allowlist. Each entry names what changed, what a reader must do on upgrade, and what proved it.
|
|
7
|
+
|
|
8
|
+
## 0.6.4 — the request closes when the agent gives up
|
|
9
|
+
|
|
10
|
+
- **The README links the agent skill file** published on the site (https://decidioai.com/skills/decidio-guard.md, one page for both languages) and the site's llms.txt. The file is served by the site, not shipped in the package; an in-package copy is a one-line publish-boundary decision for this release if wanted.
|
|
11
|
+
- **A blocking wait that hits `pollTimeoutMs` now WITHDRAWS its request** (`POST /agent/withdraw/<id>`
|
|
12
|
+
`{reason:"timeout"}`) before throwing `DecidioTimeoutError`. Before, the decision stayed open in Decidio
|
|
13
|
+
forever after this process had stopped waiting, so the queue carried a request nobody could act on and a
|
|
14
|
+
later tap sealed "approved" for an action that never ran. Now it leaves the queue as *withdrawn* and a
|
|
15
|
+
later approval is a no-op (`alreadyResolved`). `DecidioTimeoutError.withdrawn` says whether the call
|
|
16
|
+
landed; a failed withdraw changes nothing else (nothing executes either way). Withdrawing needs the
|
|
17
|
+
bound agent token and the signing key `init` writes — the gate refuses anyone else with 404, so an
|
|
18
|
+
unbound or unsigned caller simply sees `withdrawn:false`. If a human decided in the last poll window,
|
|
19
|
+
the gate answers 409 with that decision and the SDK honours it: the action runs as approved (and
|
|
20
|
+
confirms), or `DecidioRejectedError` is thrown — never a timeout that hides a decision. The durable
|
|
21
|
+
path is untouched — its parked action is exactly what a later approval resumes. The CLI tour and the
|
|
22
|
+
`--demo` stand-in say which of these happened. Nothing to do on upgrade.
|
|
23
|
+
Proved by: `smoke.ts` (the timeout vector now asserts exactly one withdraw after the last poll, and a
|
|
24
|
+
failing withdraw still ends in the same error with `withdrawn:false`; a 409 carrying `approved` runs and
|
|
25
|
+
confirms, `rejected` rejects; a wait that ends in a decision never withdraws) and, server-side,
|
|
26
|
+
`integration.smoke.ts` #W2 (a lab-posture boot with real bound tokens: another agent's token, an
|
|
27
|
+
anonymous caller and an unsigned receipt all get 404; the owner's later approve is `alreadyResolved`
|
|
28
|
+
with no sealed record; a second withdraw → 409) and #W (IdP posture: anonymous and IdP users → 404).
|
|
29
|
+
|
|
30
|
+
## 0.6.3 — the two 0.6.2 reviews' small items
|
|
31
|
+
|
|
32
|
+
- **`DECIDIO_DEBUG_INPUT=1` no longer prints what you type** (review: Medium). The 0.6.2 trace hex-dumped every stdin
|
|
33
|
+
byte - passwords, codes and links, muted prompt or not. It now prints the SHAPE only: control bytes named (`\r`, `\n`,
|
|
34
|
+
ESC), every printable byte as `x`. A newline problem is visible in the shape alone.
|
|
35
|
+
- Four strings still described the sign-in as an emailed link to paste; they say the code now. The CHANGELOG's "twins"
|
|
36
|
+
line overstated CLI parity and now says exactly what is locked and what is TypeScript-first. Two README headings
|
|
37
|
+
still said "0.4". The offline local demo no longer prints "the terminal follows the web app or your phone" when it
|
|
38
|
+
has just said there are no such doors. `receipt --json` help says it prints a summary; the credential is the file.
|
|
6
39
|
|
|
7
40
|
## 0.6.2 — the fork after its first real run
|
|
8
41
|
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ you approve right there (or from your Decidio app), executes on approval, then d
|
|
|
23
23
|
sealed Authority Receipt and verifies it offline in front of you, pinned to your workspace's
|
|
24
24
|
issuer. It mints a **7-day** tour token (`init` mints 90-day tokens — different jobs, different
|
|
25
25
|
lifetimes) and ends by offering to clean itself up (`quickstart cleanup` works later too).
|
|
26
|
-
Sign in once — `npx @decidio/sdk login`, or when the tour asks: the CLI emails you
|
|
26
|
+
Sign in once — `npx @decidio/sdk login`, or when the tour asks: the CLI emails you an 8-character code, you type it, and
|
|
27
27
|
the sign-in is kept in your profile (owner-only) for 30 days, or until this terminal closes, `logout`, or
|
|
28
28
|
`quickstart cleanup`. At the human step the tour offers three doors: answer here, open the decision in
|
|
29
29
|
the web app (a one-time link, signed in for you), or scan the QR with your phone — whichever answers
|
|
@@ -660,7 +660,7 @@ that fits every other confirm error.
|
|
|
660
660
|
- **The token recovery journal** (`.decidio-token-journal`, owner-only, gitignored; ids and timestamps, never a token value; append-only by the CLI's behaviour — not OS-enforced or tamper-evident). One JSON row per event: `minted` (a token was issued, written BEFORE its credential file), `retired how=persisted` (the credential file now holds it - the token is live and that file is its handle; not revoked), `retired how=revoked` (revoked server-side), `probe` (a durability check). `doctor` names rows still outstanding; `quickstart cleanup` sweeps them.
|
|
661
661
|
- `quickstart --demo` — the same tour with no account: an in-process stand-in of the API on 127.0.0.1 (shipped in this package) answers every door, a key generated for the run signs a real receipt (its content says `local-demo`; pinning it to the hosted issuer fails), and the web/phone door is a hosted demo decision page reached through a one-word relay (no account, no record, ten minutes). Your folder gains exactly one file, the receipt. Offline, the tour is terminal-only and says so.
|
|
662
662
|
- `quickstart --phone web` — the QR at the human step opens the phone web rendering even when the Decidio app is installed (by default it opens the app when there is one).
|
|
663
|
-
- `login [email]` / `logout` — sign in ONCE (the CLI emails you
|
|
663
|
+
- `login [email]` / `logout` — sign in ONCE (the CLI emails you an 8-character code; you type it) and forget that sign-in on this computer (the session token itself stays valid until it expires (up to 30 days) — there is no server-side revocation yet). The session is stored in your user profile, owner-only, bound to the terminal window that created it, for 30 days; `DECIDIO_SESSION_TOKEN` in the environment outranks it (headless shells).
|
|
664
664
|
- `dev [--target URL] [--port N]` — local relay for the resume webhook (operator setups)
|
|
665
665
|
|
|
666
666
|
The CLI's stream contract: **stdout carries results only** (safe to pipe — `--json` output is
|
|
@@ -680,7 +680,7 @@ manager for production.
|
|
|
680
680
|
- `DecidioBlockedError` — policy blocked the action: a named block rule, or the universal backstop that fires when NO active policy governs agents at all (fail closed, no human involved). Distinct from routing-by-default — with an active policy and no matching auto-approve rule, a request is not blocked, it is ROUTED to a person.
|
|
681
681
|
- `DecidioRejectedError` — a human rejected the routed action.
|
|
682
682
|
- `DecidioSuspendedError` — (durable mode) the action was routed and is parked for async approval; the process may exit and resume later. Not a failure.
|
|
683
|
-
- `DecidioTimeoutError` — (blocking mode only) no human decided within `pollTimeoutMs` (default 10 min); the
|
|
683
|
+
- `DecidioTimeoutError` — (blocking mode only) no human decided within `pollTimeoutMs` (default 10 min); nothing executed locally. Since 0.6.4 the SDK's last act before throwing is to tell Decidio it gave up, so the request is closed as **withdrawn** (it leaves the queue; a later approval does nothing) — `error.withdrawn` is `true` when that landed and `false` when the call failed and the request may still be open. Withdrawing needs the bound agent token and the signing key `init` writes (an unbound or unsigned caller cannot withdraw anything — it just gets `withdrawn:false`). If a human decided in the last poll window, the SDK honours that decision instead: the action runs as approved, or `DecidioRejectedError` is thrown. The durable path never withdraws: its parked action is what a later approval resumes.
|
|
684
684
|
- `DecidioRateLimitError` — the workspace's governed-action limit was hit; carries the server's `limit` / `remaining` / `resetAt`.
|
|
685
685
|
- `DecidioHttpError` — the gate refused the call. Carries `status`, `endpoint`, the parsed `body`,
|
|
686
686
|
and **`retryable`** — the field to branch on. A 401/403 is terminal (the agent token expired, or
|
|
@@ -703,7 +703,7 @@ Every error raised after a decision exists carries the `decisionId`, so a suspen
|
|
|
703
703
|
timed-out action is always findable in
|
|
704
704
|
your queue.
|
|
705
705
|
|
|
706
|
-
## What
|
|
706
|
+
## What the SDK does not yet claim
|
|
707
707
|
|
|
708
708
|
The retest that graded 0.3.3 *A- for the core and the shipped stores* and the first-run reviews of
|
|
709
709
|
0.3.3 and 0.3.5 agree on what is left, and none of it is a defect a patch release closes. Stated here so
|
|
@@ -729,7 +729,7 @@ the next reader grades a promise, not a moving target:
|
|
|
729
729
|
|
|
730
730
|
## Compatibility and support
|
|
731
731
|
|
|
732
|
-
- **Stable
|
|
732
|
+
- **Stable surface:** `guard.protect` / `withApproval` and their options; the durable resume
|
|
733
733
|
controller (`createDecidioResume`: `park`, `resolve`, `reconcile`, `reconfirm`, `recover`, the worker
|
|
734
734
|
and both webhook handlers); the `PendingStore` contract and both shipped stores, including the on-disk
|
|
735
735
|
revision-chain layout; `EvidenceOutcome` (a root export) and `ResumeStatus` / `RecoveryState` (on the
|
|
@@ -744,6 +744,7 @@ the next reader grades a promise, not a moving target:
|
|
|
744
744
|
|
|
745
745
|
## Notes
|
|
746
746
|
|
|
747
|
+
- **Coding agents and assistants:** a one-page skill file for adding the gate to an agent — TypeScript and Python on the same page, what the gate does and does not do, the wrapper, first run vs production, the typed errors, how to verify a receipt — is published at https://decidioai.com/skills/decidio-guard.md (the site summary for machines is https://decidioai.com/llms.txt).
|
|
747
748
|
- **Framework-agnostic:** it wraps at the tool-call boundary, so it works with any agent runtime (LangGraph, OpenAI Agents SDK, CrewAI, a raw tool loop) and any action (Salesforce, M365, SAP, a DB write).
|
|
748
749
|
- **Confirmation integrity:** the wrapper runs in your process, so it captures the genuine API response — a materially stronger signal than an agent self-report, but it trusts the host. For high-assurance, Decidio can *independently* read the source back (`independently_reconciled`) where it holds a read connection.
|
|
749
750
|
- **Zero-code alternative:** an agent that speaks MCP (e.g. Claude on the web) can reach the same gate via Decidio's `request_approval` MCP tool with no code at all.
|
package/dist/cli.js
CHANGED
|
@@ -501,7 +501,11 @@ function ask(question, mute = false) {
|
|
|
501
501
|
});
|
|
502
502
|
}
|
|
503
503
|
if (process.env.DECIDIO_DEBUG_INPUT && process.stdin.isTTY) {
|
|
504
|
-
process.stdin.on("data", (c) => {
|
|
504
|
+
process.stdin.on("data", (c) => {
|
|
505
|
+
const b = Buffer.from(c);
|
|
506
|
+
const shape = [...b].map((x) => x === 0x0d ? "\\r" : x === 0x0a ? "\\n" : x === 0x1b ? "ESC" : x < 0x20 ? `^${String.fromCharCode(x + 64)}` : x === 0x7f ? "DEL" : "x").join("");
|
|
507
|
+
process.stderr.write(`[stdin ${b.length}B ${shape}]\n`);
|
|
508
|
+
});
|
|
505
509
|
}
|
|
506
510
|
function terminalId() {
|
|
507
511
|
for (const k of ["WT_SESSION", "VSCODE_IPC_HOOK_CLI", "TERM_SESSION_ID", "ITERM_SESSION_ID", "TMUX_PANE", "KONSOLE_DBUS_SESSION", "GNOME_TERMINAL_SCREEN", "WINDOWID"]) {
|
|
@@ -575,7 +579,7 @@ async function loginFlow(purpose, emailArg) {
|
|
|
575
579
|
log(" ✘ no email given - re-run when you have it.");
|
|
576
580
|
return null;
|
|
577
581
|
}
|
|
578
|
-
const password = await ask(" password (Enter = emailed sign-in
|
|
582
|
+
const password = await ask(" password (Enter = emailed sign-in code): ", true);
|
|
579
583
|
if (password) {
|
|
580
584
|
const r = await api("/demo/login", { method: "POST", body: JSON.stringify({ email, password }) }, "");
|
|
581
585
|
if (r.status >= 200 && r.status < 300 && r.body?.token) {
|
|
@@ -1554,7 +1558,8 @@ async function cmdQuickstartInner(opts = {}) {
|
|
|
1554
1558
|
}
|
|
1555
1559
|
else if (doorLink)
|
|
1556
1560
|
rows.push(`${bold("your phone")} ${dim("the link above works on a phone too (no QR came back this time)")}`);
|
|
1557
|
-
|
|
1561
|
+
if (!DEMO || doorLink)
|
|
1562
|
+
rows.push(dim("whichever answers first wins — the terminal follows the web app or your phone."));
|
|
1558
1563
|
block("③", "Your call", rows, "choice");
|
|
1559
1564
|
let settledState = null;
|
|
1560
1565
|
const settledP = running.then(() => { settledState = "approved"; }, (e) => { settledState = e instanceof DecidioRejectedError ? "rejected" : "other"; });
|
|
@@ -1605,8 +1610,12 @@ async function cmdQuickstartInner(opts = {}) {
|
|
|
1605
1610
|
log(`③ the tour's blocking call gave up after 5 minutes while waiting for your answer, so your answer is NOT posted:`);
|
|
1606
1611
|
if (DEMO)
|
|
1607
1612
|
log(` the demo ends here; nothing is kept (the demo's agent, token and folder go now). Re-run and answer within 5 minutes.`);
|
|
1613
|
+
else if (earlyError.withdrawn) {
|
|
1614
|
+
log(` the request was WITHDRAWN from your queue (it no longer waits for an answer; deciding it there does nothing). Re-run the tour and answer within 5 minutes.`);
|
|
1615
|
+
log(` NOTE: this tour's credentials are still live in ${envFile} - remove them: npx @decidio/sdk quickstart cleanup`);
|
|
1616
|
+
}
|
|
1608
1617
|
else {
|
|
1609
|
-
log(` the request is still ROUTED in your queue - decide it there, or re-run the tour and answer within 5 minutes.`);
|
|
1618
|
+
log(` the request is still ROUTED in your queue (the withdraw call did not land) - decide it there, or re-run the tour and answer within 5 minutes.`);
|
|
1610
1619
|
log(` NOTE: this tour's credentials are still live in ${envFile} - remove them: npx @decidio/sdk quickstart cleanup`);
|
|
1611
1620
|
}
|
|
1612
1621
|
log("");
|
|
@@ -2186,7 +2195,9 @@ APPROVALS AND RECEIPTS
|
|
|
2186
2195
|
If it starts with a dash, put it after -- or use --reason:
|
|
2187
2196
|
... approve <id> -- "-50% cut, per the board"
|
|
2188
2197
|
... approve <id> --reason "-50% cut, per the board"
|
|
2189
|
-
npx @decidio/sdk receipt <id> [--json] download a sealed decision's Authority Receipt
|
|
2198
|
+
npx @decidio/sdk receipt <id> [--json] download a sealed decision's Authority Receipt to a .json FILE; --json prints
|
|
2199
|
+
a summary to stdout (file name, evidence, issuer, the identities you may see) -
|
|
2200
|
+
the credential itself is the file
|
|
2190
2201
|
npx @decidio/sdk verify --issuer <did> <receipt.json> [more...] verify receipts OFFLINE, pinned to your
|
|
2191
2202
|
workspace's issuer (--allow-unpinned: structural check only)
|
|
2192
2203
|
|
package/dist/demo-gate.js
CHANGED
|
@@ -35,6 +35,7 @@ export async function startDemoGate(opts = {}) {
|
|
|
35
35
|
const issuerDid = "did:key:z" + b58(Buffer.concat([Buffer.from([0xed, 0x01]), issuerRaw]));
|
|
36
36
|
const sealedAt = new Date().toISOString();
|
|
37
37
|
let verdict = null;
|
|
38
|
+
let withdrawnDemo = false;
|
|
38
39
|
let decidedBy = "the human at the terminal";
|
|
39
40
|
let lastReason = "quickstart";
|
|
40
41
|
let relayCode = null;
|
|
@@ -121,8 +122,16 @@ export async function startDemoGate(opts = {}) {
|
|
|
121
122
|
lastReason = "decided on the demo page";
|
|
122
123
|
}
|
|
123
124
|
}
|
|
125
|
+
if (withdrawnDemo && !verdict)
|
|
126
|
+
return send({ state: "rejected", reason: "quickstart: withdrawn — the tour stopped waiting" });
|
|
124
127
|
return send(verdict === "reject" ? { state: "rejected", reason: "quickstart: rejected by the approver" } : { state: verdict === "approve" ? "approved" : "pending" });
|
|
125
128
|
}
|
|
129
|
+
if (path.startsWith("/agent/withdraw/")) {
|
|
130
|
+
if (verdict)
|
|
131
|
+
return send({ code: "NOT_OPEN", state: verdict === "approve" ? "approved" : "rejected", decisionId: DECISION_ID }, 409);
|
|
132
|
+
withdrawnDemo = true;
|
|
133
|
+
return send({ ok: true, withdrawn: true, state: "rejected", decisionId: DECISION_ID, reason: "requester_stopped_waiting" });
|
|
134
|
+
}
|
|
126
135
|
if (/^\/api\/decisions\/[^/]+\/(approve|reject)$/.test(path)) {
|
|
127
136
|
const already = verdict !== null;
|
|
128
137
|
verdict = path.endsWith("/reject") ? "reject" : "approve";
|
package/dist/guard.js
CHANGED
|
@@ -65,8 +65,8 @@ export class Guard {
|
|
|
65
65
|
if ((opts?.mode ?? "durable") === "blocking") {
|
|
66
66
|
const ceilingMs = opts?.pollTimeoutMs ?? base.pollTimeoutMs ?? 600_000;
|
|
67
67
|
console.warn(`[decidio] WARNING: blocking wait — this call gives up after ${Math.round(ceilingMs / 1000)}s ` +
|
|
68
|
-
`(pollTimeoutMs), and when it does,
|
|
69
|
-
`a later approval
|
|
68
|
+
`(pollTimeoutMs), and when it does, this process stops waiting and the request is withdrawn in Decidio: ` +
|
|
69
|
+
`a later approval does nothing. Only safe for short, watched approvals — omit mode:"blocking" for ` +
|
|
70
70
|
`durable async resume on real (minutes-to-days) approvals.`);
|
|
71
71
|
return withApproval(fn, describe, base, { ...(opts?.evidence ? { evidence: opts.evidence } : {}), ...(opts?.withContext ? { withContext: true } : {}) });
|
|
72
72
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -82,7 +82,12 @@ export declare class DecidioRejectedError extends Error {
|
|
|
82
82
|
}
|
|
83
83
|
export declare class DecidioTimeoutError extends Error {
|
|
84
84
|
decisionId: string;
|
|
85
|
-
|
|
85
|
+
withdrawn: boolean;
|
|
86
|
+
/** `withdrawn` (0.6.4+): true when the SDK told Decidio it gave up and the request was closed as
|
|
87
|
+
* WITHDRAWN (the queue no longer carries it; a later approval does nothing); false when that
|
|
88
|
+
* best-effort call failed, so the request may still be open in Decidio. Nothing was executed
|
|
89
|
+
* locally either way. */
|
|
90
|
+
constructor(decisionId: string, withdrawn?: boolean);
|
|
86
91
|
}
|
|
87
92
|
/** A transport failure with GUIDANCE instead of a raw fetch stack. Carries the endpoint, the
|
|
88
93
|
* operation, the underlying code, and the safety state a caller cares about most: whether
|
package/dist/index.js
CHANGED
|
@@ -31,9 +31,11 @@ export class DecidioRejectedError extends Error {
|
|
|
31
31
|
}
|
|
32
32
|
export class DecidioTimeoutError extends Error {
|
|
33
33
|
decisionId;
|
|
34
|
-
|
|
34
|
+
withdrawn;
|
|
35
|
+
constructor(decisionId, withdrawn = false) {
|
|
35
36
|
super(`Timed out waiting for human approval (${decisionId})`);
|
|
36
37
|
this.decisionId = decisionId;
|
|
38
|
+
this.withdrawn = withdrawn;
|
|
37
39
|
this.name = "DecidioTimeoutError";
|
|
38
40
|
}
|
|
39
41
|
}
|
|
@@ -192,8 +194,24 @@ export function withApproval(fn, describe, config, opts) {
|
|
|
192
194
|
if (st.state === "blocked")
|
|
193
195
|
throw new DecidioBlockedError(st.reason ?? "blocked", auth.decisionId);
|
|
194
196
|
if (Date.now() > deadline) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
+
let withdrawn = false;
|
|
198
|
+
let lateState = null;
|
|
199
|
+
try {
|
|
200
|
+
await post(config, `/agent/withdraw/${encodeURIComponent(auth.decisionId)}`, { reason: "timeout" });
|
|
201
|
+
withdrawn = true;
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
if (e instanceof DecidioHttpError && e.status === 409 && typeof e.body?.state === "string")
|
|
205
|
+
lateState = e.body.state;
|
|
206
|
+
}
|
|
207
|
+
if (lateState === "approved" || lateState === "auto_approved")
|
|
208
|
+
break;
|
|
209
|
+
if (lateState === "rejected")
|
|
210
|
+
throw new DecidioRejectedError("rejected by approver", auth.decisionId);
|
|
211
|
+
if (lateState === "blocked")
|
|
212
|
+
throw new DecidioBlockedError("blocked", auth.decisionId);
|
|
213
|
+
console.warn(`[decidio] blocking wait hit its ${Math.round(pollTimeout / 1000)}s limit — decision ${auth.decisionId} ${withdrawn ? "was withdrawn in Decidio (the queue no longer shows it; a later approval does nothing)" : "is still open in Decidio (the withdraw call failed), but this process stopped waiting"} and nothing was executed. Re-run to request again, or use durable resume (guard.worker()) so an approval is never lost.`);
|
|
214
|
+
throw new DecidioTimeoutError(auth.decisionId, withdrawn);
|
|
197
215
|
}
|
|
198
216
|
await sleep(pollInterval);
|
|
199
217
|
}
|
package/openapi.yaml
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
openapi: 3.1.0
|
|
6
6
|
info:
|
|
7
7
|
title: Decidio Agent Gate
|
|
8
|
-
version: 0.6.
|
|
8
|
+
version: 0.6.4 # tracks the SDK release - checked by packages/conformance/manifests.mjs
|
|
9
9
|
description: >
|
|
10
10
|
Authorize an AI-agent action (proceed | route | block), confirm the captured outcome, and
|
|
11
11
|
receive the signed resume webhook when a routed action is decided. Every outcome seals a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decidio/sdk",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "One-line approval gate for AI-agent actions. Wrap a risky tool call with guard.protect(); Decidio's policy engine decides proceed | route | block, a human approves routed actions, and every outcome is sealed as a verifiable Authority Receipt.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"prepublishOnly": "npm run typecheck && npm run build && node ../publish-boundary/check.mjs --only @decidio/sdk"
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@decidio/verify": "0.6.
|
|
87
|
+
"@decidio/verify": "0.6.4"
|
|
88
88
|
},
|
|
89
89
|
"author": "OmniTwin Technologies Inc.",
|
|
90
90
|
"bugs": {
|