johnandersen777.bsky.social/atlibs-socialweb-computer-requester
socialweb.computer market requester and policy modules for atlibs, with its web pages and lexicons
0
0
// Test vectors for the policy modules (crates/policy), ported from
// socialweb-computer-kcp atlibs-bidder-fixes-rc159: internal/policyengine/policytest/cases.go
// (TrustCases: the expected Vouch / OnlyMe / Mutuals verdict per world) and records.go (how each
// world's records look). The kcp spec tests (market/bidder|requester/policy_spec_test.go) run every
// case through the scope and full runs of each policy; trustSuite does the same against the wasm,
// serving the world's records to the module's getRecord reads.
import assert from "node:assert/strict";
import { createHash } from "node:crypto";
import { test } from "node:test";
import { load, now } from "../../../atlibs/rust/src/harness.mjs";
const T = "com.publicdomainrelay.temp";
export const NSID = {
vouch: "sh.tangled.graph.vouch",
badge: `${T}.badgeBlueKeys`,
association: `${T}.market.association`,
bid: `${T}.market.bid`,
accept: `${T}.market.accept`,
receipt: `${T}.market.receipt`,
rfp: `${T}.market.rfp`,
vm: `${T}.compute.vm`,
free: `${T}.market.bids.free`,
x402: `${T}.market.bids.x402`,
vmDelete: `${T}.compute.events.vm.delete`,
vmTerminated: `${T}.compute.events.vm.terminated`,
};
export const GET_RECORD = "com.atproto.repo.getRecord";
export const Bidder = "did:plc:policytestbidder";
export const BidderOperator = "did:plc:policytestbidop";
export const Requester = "did:plc:policytestrequester";
export const ReqOperator = "did:plc:policytestreqop";
export const Stranger = "did:plc:policyteststranger";
export const OtherBidder = "did:plc:policytestbidder2";
const createdAt = "2026-10-30T00:00:00Z";
const BIDDER_ASSOCIATE = "bidder_associate";
const REQUESTER_ASSOCIATE = "requester_associate";
const sha256 = (...parts) => createHash("sha256").update(Buffer.concat(parts.map((p) => Buffer.from(p)))).digest();
export const claimRKey = (service, subject) => `${service}-${subject.replaceAll(":", "-")}`;
const receiptRKey = (uri, cid) => `receipt-${sha256(`${uri.trim()}\n${cid.trim()}`).subarray(0, 16).toString("hex")}`;
const releaseRKey = (receipt) => {
const alphabet = "234567abcdefghijklmnopqrstuvwxyz";
return [...sha256("delete", [0], receipt).subarray(0, 13)].map((b) => alphabet[b % alphabet.length]).join("");
};
const terminationRKey = (receipt) => `termination-payload-${sha256(`terminated:${receipt}`).subarray(0, 16).toString("hex")}`;
const plus = (ms) => new Date(Date.parse(now) + ms).toISOString();
export function partiesFor(perspective) {
return perspective === "requester"
? { Self: Requester, SelfOp: ReqOperator, SelfSvc: REQUESTER_ASSOCIATE, CP: Bidder, CPOp: BidderOperator, CPSvc: BIDDER_ASSOCIATE }
: { Self: Bidder, SelfOp: BidderOperator, SelfSvc: BIDDER_ASSOCIATE, CP: Requester, CPOp: ReqOperator, CPSvc: REQUESTER_ASSOCIATE };
}
// policytest.World: records by at-uri, and the getRecord answers a host would give for them.
export class World {
records = new Map();
reads = [];
put(repo, collection, rkey, value) {
const uri = `at://${repo}/${collection}/${rkey}`;
const cid = `bafy${sha256(JSON.stringify(value)).toString("hex").slice(0, 20)}`;
this.records.set(uri, { uri, cid, value });
return { uri, cid };
}
vouch(voucher, subject) {
return this.put(voucher, NSID.vouch, subject, { $type: NSID.vouch, subject, createdAt });
}
denounce(voucher, subject) {
return this.put(voucher, NSID.vouch, subject, { $type: NSID.vouch, subject, kind: "denounce", createdAt });
}
mirror(subject, operator, service) {
return this.put(subject, NSID.badge, "association", { $type: NSID.badge, service, keyId: subject, challenge: operator, createdAt });
}
claim(operator, subject, service) {
return this.put(operator, NSID.badge, claimRKey(service, subject), { $type: NSID.badge, service, keyId: subject, challenge: operator, createdAt });
}
associate(subject, operator, service) {
this.mirror(subject, operator, service);
this.claim(operator, subject, service);
}
heldContract(operator, bidder) {
const bid = this.put(bidder, NSID.bid, "policytest-bid", { $type: NSID.bid, createdAt });
const accept = this.put(operator, NSID.accept, "policytest-accept", { $type: NSID.accept, bid, createdAt });
const receipt = this.put(bidder, NSID.receipt, receiptRKey(accept.uri, accept.cid), { $type: NSID.receipt, accept, createdAt });
return { accept, receipt, bidder };
}
contractAssociation(subject, operator, service, contract, expiresAt) {
this.mirror(subject, operator, service);
return this.put(operator, NSID.association, claimRKey(service, subject), {
$type: NSID.association, subject, service, contract: contract.accept, expiresAt, createdAt,
});
}
release(operator, contract) {
this.put(operator, NSID.vmDelete, releaseRKey(contract.receipt.uri), { $type: NSID.vmDelete, createdAt });
}
terminate(contract) {
this.put(contract.bidder, NSID.vmTerminated, terminationRKey(contract.receipt.uri), { $type: NSID.vmTerminated, createdAt });
}
bid(bidder, rkey, free, cost = 0) {
const nsid = free ? NSID.free : NSID.x402;
const payload = this.put(bidder, nsid, `${rkey}-payload`, free ? { $type: nsid, reason: "free", createdAt } : { $type: nsid, cost, createdAt });
return this.put(bidder, NSID.bid, rkey, { $type: NSID.bid, payload, createdAt });
}
// The run-module call contract for a policy module: public getRecord on the repo's PDS.
respond = (call) => {
assert.equal(call.nsid, GET_RECORD, `unexpected call ${call.nsid}`);
const { repo, collection, rkey } = call.params;
assert.equal(call.service, repo, "a read goes to the repo's own PDS");
const uri = `at://${repo}/${collection}/${rkey}`;
this.reads.push(uri);
const record = this.records.get(uri);
return record ? { ok: true, output: record } : { ok: false, error: `${GET_RECORD} failed with RecordNotFound: Could not locate record: ${uri}` };
};
}
// cases.go TrustCases, verbatim.
export const TrustCases = [
{ name: "unvouched", build: () => {} },
{ name: "vouched-by-self", Vouch: true, build: (w, p) => w.vouch(p.Self, p.CP) },
{ name: "vouched-by-verified-self-operator", Vouch: true, build: (w, p) => (w.associate(p.Self, p.SelfOp, p.SelfSvc), w.vouch(p.SelfOp, p.CP)) },
{ name: "vouched-by-self-claimed-self-operator", build: (w, p) => (w.mirror(p.Self, p.SelfOp, p.SelfSvc), w.vouch(p.SelfOp, p.CP)) },
{ name: "verified-counterparty-operator-vouched-by-self", Vouch: true, build: (w, p) => (w.associate(p.CP, p.CPOp, p.CPSvc), w.vouch(p.Self, p.CPOp)) },
{ name: "verified-counterparty-operator-vouched-by-self-operator", Vouch: true, build: (w, p) => {
w.associate(p.Self, p.SelfOp, p.SelfSvc);
w.associate(p.CP, p.CPOp, p.CPSvc);
w.vouch(p.SelfOp, p.CPOp);
} },
{ name: "forged-counterparty-operator-claim", build: (w, p) => (w.vouch(p.Self, p.CPOp), w.mirror(p.CP, p.CPOp, p.CPSvc)) },
{ name: "claim-for-the-other-role", build: (w, p) => (w.vouch(p.Self, p.CPOp), w.associate(p.CP, p.CPOp, p.SelfSvc)) },
{ name: "vouched-directly-with-verified-operator", Vouch: true, build: (w, p) => (w.associate(p.CP, p.CPOp, p.CPSvc), w.vouch(p.Self, p.CP)) },
{ name: "counterparty-operator-vouches-self-only", build: (w, p) => (w.associate(p.CP, p.CPOp, p.CPSvc), w.vouch(p.CPOp, p.Self)) },
{ name: "mutual-operator-vouches", Vouch: true, Mutuals: true, build: (w, p) => {
w.associate(p.CP, p.CPOp, p.CPSvc);
w.vouch(p.Self, p.CPOp);
w.vouch(p.CPOp, p.Self);
} },
{ name: "denounced", build: (w, p) => w.denounce(p.Self, p.CP) },
{ name: "stranger-vouches", build: (w, p) => (w.vouch(Stranger, p.CP), w.vouch(p.CP, p.Self)) },
{ name: "same-verified-operator", OnlyMe: true, Vouch: true, Mutuals: true, build: (w, p) => (w.associate(p.Self, p.SelfOp, p.SelfSvc), w.associate(p.CP, p.SelfOp, p.CPSvc)) },
{ name: "counterparty-operated-by-self", OnlyMe: true, Vouch: true, Mutuals: true, build: (w, p) => w.associate(p.CP, p.Self, p.CPSvc) },
{ name: "forged-same-operator", build: (w, p) => (w.associate(p.Self, p.SelfOp, p.SelfSvc), w.mirror(p.CP, p.SelfOp, p.CPSvc)) },
{ name: "different-verified-operators", build: (w, p) => (w.associate(p.Self, p.SelfOp, p.SelfSvc), w.associate(p.CP, p.CPOp, p.CPSvc)) },
{ name: "contract-scoped-association-held", OnlyMe: true, Vouch: true, Mutuals: true, build: (w, p) => {
w.associate(p.Self, p.SelfOp, p.SelfSvc);
w.contractAssociation(p.CP, p.SelfOp, p.CPSvc, w.heldContract(p.SelfOp, OtherBidder), plus(3600e3));
} },
{ name: "contract-scoped-association-expired", build: (w, p) => {
w.associate(p.Self, p.SelfOp, p.SelfSvc);
w.contractAssociation(p.CP, p.SelfOp, p.CPSvc, w.heldContract(p.SelfOp, OtherBidder), plus(-60e3));
} },
{ name: "contract-scoped-association-released", build: (w, p) => {
w.associate(p.Self, p.SelfOp, p.SelfSvc);
const contract = w.heldContract(p.SelfOp, OtherBidder);
w.contractAssociation(p.CP, p.SelfOp, p.CPSvc, contract, plus(3600e3));
w.release(p.SelfOp, contract);
} },
{ name: "contract-scoped-association-terminated", build: (w, p) => {
w.associate(p.Self, p.SelfOp, p.SelfSvc);
const contract = w.heldContract(p.SelfOp, OtherBidder);
w.contractAssociation(p.CP, p.SelfOp, p.CPSvc, contract, plus(3600e3));
w.terminate(contract);
} },
];
const FAMILY = {
"tangled-vouch": { want: (c) => !!c.Vouch, msg: "not vouched" },
"only-me": { want: (c) => !!c.OnlyMe, msg: "operator mismatch" },
mutuals: { want: (c) => !!c.Mutuals, msg: "not mutual follows" },
open: { want: () => true },
};
export const wasm = (crate) => new URL(`../../target/wasm32-unknown-unknown/release/${crate.replaceAll("-", "_")}.wasm`, import.meta.url);
export async function loadPolicy(crate) {
const mod = await load(wasm(crate));
// One run of `evaluate` under the real runModule host loop, the world answering its reads.
mod.evaluate = async (input, world = new World()) => {
const ran = await mod.handle("evaluate", input, { respond: world.respond });
return { ...ran, verdict: ran.result, reads: world.reads };
};
return mod;
}
export function abiSuite(mod) {
test("module has no imports and exports evaluate", () => {
assert.equal(WebAssembly.Module.imports(mod.module).length, 0);
const names = WebAssembly.Module.exports(mod.module).map((e) => e.name);
for (const name of ["memory", "alloc", "evaluate"]) assert.ok(names.includes(name), name);
});
}
// Every TrustCase, scope and full, from the policy's own perspective, read from the records.
export function trustSuite(crate, name, family) {
const perspective = name.startsWith("bidder-") ? "bidder" : "requester";
const { want, msg } = FAMILY[family];
return async () => {
const mod = await loadPolicy(crate);
abiSuite(mod);
for (const tc of TrustCases) {
for (const mode of ["scope", "full"]) {
test(`${name} ${mode} ${tc.name}: allow=${want(tc)}`, async () => {
const world = new World();
const p = partiesFor(perspective);
tc.build(world, p);
const input = mode === "scope"
? { selfDid: p.Self, counterpartyDid: p.CP, mode }
: { selfDid: p.Self, counterpartyDid: p.CP, subjectDid: p.CP, mode };
const { verdict, error } = await mod.evaluate(input, world);
assert.equal(error, undefined);
const deny = mode === "scope" ? `scope denied by ${name}` : msg;
assert.deepEqual(verdict, want(tc) ? { allow: true, violations: [] } : { allow: false, violations: [{ msg: deny, policyId: name }] });
});
}
}
if (family === "open") return;
test(`${name}: a seeded snapshot is used as is, no reads`, async () => {
const p = partiesFor(perspective);
const vouched = { operatorOf: { [p.Self]: p.Self }, vouchedBy: { [p.Self]: [p.CP] } };
const verdict = mod.run("evaluate", { selfDid: p.Self, counterpartyDid: p.CP, snapshot: vouched, now, state: null, event: { type: "start" } });
assert.deepEqual(verdict.calls, undefined);
assert.equal(verdict.done, true);
assert.equal(verdict.result.allow, family === "tangled-vouch");
const operated = { operatorOf: { [p.Self]: p.SelfOp, [p.CP]: p.SelfOp }, vouchedBy: {} };
assert.equal(mod.run("evaluate", { selfDid: p.Self, counterpartyDid: p.CP, snapshot: operated, now, event: { type: "start" } }).result.allow, true);
});
test(`${name}: a self-vouch is ignored (BuildSnapshotWith skips voucher == subject)`, async () => {
// The counterparty is the evaluator's own (verified) operator, and only vouches for itself.
const p = partiesFor(perspective);
const world = new World();
world.associate(p.Self, p.SelfOp, p.SelfSvc);
world.vouch(p.SelfOp, p.SelfOp);
const { verdict, reads } = await mod.evaluate({ selfDid: p.Self, counterpartyDid: p.SelfOp, mode: "scope" }, world);
assert.equal(verdict.allow, false);
assert.ok(!reads.includes(`at://${p.SelfOp}/${NSID.vouch}/${p.SelfOp}`), "the self pair is never read");
const seeded = { operatorOf: { [p.Self]: p.SelfOp }, vouchedBy: { [p.Self]: [], [p.SelfOp]: [p.SelfOp] } };
assert.equal(mod.run("evaluate", { selfDid: p.Self, counterpartyDid: p.SelfOp, snapshot: seeded, now, event: { type: "start" } }).result.allow, false);
});
test(`${name}: bad input is an error (kcp exits 1), as data`, async () => {
assert.equal((await mod.evaluate({ counterpartyDid: Bidder })).error, "selfDid is required (the evaluator's own DID)");
assert.equal((await mod.evaluate({ selfDid: Bidder, mode: "scope" })).error, "scope mode requires counterpartyDid");
assert.deepEqual((await mod.evaluate({ selfDid: Bidder })).verdict, { allow: false, violations: [{ msg: "no counterparty to evaluate", policyId: name }] });
assert.deepEqual((await mod.evaluate({ selfDid: Bidder, subjectDid: Requester, counterpartyDid: Stranger })).verdict, {
allow: false, violations: [{ msg: "the subject and the counterparty differ", policyId: name }],
});
});
test(`${name}: full mode derives the counterparty from the records`, async () => {
const p = partiesFor(perspective);
const world = new World();
world.vouch(p.Self, p.CP);
const record = (repo, collection) => ({ uri: `at://${repo}/${collection}/r`, cid: "bafyx" });
const input = perspective === "requester" ? { bid: record(p.CP, NSID.bid) } : { rfp: record(p.CP, NSID.rfp) };
const { verdict } = await mod.evaluate({ selfDid: p.Self, ...input }, world);
assert.equal(verdict.allow, family === "tangled-vouch");
});
};
}