@atcn/verify-cli 1.4.1 → 1.5.1

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 (3) hide show
  1. package/README.md +21 -13
  2. package/dist/cli.js +29 -6
  3. package/package.json +5 -5
package/README.md CHANGED
@@ -1,31 +1,39 @@
1
1
  # @atcn/verify-cli
2
2
 
3
- `atcn-verify` checks ATCN documents offline, without contacting anyone. It accepts these documents:
3
+ `atcn-verify` checks a signed [ATCN](https://github.com/fadnisnikhil/atcn) document on your machine, without contacting anyone. Use it when someone sends you a task closure, a receipt or a closure package and you want to know whether it's genuine and whether its numbers add up.
4
4
 
5
- - subledger task closures;
6
- - provider receipts;
7
- - obligation closure packages.
5
+ It checks the signatures, recomputes the totals and exceptions from the records inside, and prints each check with its result. It accepts:
6
+
7
+ - task closures (the signed summary of an agent job and its costs);
8
+ - provider receipts (what one provider sees of a task);
9
+ - obligation closure packages (the signed record of paid work and how it was accepted);
10
+ - clearing verdicts (an obligation's decision, for a payment rail to read).
8
11
 
9
12
  ```bash
10
- npx @atcn/verify-cli task-closure.json --keys keys.json --obligation-package obligation.json
13
+ npx @atcn/verify-cli task-closure.json --keys keys.json
11
14
  ```
12
15
 
13
- Options:
16
+ To try it, run `npx @atcn/local-runner demo`: it writes a closure, its keys and its closure packages, and prints the exact `atcn-verify` command to check them.
17
+
18
+ ## Options
14
19
 
15
- - **`--keys`:** a JSON array of public key records, or `{"items": [...]}`.
16
- - **`--previous`:** checks the chain link to the previous revision.
20
+ - **`--keys`:** the signer's public keys, as a JSON array of key records or `{"items": [...]}`.
21
+ - **`--obligation-package`:** cross-checks a closure's linked obligations against their closure packages. You can repeat it. For a clearing verdict, pass the one package it was read from.
22
+ - **`--previous`:** checks the link to the previous version of a closure or revision of a receipt.
17
23
  - **`--operator-keys` and `--require-operator-signature`:** check operator countersignatures.
18
- - **`--obligation-package`:** cross-checks a closure's linked obligations against their closure packages. You can repeat it.
19
- - **`--at <ISO-8601 time>`:** checks a provider receipt's `expires_at` against that time instead of now, for example the time you received it.
24
+ - **`--trace <trace.json>`:** supplies an agent trace file. You can repeat it. For a closure package, each trace is rechecked against the declared runs and every `usage_cost` result is recomputed from the terms' pricing. For a receipt or closure, each recorded usage summary is recomputed from its trace. Usage whose trace you did not supply is reported as `NOT INSPECTED`, which is neither a pass nor a failure.
25
+ - **`--at <ISO-8601 time>`:** checks a receipt's `expires_at` against that time instead of now, for example the time you received it.
20
26
  - **`--json`:** prints the report as JSON.
21
27
 
22
- Exit codes:
28
+ ## Exit codes
23
29
 
24
30
  - `0`: valid.
25
31
  - `1`: invalid.
26
32
  - `2`: usage or input error.
27
33
  - `3`: unsupported schema version, so upgrade `atcn-verify`.
28
34
 
29
- Supported subledger schema versions are `1.2` and `1.3`; see [COMPATIBILITY.md](../schema/COMPATIBILITY.md).
35
+ Supported subledger schema versions are `1.2` to `1.5`; see [compatibility](https://github.com/fadnisnikhil/atcn/blob/main/packages/schema/COMPATIBILITY.md).
36
+
37
+ A valid signature shows who stated something and that it hasn't changed since. It doesn't prove the work or payment really happened; each claim carries a label saying who stands behind it.
30
38
 
31
- A valid signature attests to what the signer stated, not to the truth of the underlying work or payment. Part of [ATCN](../../README.md). Apache-2.0.
39
+ Part of [ATCN](https://github.com/fadnisnikhil/atcn). Apache-2.0.
package/dist/cli.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { parseArgs } from "node:util";
3
- import { verifyClosurePackage } from "@atcn/core";
4
- import { PublicKeyRecordSchema } from "@atcn/schema";
3
+ import { verifyClearingVerdict, verifyClosurePackage } from "@atcn/core";
4
+ import { CLEARING_VERDICT_TYPE, PublicKeyRecordSchema } from "@atcn/schema";
5
5
  import { OperatorKeyRecordSchema, SUBLEDGER_VERIFIER_VERSION, SUPPORTED_SUBLEDGER_SCHEMA_VERSIONS, verifySubledgerDocument, } from "@atcn/subledger";
6
6
  const USAGE = `usage: atcn-verify <document.json> --keys <published-keys.json> [--previous <previous-revision.json>]
7
7
  [--operator-keys <operator-keys.json>] [--require-operator-signature]
8
- [--obligation-package <closure-package.json> ...] [--at <ISO-8601 time>] [--json]
8
+ [--obligation-package <closure-package.json> ...] [--trace <trace.json> ...]
9
+ [--at <ISO-8601 time>] [--json]
9
10
 
10
11
  Verifies offline, without contacting the service:
11
12
  - ATCN closure packages (obligations): signatures, key validity, event references,
@@ -15,6 +16,9 @@ Verifies offline, without contacting the service:
15
16
  provider response signatures, and the version chain.
16
17
  - Subledger provider receipts (atcn.subledger.receipt): signature, schema, reversals,
17
18
  totals, field disclosure, the revision chain, and expiry.
19
+ - Clearing verdicts (atcn.clearing.verdict): the service signature and, with --obligation-package, that
20
+ the package verifies and the verdict states the decision in effect in it. ATCN only publishes a verdict;
21
+ an escrow rail decides whether to release.
18
22
  --keys accepts a JSON array of public key records or the /v1/service/keys response ({"items": [...]}).
19
23
  --previous checks the chain link to the prior receipt revision or closure version.
20
24
  --operator-keys checks countersignatures made with the operator's own keys
@@ -22,6 +26,11 @@ Verifies offline, without contacting the service:
22
26
  --obligation-package (repeatable) cross-checks a task closure's obligation-backed delegations against
23
27
  the obligations' closure packages (GET /v1/exports/{obligation_id}): each package must verify, and its
24
28
  journal must produce exactly the costs the closure recorded from the clearing network.
29
+ For a clearing verdict, pass the one package it was read from.
30
+ --trace (repeatable) supplies agent trace files. For a closure package it rechecks agent_trace evidence
31
+ against the declared runs and recomputes usage_cost results from the terms' pricing; for a subledger
32
+ receipt or closure it recomputes each recorded usage summary from its trace. Evidence or usage whose
33
+ trace was not supplied is reported as NOT INSPECTED, which is neither a pass nor a failure.
25
34
  --at checks a provider receipt's expires_at against that time instead of now.
26
35
  Subledger schema versions supported: ${SUPPORTED_SUBLEDGER_SCHEMA_VERSIONS.join(", ")} (atcn-verify ${SUBLEDGER_VERIFIER_VERSION}).
27
36
  Exit code 0 = valid, 1 = invalid, 2 = usage or input error, 3 = unsupported schema version (upgrade atcn-verify).`;
@@ -56,6 +65,7 @@ function main() {
56
65
  "operator-keys": { type: "string" },
57
66
  "require-operator-signature": { type: "boolean" },
58
67
  "obligation-package": { type: "string", multiple: true },
68
+ trace: { type: "string", multiple: true },
59
69
  at: { type: "string" },
60
70
  json: { type: "boolean" },
61
71
  help: { type: "boolean" },
@@ -80,7 +90,18 @@ function main() {
80
90
  try {
81
91
  const doc = readJson(parsed.positionals[0]);
82
92
  const trustedKeys = loadKeys(parsed.values.keys);
83
- if (isSubledgerDocument(doc)) {
93
+ const traces = parsed.values.trace?.map((path) => new Uint8Array(readFileSync(path)));
94
+ const documentType = doc?.payload?.document_type;
95
+ if (documentType === CLEARING_VERDICT_TYPE) {
96
+ const packages = parsed.values["obligation-package"]?.map(readJson) ?? [];
97
+ if (packages.length > 1) {
98
+ console.error(`a clearing verdict is checked against one --obligation-package, got ${packages.length}\n\n${USAGE}`);
99
+ return 2;
100
+ }
101
+ report = verifyClearingVerdict(doc, { trustedKeys, closurePackage: packages[0] });
102
+ label = "clearing verdict";
103
+ }
104
+ else if (isSubledgerDocument(doc)) {
84
105
  const previous = parsed.values.previous ? readJson(parsed.values.previous) : undefined;
85
106
  const operatorKeysPath = parsed.values["operator-keys"];
86
107
  const operatorKeys = operatorKeysPath ? loadOperatorKeys(operatorKeysPath) : undefined;
@@ -91,13 +112,14 @@ function main() {
91
112
  operatorKeys,
92
113
  requireOperatorSignature: parsed.values["require-operator-signature"],
93
114
  obligationPackages,
115
+ traces,
94
116
  at: at === undefined ? undefined : new Date(at).toISOString(),
95
117
  });
96
118
  report = result;
97
119
  label = result.document_type === "atcn.subledger.receipt" ? "provider receipt" : "task closure";
98
120
  }
99
121
  else {
100
- report = verifyClosurePackage(doc, { trustedKeys });
122
+ report = verifyClosurePackage(doc, { trustedKeys, traces });
101
123
  label = "closure package";
102
124
  }
103
125
  }
@@ -113,7 +135,8 @@ function main() {
113
135
  }
114
136
  else {
115
137
  for (const check of report.checks) {
116
- console.log(`${check.ok ? "PASS" : "FAIL"} ${check.name}`);
138
+ const status = !check.ok ? "FAIL" : check.state === "not_inspected" ? "NOT INSPECTED" : "PASS";
139
+ console.log(`${status} ${check.name}`);
117
140
  for (const detail of check.details)
118
141
  console.log(` ${detail}`);
119
142
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@atcn/verify-cli",
3
- "version": "1.4.1",
4
- "description": "Offline verifier for ATCN closure packages, subledger task closures, and provider receipts: atcn-verify <document.json> --keys <keys.json>",
3
+ "version": "1.5.1",
4
+ "description": "atcn-verify: check a signed ATCN closure, receipt, closure package or clearing verdict offline, without contacting anyone",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -27,8 +27,8 @@
27
27
  "build": "tsc -p tsconfig.build.json"
28
28
  },
29
29
  "dependencies": {
30
- "@atcn/core": "1.4.1",
31
- "@atcn/schema": "1.4.1",
32
- "@atcn/subledger": "1.4.1"
30
+ "@atcn/core": "1.5.1",
31
+ "@atcn/schema": "1.5.1",
32
+ "@atcn/subledger": "1.5.1"
33
33
  }
34
34
  }