chore: sync the frontend template from 4dc033c to 8157ad4
The product was materialized from the template at `4dc033c` and has stayed on it through 43 template commits, so it was missing all three rounds of adapter remediation — including files it never had, such as the shared `abortable-operation` primitive and the `exact-snapshot` decoder that later fixes are written against. Taking only the newest round was not possible for that reason: the delta is coherent only as a whole. The product had not touched `src/adapters` at all since materialization, so the 140-file delta applied with a three-way merge and no conflicts. `package.json` was the single overlap and merged cleanly: the product owns `name`, the template contributed `check:adapter-inventory`, `check:remediation-ledger` and the image-resolve-signal type fixture. All 24 product-owned files — README, index.html, CI workflow, i18n catalog, home page, generated schemas, evidence scripts, component and visual snapshots — are byte-identical to `main`. `template.lock.json` now pins the synced revision and tree. Verified in this repository, not inherited from the template: six type projects, lint, nine gates (adapter inventory, remediation ledger, registries, diagnostics, realtime boundaries, architecture, browser file/storage boundaries, optional recipes, documentation), the production build, and 2,054 of 2,073 tests. The 19 failures are all in `tests/unit/ci-artifact-contract.test.ts` and are the same pre-existing sandbox RLIMIT, EMFILE, umask and `/tmp` permission behaviour the template records; four suites that failed once under parallel load pass in isolation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
002ba3624e
commit
4bff9ca151
@@ -0,0 +1,337 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
composeContractContributions,
|
||||
type ComposedContractContributions,
|
||||
} from "../../src/contracts/external-contract-runtime.ts";
|
||||
import {
|
||||
installRestAuthProfileRegistry,
|
||||
INSTALLED_REST_AUTH_PROFILES,
|
||||
REST_AUTH_PROFILES,
|
||||
} from "../../src/contracts/rest-profiles.ts";
|
||||
import { TEST_CONTRACT_CONTRIBUTION } from "../helpers/external-contract-fixture.ts";
|
||||
|
||||
/**
|
||||
* LIVE-02 / LIVE-03. `Object.freeze(new Map(...))` freezes the wrapper object,
|
||||
* not the backing store: `set`, `delete` and `clear` keep working. Every
|
||||
* registry the executor consults after composition must therefore be a read
|
||||
* facade over a private store, and the rows it hands back must be exact
|
||||
* own-data snapshots that a later mutation of the source cannot reach.
|
||||
*/
|
||||
|
||||
const MUTATORS = ["set", "delete", "clear"] as const;
|
||||
|
||||
function borrowedMapMutation(
|
||||
facade: unknown,
|
||||
mutator: (typeof MUTATORS)[number],
|
||||
): "THREW" | "MUTATED" {
|
||||
try {
|
||||
switch (mutator) {
|
||||
case "set":
|
||||
Map.prototype.set.call(facade as never, "INJECTED", {} as never);
|
||||
break;
|
||||
case "delete":
|
||||
Map.prototype.delete.call(facade as never, "ANONYMOUS");
|
||||
break;
|
||||
case "clear":
|
||||
Map.prototype.clear.call(facade as never);
|
||||
break;
|
||||
}
|
||||
return "MUTATED";
|
||||
} catch {
|
||||
return "THREW";
|
||||
}
|
||||
}
|
||||
|
||||
describe("LIVE-02 installed REST auth profile registry", () => {
|
||||
it("exposes no mutation API", () => {
|
||||
const registry = INSTALLED_REST_AUTH_PROFILES as unknown as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
for (const mutator of MUTATORS) {
|
||||
expect(registry[mutator]).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
it("survives a cast mutation and a borrowed Map.prototype mutator", () => {
|
||||
const registry = installRestAuthProfileRegistry(REST_AUTH_PROFILES);
|
||||
const before = registry.size;
|
||||
const identity = registry.get("ANONYMOUS");
|
||||
expect(identity).toBeDefined();
|
||||
|
||||
for (const mutator of MUTATORS) {
|
||||
expect(borrowedMapMutation(registry, mutator)).toBe("THREW");
|
||||
}
|
||||
|
||||
expect(registry.size).toBe(before);
|
||||
expect(registry.get("ANONYMOUS")).toBe(identity);
|
||||
expect(registry.get("REFERENCE_EXTERNAL_BEARER")?.credentials).toBe("omit");
|
||||
});
|
||||
|
||||
it("does not observe a post-installation mutation of the source record", () => {
|
||||
const source: Record<string, (typeof REST_AUTH_PROFILES)["ANONYMOUS"]> = {
|
||||
ANONYMOUS: {
|
||||
authProfileId: "ANONYMOUS",
|
||||
transport: "ANONYMOUS",
|
||||
credentials: "omit",
|
||||
allowedCredentialHeaders: [],
|
||||
requiredCredentialHeaders: [],
|
||||
},
|
||||
};
|
||||
const registry = installRestAuthProfileRegistry(source);
|
||||
delete source.ANONYMOUS;
|
||||
expect(registry.get("ANONYMOUS")?.transport).toBe("ANONYMOUS");
|
||||
});
|
||||
|
||||
it("keeps read APIs the executor depends on", () => {
|
||||
const registry = INSTALLED_REST_AUTH_PROFILES;
|
||||
expect(registry.has("ANONYMOUS")).toBe(true);
|
||||
expect(registry.has("NO_SUCH_PROFILE")).toBe(false);
|
||||
expect([...registry.keys()].sort()).toEqual([
|
||||
"ANONYMOUS",
|
||||
"REFERENCE_EXTERNAL_BEARER",
|
||||
]);
|
||||
expect([...registry.entries()].length).toBe(registry.size);
|
||||
expect([...registry.values()].length).toBe(registry.size);
|
||||
});
|
||||
});
|
||||
|
||||
describe("LIVE-03 composed contract registry", () => {
|
||||
function compose(): ComposedContractContributions {
|
||||
return composeContractContributions([TEST_CONTRACT_CONTRIBUTION] as never);
|
||||
}
|
||||
|
||||
it("exposes no mutation API on either lookup", () => {
|
||||
const composed = compose();
|
||||
for (const facade of [composed.httpByOperationId, composed.eventByType]) {
|
||||
const record = facade as unknown as Record<string, unknown>;
|
||||
for (const mutator of MUTATORS) {
|
||||
expect(record[mutator]).toBeUndefined();
|
||||
}
|
||||
for (const mutator of MUTATORS) {
|
||||
expect(borrowedMapMutation(facade, mutator)).toBe("THREW");
|
||||
}
|
||||
}
|
||||
expect(composed.httpByOperationId.size).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("snapshots the frontend policy so a later source mutation cannot reach it", () => {
|
||||
const mutablePolicy = {
|
||||
...TEST_CONTRACT_CONTRIBUTION.http[0]!.frontend,
|
||||
};
|
||||
const contribution = {
|
||||
...TEST_CONTRACT_CONTRIBUTION,
|
||||
http: [
|
||||
{
|
||||
...TEST_CONTRACT_CONTRIBUTION.http[0]!,
|
||||
frontend: mutablePolicy,
|
||||
},
|
||||
],
|
||||
};
|
||||
const composed = composeContractContributions([contribution] as never);
|
||||
const operationId = [...composed.httpByOperationId.keys()][0]!;
|
||||
const installedBefore =
|
||||
composed.httpByOperationId.get(operationId)!.frontend.totalDeadlineMs;
|
||||
|
||||
mutablePolicy.totalDeadlineMs = 999_999;
|
||||
|
||||
expect(
|
||||
composed.httpByOperationId.get(operationId)!.frontend.totalDeadlineMs,
|
||||
).toBe(installedBefore);
|
||||
expect(installedBefore).not.toBe(999_999);
|
||||
});
|
||||
|
||||
it("rejects an accessor or inherited policy field", () => {
|
||||
const inherited = Object.create({ diagnosticsOperation: "INHERITED" }) as
|
||||
Record<string, unknown>;
|
||||
for (const [key, value] of Object.entries(
|
||||
TEST_CONTRACT_CONTRIBUTION.http[0]!.frontend,
|
||||
)) {
|
||||
if (key === "diagnosticsOperation") continue;
|
||||
inherited[key] = value;
|
||||
}
|
||||
const accessor = { ...TEST_CONTRACT_CONTRIBUTION.http[0]!.frontend };
|
||||
Object.defineProperty(accessor, "totalDeadlineMs", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: () => 10_000,
|
||||
});
|
||||
|
||||
for (const frontend of [inherited, accessor]) {
|
||||
expect(() =>
|
||||
composeContractContributions([
|
||||
{
|
||||
...TEST_CONTRACT_CONTRIBUTION,
|
||||
http: [{ ...TEST_CONTRACT_CONTRIBUTION.http[0]!, frontend }],
|
||||
},
|
||||
] as never),
|
||||
).toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* NS-02. Composition validated the caller's object and then read it again to
|
||||
* copy it. Between those two reads a stateful answer could swap a deadline or
|
||||
* a retry budget, so the value that passed the ceiling check and the value the
|
||||
* executor ran with were two different things.
|
||||
*/
|
||||
describe("validate the snapshot, never the source", () => {
|
||||
/** Answers a safe value to a plain read and a hostile one to a copy. */
|
||||
const statefulFrontend = () =>
|
||||
new Proxy(
|
||||
{ ...TEST_CONTRACT_CONTRIBUTION.http[0]!.frontend },
|
||||
{
|
||||
get(target, key, receiver) {
|
||||
if (key === "totalDeadlineMs") return 10_000;
|
||||
return Reflect.get(target, key, receiver);
|
||||
},
|
||||
getOwnPropertyDescriptor(target, key) {
|
||||
if (key === "totalDeadlineMs") {
|
||||
return {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: 999_999,
|
||||
};
|
||||
}
|
||||
return Reflect.getOwnPropertyDescriptor(target, key);
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const contributionWith = (row: unknown) => [
|
||||
{ ...TEST_CONTRACT_CONTRIBUTION, http: [row] },
|
||||
];
|
||||
|
||||
it("validates the deadline it will install, not the one it was shown", () => {
|
||||
// The copied value exceeds the hard ceiling, so composition must stop
|
||||
// rather than install a deadline no check ever saw.
|
||||
expect(() =>
|
||||
composeContractContributions(
|
||||
contributionWith({
|
||||
...TEST_CONTRACT_CONTRIBUTION.http[0]!,
|
||||
frontend: statefulFrontend(),
|
||||
}) as never,
|
||||
),
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
it("keys the registry by the operation id it copied, not the one it was shown", () => {
|
||||
const base = { ...TEST_CONTRACT_CONTRIBUTION.http[0]!.contract };
|
||||
const contract = new Proxy(base, {
|
||||
get(target, key, receiver) {
|
||||
if (key === "operationId") return base.operationId;
|
||||
return Reflect.get(target, key, receiver);
|
||||
},
|
||||
getOwnPropertyDescriptor(target, key) {
|
||||
if (key === "operationId") {
|
||||
return {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: "SwappedOperation",
|
||||
};
|
||||
}
|
||||
return Reflect.getOwnPropertyDescriptor(target, key);
|
||||
},
|
||||
});
|
||||
const composed = composeContractContributions(
|
||||
contributionWith({
|
||||
...TEST_CONTRACT_CONTRIBUTION.http[0]!,
|
||||
contract,
|
||||
}) as never,
|
||||
);
|
||||
expect([...composed.httpByOperationId.keys()]).toEqual([
|
||||
"SwappedOperation",
|
||||
]);
|
||||
expect(
|
||||
composed.httpByOperationId.get("SwappedOperation")!.contract
|
||||
.operationId,
|
||||
).toBe("SwappedOperation");
|
||||
});
|
||||
|
||||
const hostileRows = [
|
||||
{
|
||||
label: "an installed row with an extra own field",
|
||||
row: () => ({
|
||||
...TEST_CONTRACT_CONTRIBUTION.http[0]!,
|
||||
injected: true,
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: "an installed row with a symbol field",
|
||||
row: () => ({
|
||||
...TEST_CONTRACT_CONTRIBUTION.http[0]!,
|
||||
[Symbol.for("injected")]: true,
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: "an installed row with a custom prototype",
|
||||
row: () =>
|
||||
Object.assign(Object.create({ injected: true }), {
|
||||
...TEST_CONTRACT_CONTRIBUTION.http[0]!,
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: "an installed row hiding a non-enumerable own field",
|
||||
row: () =>
|
||||
Object.defineProperty(
|
||||
{ ...TEST_CONTRACT_CONTRIBUTION.http[0]! },
|
||||
"injected",
|
||||
{ enumerable: false, value: true },
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "an installed row behind a throwing ownKeys trap",
|
||||
row: () =>
|
||||
new Proxy(
|
||||
{ ...TEST_CONTRACT_CONTRIBUTION.http[0]! },
|
||||
{
|
||||
ownKeys() {
|
||||
throw new TypeError("hostile ownKeys trap");
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
for (const { label, row } of hostileRows) {
|
||||
it(`refuses to compose ${label}`, () => {
|
||||
expect(() =>
|
||||
composeContractContributions(contributionWith(row()) as never),
|
||||
).toThrow();
|
||||
});
|
||||
}
|
||||
|
||||
it("refuses a contribution whose own shape is not exact", () => {
|
||||
for (const contribution of [
|
||||
{ ...TEST_CONTRACT_CONTRIBUTION, injected: true },
|
||||
Object.assign(Object.create({ injected: true }), {
|
||||
...TEST_CONTRACT_CONTRIBUTION,
|
||||
}),
|
||||
{
|
||||
...TEST_CONTRACT_CONTRIBUTION,
|
||||
[Symbol.for("injected")]: true,
|
||||
},
|
||||
]) {
|
||||
expect(() =>
|
||||
composeContractContributions([contribution] as never),
|
||||
).toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
it("refuses an event contract whose own shape is not exact", () => {
|
||||
const events = TEST_CONTRACT_CONTRIBUTION.events;
|
||||
if (events.length === 0) return;
|
||||
for (const event of [
|
||||
{ ...events[0]!, injected: true },
|
||||
Object.assign(Object.create({ injected: true }), { ...events[0]! }),
|
||||
]) {
|
||||
expect(() =>
|
||||
composeContractContributions([
|
||||
{ ...TEST_CONTRACT_CONTRIBUTION, events: [event] },
|
||||
] as never),
|
||||
).toThrow();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user