@githolon/testing 0.4.0 → 0.5.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@githolon/testing",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "description": "@githolon/testing — law TDD for Nomos domains: boot the REAL engine plane in-process (the exact machinery every cloud DO, heavy container and web client runs), dispatch directives, assert rows, assert TYPED REFUSALS, fork for what-ifs — fully offline inside vitest.",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -53,7 +53,7 @@ function seedManifests(m, strings) {
53
53
  m.set("identity-manifests.json", new File(enc.encode(strings.identity)));
54
54
  }
55
55
 
56
- export const installPayload = (hash, usda, installedBy) => ({ domainHash: hash, packageUsda: usda, installedBy, authorityScope: "workspace/root", dependencies: [], finalizers: [] });
56
+ export const installPayload = (hash, usda, installedBy, dispositions) => ({ domainHash: hash, packageUsda: usda, installedBy, authorityScope: "workspace/root", dependencies: [], finalizers: [], ...(dispositions ? { dispositions } : {}) });
57
57
 
58
58
  /**
59
59
  * Boot the resident wasm + /work tree. `wasmModule` is a PRECOMPILED WebAssembly.Module
@@ -1149,6 +1149,22 @@ export function unmount(eng, ws) {
1149
1149
 
1150
1150
  function writeWork(eng, name, bytes) { eng.preopen.dir.contents.set(name, new File(bytes)); }
1151
1151
 
1152
+ /** THE EVOLVE DRY-RUN (managed_rollout.md slice 1 — "would this upgrade admit?"):
1153
+ * the evolve gate's pure judgment over the mounted workspace's folded state and a
1154
+ * CANDIDATE package, without installing. Returns {admits} or {admits:false,
1155
+ * domain, detail} — byte-identical to the refusal the real install would meet. */
1156
+ export function evolveDryRun(eng, ws, usda, domainHash, dispositions = null) {
1157
+ return JSON.parse(call(eng.ex, "evolve_dryrun", { repoArg: repoArgOf(ws), branch: BRANCH, bundle: usda, hash: domainHash, ...(dispositions ? { dispositions } : {}) }, eng.STDERR));
1158
+ }
1159
+
1160
+ /** THE FRONT-DOOR MINT (engine plane): reserve a kernel-minted typed id
1161
+ * (`<TypeTag>_<uuidv7>`) via the wasm `mint` arm — the same mint the web client
1162
+ * and the generated clients call. The minted id rides IN the payload, so replay
1163
+ * reads the captured id and never re-mints (determinism via capture). */
1164
+ export function mintId(eng, typeTag) {
1165
+ return JSON.parse(call(eng.ex, "mint", { typeTag, nowMillis: Date.now() }, eng.STDERR)).id;
1166
+ }
1167
+
1152
1168
  export function author(eng, ws, domain, directiveId, payload, controllerHash, opts = {}) {
1153
1169
  const seq = eng.seq++;
1154
1170
  // rngDraws: the captured-entropy budget this intent's plan may consume (each minted id
@@ -1238,7 +1254,7 @@ async function mainIntentIds(eng, ws) {
1238
1254
  * engine has no durable store), obvious attacks drop. Admitted intents merge to main,
1239
1255
  * durably push, the branch is consumed.
1240
1256
  */
1241
- export async function admitAll(eng, ws, ledger, { refuseDomains = [], shardRouting = null } = {}) {
1257
+ export async function admitAll(eng, ws, ledger, { refuseDomains = [], receiptFence = null, shardRouting = null } = {}) {
1242
1258
  const refuse = new Set(refuseDomains);
1243
1259
  const routes = shardRouting ? directiveRoutes(eng) : null;
1244
1260
  const gitdir = gitdirOf(ws);
@@ -1305,6 +1321,20 @@ export async function admitAll(eng, ws, ledger, { refuseDomains = [], shardRouti
1305
1321
  deadLetters.push({ intentId, oid: oid.slice(0, 10), session: cid, error, blob, domain: dom, directiveId: dirId });
1306
1322
  continue;
1307
1323
  }
1324
+ // THE RECEIPT FENCE (capability_marketplace.md slice 1.5 — the ratified
1325
+ // authz condition): a capability RECEIPT (complete/fail/block/deadLetter)
1326
+ // is an EXECUTOR/OWNER write — the open session lane never folds one, so
1327
+ // a hostile peer cannot terminally close orders it didn't fulfill, and a
1328
+ // forged "result" never reaches any watcher. PARKED, not dropped: an
1329
+ // honest-but-misconfigured self-hosted executor sees its receipt in the
1330
+ // DLQ, and the OWNER-GATED retry is the owner-sanctioned unjam (the
1331
+ // lawful lane for a credential-holding self-hoster is /author).
1332
+ if (receiptFence && dirId && Array.isArray(receiptFence[dom]) && receiptFence[dom].includes(dirId)) {
1333
+ const error = `'${dom}/${dirId}' is a capability RECEIPT — receipts are executor/owner writes, never open-session writes. Author it via POST /v1/workspaces/${ws}/author (owner Bearer), or — if this parked receipt is sanctioned — the owner unjams it: POST /v1/workspaces/${ws}/dead-letters/retry`;
1334
+ rejected.push({ oid: oid.slice(0, 10), error, deadLettered: true });
1335
+ deadLetters.push({ intentId, oid: oid.slice(0, 10), session: cid, error, blob, domain: dom, directiveId: dirId });
1336
+ continue;
1337
+ }
1308
1338
  // THE WRONG-HOME GATE (sharding slice 2): a routed directive's home must be
1309
1339
  // assigned to THIS workspace by the coordinator's law-state shard map.
1310
1340
  // Misrouted → the typed `wrong-home` refusal naming the correct workspace
@@ -1517,8 +1547,12 @@ export async function boot(eng, ws, ledger) {
1517
1547
  }
1518
1548
 
1519
1549
  /** Install a tenant package under the nomos controller (validation is the HOST's job). */
1520
- export async function deploy(eng, ws, ledger, usda, domainHash) {
1521
- const result = author(eng, ws, "nomos", "installDomain", installPayload(domainHash, usda, eng.installedBy), eng.hashes.nomos);
1550
+ export async function deploy(eng, ws, ledger, usda, domainHash, dispositions) {
1551
+ // THE EVOLVE-GATE ANSWER LANE (#58): `dispositions` ({retired, retyped, rebinds,
1552
+ // ackBy}) ride the committed installDomain payload — IN-HISTORY facts the one gate
1553
+ // adjudicates the stable-id diff against. Absent for the common (non-destructive)
1554
+ // upgrade; the gate's typed refusal names the remedy when one is needed.
1555
+ const result = author(eng, ws, "nomos", "installDomain", installPayload(domainHash, usda, eng.installedBy, dispositions), eng.hashes.nomos);
1522
1556
  // THE SHARD-IDENTITY ENSURE (#41 — slice 3a): a taxonomy-bearing law carries the
1523
1557
  // homing invariant, which judges against the workspace's OWN declared identity
1524
1558
  // (`NomosShardIdentity`, law-state in the shard's own chain). The worker is the