A provisioner is told what the mesh derived for each consumer (hq ADR 0201)

Provision gains `derived`; the harness keeps it per applied login so remove()
is told it too, and includes it in the change hash — a provider that renames
what it derives has given the consumer a different resource.

Version 0.1.7. Rebased onto main after the bundles refactor; the record this
cites was written as 0188 and renumbered to 0201, because ADR 0188 on main is
now the bundles record.
This commit is contained in:
2026-10-04 02:44:50 +02:00
parent 0b018562e3
commit f1485257a8
4 changed files with 90 additions and 13 deletions
+49
View File
@@ -74,6 +74,55 @@ test("provisioner creates each consumer with the mesh's login and password, remo
stop();
});
test("provisioner hands the adapter what the mesh derived, and still has it at withdrawal", async () => {
// novox/hq ADR 0201: the provider declares what it derives for each consumer and the mesh fills
// it. The adapter must be able to read it on create, must see a changed derivation as a change
// worth re-applying, and must still be told it when the consumer is withdrawn — by which time
// the mesh has already dropped it from the file.
const dir = await mkdtemp(join(tmpdir(), "prov-derived-"));
const created: unknown[] = [];
const removed: unknown[] = [];
await writeFile(join(dir, "ncloud.secret"), "minted-pw\n");
const receives = join(dir, "store.json");
const doc = (given: unknown[]): string =>
JSON.stringify({ contributions: 1, requirement: "s3-bucket", given });
const entry = (bucket: string) => ({
from: "nextcloud", node: "anchor", as: "mesh_anchor_ncloud",
secret: join(dir, "ncloud.secret"), values: {}, derived: { bucket },
});
await writeFile(receives, doc([entry("mesh-anchor-ncloud")]));
const stop = runProvisioner(
"s3-bucket",
{
async create(p) {
created.push(p.derived);
},
async remove(p) {
removed.push(p.derived);
},
},
{ receives, everyMs: 20 },
);
await waitFor(() => created.length === 1, 2000);
assert.deepEqual(created[0], { bucket: "mesh-anchor-ncloud" });
// A changed derivation is a changed consumer: the login and the password are the same, and the
// resource it is being given is not. Trusted from memory, this would never be applied.
await writeFile(receives, doc([entry("mesh-anchor-files")]));
await waitFor(() => created.length === 2, 2000);
assert.deepEqual(created[1], { bucket: "mesh-anchor-files" });
// Withdrawn: the file no longer says anything about this consumer, and the adapter is still
// told which bucket to take away.
await writeFile(receives, doc([]));
await waitFor(() => removed.length === 1, 2000);
assert.deepEqual(removed[0], { bucket: "mesh-anchor-files" });
stop();
});
test("provisioner applies again what the backend no longer holds, and trusts memory without holds", async () => {
const dir = await mkdtemp(join(tmpdir(), "prov-holds-"));
await writeFile(join(dir, "webapp.secret"), "minted-pw\n");