import { afterEach, describe, it } from "@std/testing/bdd"; import { expect } from "@std/expect"; import { Identity } from "@commonfabric/identity"; import { StorageManager } from "@commonfabric/runner/storage/cache.deno"; import { Runtime } from "../src/runtime.ts"; import { resolvePolicyFacingImplementationIdentity } from "../src/cfc/implementation-identity.ts"; import { getVerifiedProvenance } from "../src/harness/verified-provenance.ts"; import type { Module, Pattern } from "../src/builder/types.ts"; import type { HarnessedFunction } from "../src/harness/types.ts"; /** * Regression for the re-export provenance hazard (Codex review of PR C, fixed * with the source-identity guard in `Engine.recordModuleProvenance`): * * A re-exporting module (`export { setName } from "./handlers"`) surfaces the * defining module's function under the RE-EXPORTER's identity. Provenance is * first-write-wins and CFC fails closed on an identity/`fn.src` mismatch, so * letting the re-exporter (potentially visited first) stamp its own identity * would make a genuinely-verified handler resolve as `unsupported`. The guard * records provenance only when the function's canonical `fn.src` names the * recording module, so only the defining module's registration sticks. */ const signer = await Identity.fromPassphrase("reexport-provenance"); const PROGRAM = { main: "/main.tsx", files: [ { name: "/handlers.tsx", contents: `/// import { handler, Writable } from "commonfabric"; export const setName = handler<{ name?: string }, { name: Writable }>( (event, state) => { state.name.set(event.name ?? ""); }, ); `, }, { // The entry re-exports the handler AND uses it, so the entry module is // evaluated/indexed and surfaces `setName` under its own identity. name: "/main.tsx", contents: `/// import { pattern, Writable } from "commonfabric"; import { setName } from "./handlers.tsx"; export { setName } from "./handlers.tsx"; export default pattern(() => { const name = new Writable("").for("name"); return { name, setName: setName({ name }) }; }); `, }, ], }; describe("re-export provenance", () => { let storageManager: ReturnType | undefined; let runtime: Runtime | undefined; afterEach(async () => { await runtime?.dispose(); await storageManager?.close(); runtime = undefined; storageManager = undefined; }); it("a re-exported handler still resolves as verified (defining identity wins)", async () => { storageManager = StorageManager.emulate({ as: signer }); runtime = new Runtime({ apiUrl: new URL(import.meta.url), storageManager, cfcEnforcementMode: "observe", }); const pattern = await runtime.patternManager.compilePattern( PROGRAM, ) as Pattern; await runtime.idle(); const node = pattern.nodes.find((n) => (n.module as Module).type === "javascript" && (n.module as Module).wrapper === "handler" ); expect(node).toBeDefined(); const module = node!.module as Module; const fn = module.implementation as HarnessedFunction; // Provenance identity matches the function's own canonical source — the // DEFINING module (handlers.tsx), never the re-exporting entry. const provenance = getVerifiedProvenance(fn); expect(provenance).toBeDefined(); expect((fn as { src?: string }).src ?? "").toContain( `cf:module/${provenance!.identity}`, ); // CFC resolves it as verified — NOT unsupported (the bug would have made a // re-exporter's identity stamp it, failing the fn.src consistency check). const identity = resolvePolicyFacingImplementationIdentity(module, { implementation: fn, }); expect(identity?.kind).toBe("verified"); }); });