@crawlcheck/sdk 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -66,6 +66,23 @@ suite.ok; // every fixture gave exactly its expecte
66
66
 
67
67
  `npm test` in the installed package runs the conformance suite and live checks against crawlcheck.io.
68
68
 
69
+ ## Catch a split view
70
+
71
+ Every Resolve answer names its leaf in CrawlCheck's transparency log and, once merged, carries the signed tree head of its batch. The client keeps every head it sees in `client.log` (plain JSON) and checks each new one against its neighbours: two heads for one batch, or a head that does not chain to the one before, is a **fork**, kept with both signed heads as proof. `guard()` refuses to proceed while the client holds one.
72
+
73
+ ```js
74
+ import fs from "node:fs";
75
+ import { CrawlCheck, newLogStore } from "@crawlcheck/sdk";
76
+ const store = fs.existsSync("cc-log.json") ? JSON.parse(fs.readFileSync("cc-log.json", "utf8")) : newLogStore();
77
+ const client = new CrawlCheck({ logStore: store });
78
+ await client.resolve("example.com"); // the answer's head is checked against the store
79
+ const r = await client.logCheck(); // current head + GitHub's witness co-signature + the chain down to your heads
80
+ console.log(r.summary); // "consistent: ..." or "SPLIT VIEW: ..."
81
+ fs.writeFileSync("cc-log.json", JSON.stringify(client.log));
82
+ ```
83
+
84
+ `logCheck` verifies the outside witness: a GitHub Actions run re-checks the chain and co-signs the newest head with a GitHub OIDC token (RS256, GitHub's key) whose audience is the head's digest. A head the witness's chain does not contain shows up as a fork. Heads newer than the witnessed one are listed as `unwitnessed`. Clients can also swap heads directly: `logHeads(store)` on one side, `client.logGossip(heads)` on the other. Forks are reported to `/api/v1/log/gossip` (pass `{ report: false }` to skip).
85
+
69
86
  ## Errors
70
87
 
71
88
  A refused request throws `CrawlCheckError` with `status`, `body` and `locked` (true for "this needs a licence for the domain").