CAT-G2: the packages token is renewed on the forge's refusal, said as a finding, never on a timer

The Go bundle raises packages-token-refused in the module's findings state when the forge
answers 401 to a write; the watcher mints afresh on that key's event and clears it (lead's
ruling on A3n, map-onto-how-the-mesh-is-built: nothing waits on a timer).

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 14:47:26 +01:00
parent 929b1ce13e
commit 4492bc3013
7 changed files with 103 additions and 20 deletions
+12 -3
View File
@@ -17,7 +17,7 @@ import { join } from "node:path";
import { MintedToken, TOKEN_SCOPES } from "../dist/token.js";
import { GiteaClient } from "../dist/client.js";
import { TOOLS_ACCOUNT, TOOLS_TEAM_UNITS, BUILDER_ACCOUNT, AGENT_ACCOUNT, meshAccounts } from "../dist/tools-account.js";
import { PACKAGES_ACCOUNT, PACKAGES_TEAM_UNITS, keepPackagesToken, packagesToken } from "../dist/packages-account.js";
import { PACKAGES_ACCOUNT, PACKAGES_TEAM_UNITS, PACKAGES_TOKEN_REFUSED, keepPackagesToken, packagesToken, renewOnRefusal } from "../dist/packages-account.js";
import { repoCheckFacts } from "../dist/pulls.js";
const ADMIN = "mesh-admin";
@@ -391,9 +391,18 @@ test("the package seats write as an account of their own: plain, in a team writi
const team = forge.teams.find((t) => t.name === "mesh-packages");
assert.ok(team?.members.has(PACKAGES_ACCOUNT));
assert.deepEqual(team!.units.units_map, PACKAGES_TEAM_UNITS.units_map, "the team writes packages and nothing else");
// The forge drops the token behind the module's back: the next look mints it afresh.
// The forge drops the token behind the module's back: the Go bundle's refusal (the finding's put) mints it afresh and
// clears the finding; no timer looks at it, and another key of the findings state is not its own.
forge.tokens.splice(forge.tokens.indexOf(held[0]), 1);
assert.equal(await keepPackagesToken(source, forge.url), "the forge rejected the package seats' write token; minted afresh");
const cleared: string[] = [];
const said: string[] = [];
const renew = renewOnRefusal(source, forge.url, { delete: async (k) => { cleared.push(k); } }, (l) => said.push(l));
await renew({ key: "seat.gitea.other", op: "put" });
await renew({ key: PACKAGES_TOKEN_REFUSED, op: "delete" });
assert.equal(forge.tokens.filter((t) => t.name === "mesh-packages").length, 0, "nothing renews but the refusal");
await renew({ key: PACKAGES_TOKEN_REFUSED, op: "put" });
assert.deepEqual(said, ["the forge rejected the package seats' write token; minted afresh"]);
assert.deepEqual(cleared, [PACKAGES_TOKEN_REFUSED]);
assert.equal(forge.tokens.filter((t) => t.name === "mesh-packages").length, 1);
// The tools' token reads packages too: read:package (design 51's read-only tool token).
assert.ok(TOKEN_SCOPES.includes("read:package"));