@fabricorg/gen-conformance 0.2.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Release additive public compiler and generator APIs as minor versions. This includes parameterized
8
+ view schema contracts, the exported usage-contract JSON schema, and the runtime Platform validation
9
+ used by capability generation.
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+ - @fabricorg/compiler@2.2.0
15
+
16
+ ## 0.2.1
17
+
18
+ ### Patch Changes
19
+
20
+ - b932767: Add portable parameter schemas and validation for projection views. Projection snapshot keys now
21
+ include a canonical parameter identity, generated capability and experience contracts preserve view
22
+ parameter schemas, and compatible snapshots continue through the explicit `upgradeSnapshot` seam.
23
+ - Updated dependencies [b932767]
24
+ - @fabricorg/compiler@2.1.1
25
+
26
+ ### Additional release notes
27
+
28
+ ### Patch Changes
29
+
30
+ - Preserve projection view parameter schemas in generated conformance plans.
31
+
3
32
  ## 0.2.0
4
33
 
5
34
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -279,6 +279,7 @@ function buildModuleConformancePlan(module2, manifestDigest) {
279
279
  views: module2.views.map((view) => ({
280
280
  name: view.name,
281
281
  version: view.version,
282
+ ...view.parameterSchema ? { parameterSchema: view.parameterSchema } : {},
282
283
  consumes: view.consumes.map((consumption) => ({ eventType: consumption.eventType, schemaVersions: [...consumption.schemaVersions] }))
283
284
  })),
284
285
  eventTypes: module2.eventTypes.map((event) => ({ eventType: event.eventType, schemaVersion: event.schemaVersion }))
@@ -306,7 +307,7 @@ function suiteSource(plan, generator) {
306
307
  }
307
308
  var conformanceGenerator = {
308
309
  name: "@fabricorg/gen-conformance",
309
- version: "0.2.0",
310
+ version: "0.3.0",
310
311
  generate(ir) {
311
312
  return ir.modules.flatMap((module2) => {
312
313
  const plan = buildModuleConformancePlan(module2, ir.manifestDigest);
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["import { stableStringify, type FabricCompilerIr, type GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { ModuleManifest } from \"@fabricorg/platform\";\n\n/** Checks a single module's own behaviour, verifiable against a governed host. */\nexport const MODULE_CONFORMANCE_CHECKS = [\n\t\"fabric.idempotency.same-command-replay.v1\",\n\t\"fabric.idempotency.conflicting-payload.v1\",\n\t\"fabric.idempotency.concurrent-submission.v1\",\n\t\"fabric.authorization.governing-moment.v1\",\n\t\"fabric.authorization.offline-replay.v1\",\n\t\"fabric.events.compatibility.v1\",\n\t\"fabric.provenance.propagation.v1\",\n\t\"fabric.consumers.tolerant-envelope.v1\",\n] as const;\n\n/**\n * Checks that belong to a repository rather than a module. They are certification\n * evidence like any other check, but no per-module suite can produce them.\n */\nexport const PLATFORM_CONFORMANCE_CHECKS = [\n\t\"fabric.documentation.parity.v1\",\n\t\"fabric.documentation.llms-contract.v1\",\n] as const;\n\nexport const PHASE_1_CONFORMANCE_CHECKS = [...MODULE_CONFORMANCE_CHECKS, ...PLATFORM_CONFORMANCE_CHECKS] as const;\n\nexport type ModuleConformanceCheckId = typeof MODULE_CONFORMANCE_CHECKS[number];\nexport type PlatformConformanceCheckId = typeof PLATFORM_CONFORMANCE_CHECKS[number];\nexport type Phase1ConformanceCheckId = ModuleConformanceCheckId | PlatformConformanceCheckId;\n\nexport interface ConformanceEvidence { id: Phase1ConformanceCheckId; status: \"passed\" | \"failed\"; evidence: string[] }\n\nexport interface CertificationResult {\n\tformatVersion: 1;\n\tmanifestDigest: string;\n\tcompilerVersion: string;\n\tgeneratorDigests: Record<string, string>;\n\tchecks: ConformanceEvidence[];\n\tpassed: boolean;\n}\n\n// ── Plan ────────────────────────────────────────────────────────────────────\n\nexport interface PlannedAction {\n\tactionId: string;\n\tversion: number;\n\tmutatesDomain: boolean;\n\tidempotent: boolean;\n\tidempotency?: \"required\" | \"supported\" | \"prohibited\";\n\tauthorityMoment?: \"capture\" | \"execution\" | \"both\";\n\tconnectivity?: \"online-required\" | \"offline-capturable\";\n\tconsistency?: \"authoritative-now\" | \"provisional-until-reconciled\";\n}\n\nexport interface PlannedView {\n\tname: string;\n\tversion: string;\n\tconsumes: Array<{ eventType: string; schemaVersions: number[] }>;\n}\n\nexport interface ModuleConformancePlan {\n\tformatVersion: 1;\n\tmodule: string;\n\tmanifestDigest: string;\n\trequiredChecks: readonly ModuleConformanceCheckId[];\n\tplatformChecks: readonly PlatformConformanceCheckId[];\n\tactions: PlannedAction[];\n\tviews: PlannedView[];\n\teventTypes: Array<{ eventType: string; schemaVersion: number }>;\n}\n\n// ── Harness contract ────────────────────────────────────────────────────────\n\nexport interface ConformanceScope { tenantId: string; spaceId: string; actorId: string; actorType: string }\n\nexport interface ConformanceSubmitInput {\n\tactionId: string;\n\tparameters: Record<string, unknown>;\n\tidempotencyKey?: string;\n\tcorrelationId?: string;\n\tprovenance?: { source: string; correlationId: string; auditAttributes?: Record<string, string> };\n\t/**\n\t * Declares only the intent of the binding. The harness completes tenant, actor,\n\t * action and parameter-digest identity, because only it knows the command shape.\n\t */\n\tauthorizationBinding?: { governingMoment: \"capture\" | \"execution\" | \"both\"; capturedAt?: string; expiresAt?: string };\n\texecutionReason?: \"initial\" | \"offline_replay\";\n}\n\nexport interface ConformanceSubmitResult {\n\tactionInvocationId: string;\n\tstatus: string;\n\treconciliation?: { kind: string };\n}\n\nexport interface ConformanceEventEnvelope {\n\teventType: string;\n\tcorrelationId?: string;\n\tactionInvocationId?: string;\n\ttenantId?: string;\n\tspaceId?: string;\n\tsubjectType?: string;\n\tsubjectId?: string;\n\tsequence?: number;\n\t[key: string]: unknown;\n}\n\n/**\n * What an application supplies so its module's generated suite can run. Structural\n * by design: any store or host that satisfies it is a valid subject.\n */\nexport interface ConformanceHarness {\n\tscope: ConformanceScope;\n\t/** Representative parameters for an action; the module owns its own fixtures. */\n\tparameters(actionId: string): Record<string, unknown>;\n\tsubmit(input: ConformanceSubmitInput): Promise<ConformanceSubmitResult>;\n\tevents(): Promise<ConformanceEventEnvelope[]>;\n\t/** Withdraw execution-time authority so a replay must be refused. */\n\trevokeAuthority(actionId: string): Promise<void>;\n\t/**\n\t * Observable effects an action has produced so far — events appended, rows written,\n\t * whatever the application counts. Supply it and the idempotency checks prove the\n\t * handler did not run twice, rather than only that the same identifier came back.\n\t */\n\tsideEffects?(actionId: string): Promise<number>;\n\t/**\n\t * Hand a real emitted envelope to a real consumer. Supply it and the\n\t * tolerant-envelope check stops being producer-side only: it proves a consumer\n\t * survives fields it does not recognise, which is what tolerance means.\n\t */\n\tacceptsEnvelope?(envelope: ConformanceEventEnvelope): Promise<boolean> | boolean;\n}\n\nexport type ConformanceOutcome =\n\t| { status: \"passed\"; evidence: string[] }\n\t| { status: \"not-applicable\"; reason: string };\n\nexport interface ConformanceCheck {\n\tid: ModuleConformanceCheckId;\n\ttitle: string;\n\trun(harness: ConformanceHarness, plan: ModuleConformancePlan): Promise<ConformanceOutcome>;\n}\n\nclass ConformanceFailure extends Error {\n\toverride readonly name = \"ConformanceFailure\";\n}\n\nfunction expect(condition: unknown, message: string): asserts condition {\n\tif (!condition) throw new ConformanceFailure(message);\n}\n\nconst idempotentActions = (plan: ModuleConformancePlan): PlannedAction[] =>\n\tplan.actions.filter((action) => action.idempotency !== \"prohibited\" && action.idempotent);\n\nconst key = (label: string, action: PlannedAction): string => `conformance:${label}:${action.actionId}`;\n\nconst conflictReason = (conflict: { code?: string; message: string }): string => conflict.code ?? conflict.message;\n\nasync function conflictOf(run: () => Promise<unknown>): Promise<{ thrown: boolean; code?: string; message: string }> {\n\ttry {\n\t\tawait run();\n\t\treturn { thrown: false, message: \"\" };\n\t} catch (error) {\n\t\tconst code = (error as { code?: string }).code;\n\t\treturn { thrown: true, ...(code ? { code } : {}), message: error instanceof Error ? error.message : String(error) };\n\t}\n}\n\n/**\n * Runs a check against every eligible action, not just the first. A module whose\n * first action conforms and whose second does not must fail, or certification\n * means nothing for the rest of the module.\n */\nasync function forEachAction(\n\tactions: PlannedAction[],\n\treason: string,\n\tbody: (action: PlannedAction) => Promise<string[]>,\n): Promise<ConformanceOutcome> {\n\tif (actions.length === 0) return { status: \"not-applicable\", reason };\n\tconst evidence: string[] = [];\n\tfor (const action of actions) evidence.push(...await body(action));\n\treturn { status: \"passed\", evidence };\n}\n\nexport function moduleConformanceChecks(): ConformanceCheck[] {\n\treturn [\n\t\t{\n\t\t\tid: \"fabric.idempotency.same-command-replay.v1\",\n\t\t\ttitle: \"replaying one command key with the same payload does not re-execute\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst input = { actionId: action.actionId, parameters: harness.parameters(action.actionId), idempotencyKey: key(\"replay\", action) };\n\t\t\t\tconst first = await harness.submit(input);\n\t\t\t\tconst before = await harness.sideEffects?.(action.actionId);\n\t\t\t\tconst second = await harness.submit(input);\n\t\t\t\texpect(first.actionInvocationId === second.actionInvocationId, `replay of ${action.actionId} produced a second invocation ${second.actionInvocationId} for key ${input.idempotencyKey}`);\n\t\t\t\tconst after = await harness.sideEffects?.(action.actionId);\n\t\t\t\tif (before !== undefined && after !== undefined) {\n\t\t\t\t\texpect(after === before, `replay of ${action.actionId} returned the original invocation but produced ${after - before} further effects; the handler ran again`);\n\t\t\t\t}\n\t\t\t\treturn [`invocation:${first.actionInvocationId}`, `key:${input.idempotencyKey}`, `effects:${after ?? \"unobserved\"}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.idempotency.conflicting-payload.v1\",\n\t\t\ttitle: \"reusing a command key with an altered payload is refused\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst idempotencyKey = key(\"conflict\", action);\n\t\t\t\tconst parameters = harness.parameters(action.actionId);\n\t\t\t\tawait harness.submit({ actionId: action.actionId, parameters, idempotencyKey });\n\t\t\t\tconst conflict = await conflictOf(() => harness.submit({\n\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\tparameters: { ...parameters, \"x-conformance-altered\": true },\n\t\t\t\t\tidempotencyKey,\n\t\t\t\t}));\n\t\t\t\texpect(conflict.thrown, `altered payload reusing key ${idempotencyKey} was accepted instead of refused`);\n\t\t\t\texpect(\n\t\t\t\t\tconflict.code === \"IDEMPOTENCY_CONFLICT\" || /idempotenc/i.test(conflict.message),\n\t\t\t\t\t`altered payload for ${action.actionId} was refused, but not as an idempotency conflict: ${conflict.message}`,\n\t\t\t\t);\n\t\t\t\treturn [`key:${idempotencyKey}`, `refusal:${conflictReason(conflict)}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.idempotency.concurrent-submission.v1\",\n\t\t\ttitle: \"concurrent identical submissions collapse to one invocation\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst input = { actionId: action.actionId, parameters: harness.parameters(action.actionId), idempotencyKey: key(\"concurrent\", action) };\n\t\t\t\tconst before = await harness.sideEffects?.(action.actionId);\n\t\t\t\tconst results = await Promise.all([harness.submit(input), harness.submit(input), harness.submit(input)]);\n\t\t\t\tconst ids = new Set(results.map((result) => result.actionInvocationId));\n\t\t\t\texpect(ids.size === 1, `concurrent submissions of ${action.actionId} produced ${ids.size} invocations: ${[...ids].join(\", \")}`);\n\t\t\t\tconst after = await harness.sideEffects?.(action.actionId);\n\t\t\t\tif (before !== undefined && after !== undefined) {\n\t\t\t\t\tconst executions = after - before;\n\t\t\t\t\texpect(executions <= 1, `${results.length} concurrent submissions of ${action.actionId} collapsed to one invocation but produced ${executions} executions' worth of effects`);\n\t\t\t\t}\n\t\t\t\treturn [`invocation:${[...ids][0]}`, `attempts:${results.length}`, `effects:${after ?? \"unobserved\"}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.authorization.governing-moment.v1\",\n\t\t\ttitle: \"an authorization binding must match the action's declared governing moment\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.authorityMoment !== undefined),\n\t\t\t\t\"module declares no action with an authority moment\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst mismatched = action.authorityMoment === \"capture\" ? \"execution\" : \"capture\";\n\t\t\t\t\tconst rejection = await conflictOf(() => harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tauthorizationBinding: { governingMoment: mismatched, capturedAt: new Date(Date.now() - 60_000).toISOString() },\n\t\t\t\t\t}));\n\t\t\t\t\texpect(rejection.thrown, `a binding declaring governingMoment \"${mismatched}\" was accepted for ${action.actionId}, governed at \"${action.authorityMoment}\"`);\n\t\t\t\t\texpect(\n\t\t\t\t\t\t/governingmoment|governing moment/i.test(conflictReason(rejection)),\n\t\t\t\t\t\t`the binding for ${action.actionId} was refused, but not for its governing moment: ${conflictReason(rejection)}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn [`action:${action.actionId}`, `declared:${action.authorityMoment}`, `refused:${mismatched}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.authorization.offline-replay.v1\",\n\t\t\ttitle: \"an offline capture replayed after authority is withdrawn is refused into reconciliation\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) =>\n\t\t\t\t\taction.connectivity === \"offline-capturable\" && action.authorityMoment !== undefined && action.authorityMoment !== \"capture\"),\n\t\t\t\t\"module declares no offline-capturable action governed at execution\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tawait harness.revokeAuthority(action.actionId);\n\t\t\t\t\tconst replay = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tidempotencyKey: key(\"offline-replay\", action),\n\t\t\t\t\t\texecutionReason: \"offline_replay\",\n\t\t\t\t\t});\n\t\t\t\t\texpect(\n\t\t\t\t\t\treplay.status === \"reconciliation_required\",\n\t\t\t\t\t\t`replay of ${action.actionId} after authority withdrawal returned status \"${replay.status}\" instead of reconciliation_required`,\n\t\t\t\t\t);\n\t\t\t\t\texpect(replay.reconciliation !== undefined, `reconciliation_required was returned for ${action.actionId} without a reconciliation outcome`);\n\t\t\t\t\treturn [`action:${action.actionId}`, `reconciliation:${replay.reconciliation?.kind}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.events.compatibility.v1\",\n\t\t\ttitle: \"every consumed event version is one the module still declares\",\n\t\t\tasync run(_harness, plan) {\n\t\t\t\tif (plan.views.length === 0) return { status: \"not-applicable\", reason: \"module declares no views\" };\n\t\t\t\tconst declared = new Map(plan.eventTypes.map((event) => [event.eventType, event.schemaVersion]));\n\t\t\t\tconst evidence: string[] = [];\n\t\t\t\tfor (const view of plan.views) {\n\t\t\t\t\tfor (const consumption of view.consumes) {\n\t\t\t\t\t\tconst current = declared.get(consumption.eventType);\n\t\t\t\t\t\tif (current === undefined) continue;\n\t\t\t\t\t\texpect(\n\t\t\t\t\t\t\tconsumption.schemaVersions.includes(current),\n\t\t\t\t\t\t\t`view ${view.name}@${view.version} consumes ${consumption.eventType} at [${consumption.schemaVersions.join(\", \")}] but the module now emits version ${current}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tevidence.push(`${view.name}@${view.version}:${consumption.eventType}=${current}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (evidence.length === 0) return { status: \"not-applicable\", reason: \"no view consumes an event this module declares\" };\n\t\t\t\treturn { status: \"passed\", evidence };\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.provenance.propagation.v1\",\n\t\t\ttitle: \"submission provenance reaches the events the action emits\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.mutatesDomain),\n\t\t\t\t\"module declares no domain-mutating action\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst correlationId = `conformance-corr-${action.actionId}`;\n\t\t\t\t\tconst submitted = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tcorrelationId,\n\t\t\t\t\t\t// Audit attributes are allowlisted per application, so provenance identity is asserted on correlation alone.\n\t\t\t\t\t\tprovenance: { source: \"system\", correlationId },\n\t\t\t\t\t});\n\t\t\t\t\tconst emitted = (await harness.events()).filter((event) => event.actionInvocationId === submitted.actionInvocationId);\n\t\t\t\t\texpect(emitted.length > 0, `action ${action.actionId} mutates domain but emitted no events`);\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\texpect(event.correlationId === correlationId, `event ${event.eventType} carried correlationId ${String(event.correlationId)} instead of ${correlationId}`);\n\t\t\t\t\t}\n\t\t\t\t\treturn [`invocation:${submitted.actionInvocationId}`, `events:${emitted.length}`, `correlationId:${correlationId}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.consumers.tolerant-envelope.v1\",\n\t\t\ttitle: \"emitted envelopes are complete, and a consumer tolerates fields it does not know\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.mutatesDomain),\n\t\t\t\t\"module declares no domain-mutating action\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst submitted = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tidempotencyKey: key(\"envelope\", action),\n\t\t\t\t\t});\n\t\t\t\t\tconst emitted = (await harness.events()).filter((event) => event.actionInvocationId === submitted.actionInvocationId);\n\t\t\t\t\texpect(emitted.length > 0, `action ${action.actionId} mutates domain but emitted no events`);\n\t\t\t\t\tconst required = [\"eventType\", \"tenantId\", \"spaceId\", \"subjectType\", \"subjectId\", \"sequence\", \"correlationId\"] as const;\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\tfor (const field of required) {\n\t\t\t\t\t\t\texpect(event[field] !== undefined && event[field] !== null, `event ${event.eventType} omits the canonical envelope field \"${field}\"`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst evidence = emitted.map((event) => `${event.eventType}@${event.sequence}`);\n\t\t\t\t\tif (!harness.acceptsEnvelope) return [...evidence, \"consumer:unobserved\"];\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\t// Additive fields are exactly what a future schema version introduces.\n\t\t\t\t\t\tconst extended = { ...event, \"x-conformance-unknown\": true, consistency: \"provisional-until-reconciled\" };\n\t\t\t\t\t\tconst accepted = await harness.acceptsEnvelope(extended);\n\t\t\t\t\t\texpect(accepted, `a consumer rejected ${event.eventType} once it carried a field it did not recognise; additive event changes would break it`);\n\t\t\t\t\t}\n\t\t\t\t\treturn [...evidence, `consumer:tolerated:${emitted.length}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t];\n}\n\n// ── Certification evidence ──────────────────────────────────────────────────\n\nexport function createCertificationResult(input: Omit<CertificationResult, \"formatVersion\" | \"passed\">): CertificationResult {\n\tconst results = new Map(input.checks.map((check) => [check.id, check]));\n\tif (results.size !== input.checks.length) throw new Error(\"Certification evidence contains duplicate check identifiers.\");\n\tconst missing = PHASE_1_CONFORMANCE_CHECKS.filter((id) => !results.has(id));\n\tif (missing.length) throw new Error(`Certification evidence is missing mandatory checks: ${missing.join(\", \")}`);\n\tif (!/^[0-9a-f]{64}$/.test(input.manifestDigest)) throw new Error(\"Certification manifestDigest must be a lowercase SHA-256 digest.\");\n\tconst generatorDigests = Object.entries(input.generatorDigests);\n\tif (!generatorDigests.length || generatorDigests.some(([, digest]) => !/^[0-9a-f]{64}$/.test(digest))) throw new Error(\"Certification generatorDigests must contain SHA-256 evidence.\");\n\tif (input.checks.some((check) => check.status === \"passed\" && check.evidence.length === 0)) throw new Error(\"Passed certification checks require evidence references.\");\n\treturn { ...input, formatVersion: 1, checks: [...input.checks].sort((a, b) => a.id.localeCompare(b.id)), passed: input.checks.every((check) => check.status === \"passed\") };\n}\n\n// ── Generator ───────────────────────────────────────────────────────────────\n\nexport function buildModuleConformancePlan(module: ModuleManifest, manifestDigest: string): ModuleConformancePlan {\n\treturn {\n\t\tformatVersion: 1,\n\t\tmodule: module.namespace,\n\t\tmanifestDigest,\n\t\trequiredChecks: MODULE_CONFORMANCE_CHECKS,\n\t\tplatformChecks: PLATFORM_CONFORMANCE_CHECKS,\n\t\tactions: module.actions.map((action) => ({\n\t\t\tactionId: action.actionId,\n\t\t\tversion: action.version,\n\t\t\tmutatesDomain: action.mutatesDomain,\n\t\t\tidempotent: action.idempotent,\n\t\t\t...(action.execution?.idempotency ? { idempotency: action.execution.idempotency } : {}),\n\t\t\t...(action.execution?.authorityMoment ? { authorityMoment: action.execution.authorityMoment } : {}),\n\t\t\t...(action.execution?.connectivity ? { connectivity: action.execution.connectivity } : {}),\n\t\t\t...(action.execution?.consistency ? { consistency: action.execution.consistency } : {}),\n\t\t})),\n\t\tviews: module.views.map((view) => ({\n\t\t\tname: view.name,\n\t\t\tversion: view.version,\n\t\t\tconsumes: view.consumes.map((consumption) => ({ eventType: consumption.eventType, schemaVersions: [...consumption.schemaVersions] })),\n\t\t})),\n\t\teventTypes: module.eventTypes.map((event) => ({ eventType: event.eventType, schemaVersion: event.schemaVersion })),\n\t};\n}\n\nfunction suiteSource(plan: ModuleConformancePlan, generator: { name: string; version: string }): string {\n\treturn [\n\t\t`// Generated by ${generator.name}@${generator.version}. Do not edit.`,\n\t\t`// Manifest digest: ${plan.manifestDigest}`,\n\t\t`// Supply ./conformance.harness with a createConformanceHarness() factory returning a fresh, isolated harness.`,\n\t\t'import { expect, it } from \"vitest\";',\n\t\t'import { moduleConformanceChecks, type ModuleConformancePlan } from \"@fabricorg/gen-conformance\";',\n\t\t'import { createConformanceHarness } from \"./conformance.harness\";',\n\t\t\"\",\n\t\t`export const plan: ModuleConformancePlan = ${JSON.stringify(plan, null, 2)};`,\n\t\t\"\",\n\t\t\"for (const check of moduleConformanceChecks()) {\",\n\t\t\" it(`${check.id} — ${check.title}`, async () => {\",\n\t\t\" const outcome = await check.run(await createConformanceHarness(), plan);\",\n\t\t' expect([\"passed\", \"not-applicable\"]).toContain(outcome.status);',\n\t\t\" });\",\n\t\t\"}\",\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\nexport const conformanceGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-conformance\",\n\tversion: \"0.2.0\",\n\tgenerate(ir: FabricCompilerIr) {\n\t\treturn ir.modules.flatMap((module) => {\n\t\t\tconst plan = buildModuleConformancePlan(module, ir.manifestDigest);\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tpath: `${module.namespace}/conformance-plan.json`,\n\t\t\t\t\tcontent: stableStringify({\n\t\t\t\t\t\t...plan,\n\t\t\t\t\t\tgenerator: { name: conformanceGenerator.name, version: conformanceGenerator.version },\n\t\t\t\t\t\tcompilerVersion: ir.compilerVersion,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: `${module.namespace}/conformance.test.ts`,\n\t\t\t\t\tcontent: suiteSource(plan, { name: conformanceGenerator.name, version: conformanceGenerator.version }),\n\t\t\t\t},\n\t\t\t];\n\t\t});\n\t},\n};\n"],"mappings":"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","names":["module"]}
1
+ {"version":3,"sources":["../index.ts"],"sourcesContent":["import { stableStringify, type FabricCompilerIr, type GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { ModuleManifest } from \"@fabricorg/platform\";\n\n/** Checks a single module's own behaviour, verifiable against a governed host. */\nexport const MODULE_CONFORMANCE_CHECKS = [\n\t\"fabric.idempotency.same-command-replay.v1\",\n\t\"fabric.idempotency.conflicting-payload.v1\",\n\t\"fabric.idempotency.concurrent-submission.v1\",\n\t\"fabric.authorization.governing-moment.v1\",\n\t\"fabric.authorization.offline-replay.v1\",\n\t\"fabric.events.compatibility.v1\",\n\t\"fabric.provenance.propagation.v1\",\n\t\"fabric.consumers.tolerant-envelope.v1\",\n] as const;\n\n/**\n * Checks that belong to a repository rather than a module. They are certification\n * evidence like any other check, but no per-module suite can produce them.\n */\nexport const PLATFORM_CONFORMANCE_CHECKS = [\n\t\"fabric.documentation.parity.v1\",\n\t\"fabric.documentation.llms-contract.v1\",\n] as const;\n\nexport const PHASE_1_CONFORMANCE_CHECKS = [...MODULE_CONFORMANCE_CHECKS, ...PLATFORM_CONFORMANCE_CHECKS] as const;\n\nexport type ModuleConformanceCheckId = typeof MODULE_CONFORMANCE_CHECKS[number];\nexport type PlatformConformanceCheckId = typeof PLATFORM_CONFORMANCE_CHECKS[number];\nexport type Phase1ConformanceCheckId = ModuleConformanceCheckId | PlatformConformanceCheckId;\n\nexport interface ConformanceEvidence { id: Phase1ConformanceCheckId; status: \"passed\" | \"failed\"; evidence: string[] }\n\nexport interface CertificationResult {\n\tformatVersion: 1;\n\tmanifestDigest: string;\n\tcompilerVersion: string;\n\tgeneratorDigests: Record<string, string>;\n\tchecks: ConformanceEvidence[];\n\tpassed: boolean;\n}\n\n// ── Plan ────────────────────────────────────────────────────────────────────\n\nexport interface PlannedAction {\n\tactionId: string;\n\tversion: number;\n\tmutatesDomain: boolean;\n\tidempotent: boolean;\n\tidempotency?: \"required\" | \"supported\" | \"prohibited\";\n\tauthorityMoment?: \"capture\" | \"execution\" | \"both\";\n\tconnectivity?: \"online-required\" | \"offline-capturable\";\n\tconsistency?: \"authoritative-now\" | \"provisional-until-reconciled\";\n}\n\nexport interface PlannedView {\n\tname: string;\n\tversion: string;\n\tparameterSchema?: ModuleManifest[\"views\"][number][\"parameterSchema\"];\n\tconsumes: Array<{ eventType: string; schemaVersions: number[] }>;\n}\n\nexport interface ModuleConformancePlan {\n\tformatVersion: 1;\n\tmodule: string;\n\tmanifestDigest: string;\n\trequiredChecks: readonly ModuleConformanceCheckId[];\n\tplatformChecks: readonly PlatformConformanceCheckId[];\n\tactions: PlannedAction[];\n\tviews: PlannedView[];\n\teventTypes: Array<{ eventType: string; schemaVersion: number }>;\n}\n\n// ── Harness contract ────────────────────────────────────────────────────────\n\nexport interface ConformanceScope { tenantId: string; spaceId: string; actorId: string; actorType: string }\n\nexport interface ConformanceSubmitInput {\n\tactionId: string;\n\tparameters: Record<string, unknown>;\n\tidempotencyKey?: string;\n\tcorrelationId?: string;\n\tprovenance?: { source: string; correlationId: string; auditAttributes?: Record<string, string> };\n\t/**\n\t * Declares only the intent of the binding. The harness completes tenant, actor,\n\t * action and parameter-digest identity, because only it knows the command shape.\n\t */\n\tauthorizationBinding?: { governingMoment: \"capture\" | \"execution\" | \"both\"; capturedAt?: string; expiresAt?: string };\n\texecutionReason?: \"initial\" | \"offline_replay\";\n}\n\nexport interface ConformanceSubmitResult {\n\tactionInvocationId: string;\n\tstatus: string;\n\treconciliation?: { kind: string };\n}\n\nexport interface ConformanceEventEnvelope {\n\teventType: string;\n\tcorrelationId?: string;\n\tactionInvocationId?: string;\n\ttenantId?: string;\n\tspaceId?: string;\n\tsubjectType?: string;\n\tsubjectId?: string;\n\tsequence?: number;\n\t[key: string]: unknown;\n}\n\n/**\n * What an application supplies so its module's generated suite can run. Structural\n * by design: any store or host that satisfies it is a valid subject.\n */\nexport interface ConformanceHarness {\n\tscope: ConformanceScope;\n\t/** Representative parameters for an action; the module owns its own fixtures. */\n\tparameters(actionId: string): Record<string, unknown>;\n\tsubmit(input: ConformanceSubmitInput): Promise<ConformanceSubmitResult>;\n\tevents(): Promise<ConformanceEventEnvelope[]>;\n\t/** Withdraw execution-time authority so a replay must be refused. */\n\trevokeAuthority(actionId: string): Promise<void>;\n\t/**\n\t * Observable effects an action has produced so far — events appended, rows written,\n\t * whatever the application counts. Supply it and the idempotency checks prove the\n\t * handler did not run twice, rather than only that the same identifier came back.\n\t */\n\tsideEffects?(actionId: string): Promise<number>;\n\t/**\n\t * Hand a real emitted envelope to a real consumer. Supply it and the\n\t * tolerant-envelope check stops being producer-side only: it proves a consumer\n\t * survives fields it does not recognise, which is what tolerance means.\n\t */\n\tacceptsEnvelope?(envelope: ConformanceEventEnvelope): Promise<boolean> | boolean;\n}\n\nexport type ConformanceOutcome =\n\t| { status: \"passed\"; evidence: string[] }\n\t| { status: \"not-applicable\"; reason: string };\n\nexport interface ConformanceCheck {\n\tid: ModuleConformanceCheckId;\n\ttitle: string;\n\trun(harness: ConformanceHarness, plan: ModuleConformancePlan): Promise<ConformanceOutcome>;\n}\n\nclass ConformanceFailure extends Error {\n\toverride readonly name = \"ConformanceFailure\";\n}\n\nfunction expect(condition: unknown, message: string): asserts condition {\n\tif (!condition) throw new ConformanceFailure(message);\n}\n\nconst idempotentActions = (plan: ModuleConformancePlan): PlannedAction[] =>\n\tplan.actions.filter((action) => action.idempotency !== \"prohibited\" && action.idempotent);\n\nconst key = (label: string, action: PlannedAction): string => `conformance:${label}:${action.actionId}`;\n\nconst conflictReason = (conflict: { code?: string; message: string }): string => conflict.code ?? conflict.message;\n\nasync function conflictOf(run: () => Promise<unknown>): Promise<{ thrown: boolean; code?: string; message: string }> {\n\ttry {\n\t\tawait run();\n\t\treturn { thrown: false, message: \"\" };\n\t} catch (error) {\n\t\tconst code = (error as { code?: string }).code;\n\t\treturn { thrown: true, ...(code ? { code } : {}), message: error instanceof Error ? error.message : String(error) };\n\t}\n}\n\n/**\n * Runs a check against every eligible action, not just the first. A module whose\n * first action conforms and whose second does not must fail, or certification\n * means nothing for the rest of the module.\n */\nasync function forEachAction(\n\tactions: PlannedAction[],\n\treason: string,\n\tbody: (action: PlannedAction) => Promise<string[]>,\n): Promise<ConformanceOutcome> {\n\tif (actions.length === 0) return { status: \"not-applicable\", reason };\n\tconst evidence: string[] = [];\n\tfor (const action of actions) evidence.push(...await body(action));\n\treturn { status: \"passed\", evidence };\n}\n\nexport function moduleConformanceChecks(): ConformanceCheck[] {\n\treturn [\n\t\t{\n\t\t\tid: \"fabric.idempotency.same-command-replay.v1\",\n\t\t\ttitle: \"replaying one command key with the same payload does not re-execute\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst input = { actionId: action.actionId, parameters: harness.parameters(action.actionId), idempotencyKey: key(\"replay\", action) };\n\t\t\t\tconst first = await harness.submit(input);\n\t\t\t\tconst before = await harness.sideEffects?.(action.actionId);\n\t\t\t\tconst second = await harness.submit(input);\n\t\t\t\texpect(first.actionInvocationId === second.actionInvocationId, `replay of ${action.actionId} produced a second invocation ${second.actionInvocationId} for key ${input.idempotencyKey}`);\n\t\t\t\tconst after = await harness.sideEffects?.(action.actionId);\n\t\t\t\tif (before !== undefined && after !== undefined) {\n\t\t\t\t\texpect(after === before, `replay of ${action.actionId} returned the original invocation but produced ${after - before} further effects; the handler ran again`);\n\t\t\t\t}\n\t\t\t\treturn [`invocation:${first.actionInvocationId}`, `key:${input.idempotencyKey}`, `effects:${after ?? \"unobserved\"}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.idempotency.conflicting-payload.v1\",\n\t\t\ttitle: \"reusing a command key with an altered payload is refused\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst idempotencyKey = key(\"conflict\", action);\n\t\t\t\tconst parameters = harness.parameters(action.actionId);\n\t\t\t\tawait harness.submit({ actionId: action.actionId, parameters, idempotencyKey });\n\t\t\t\tconst conflict = await conflictOf(() => harness.submit({\n\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\tparameters: { ...parameters, \"x-conformance-altered\": true },\n\t\t\t\t\tidempotencyKey,\n\t\t\t\t}));\n\t\t\t\texpect(conflict.thrown, `altered payload reusing key ${idempotencyKey} was accepted instead of refused`);\n\t\t\t\texpect(\n\t\t\t\t\tconflict.code === \"IDEMPOTENCY_CONFLICT\" || /idempotenc/i.test(conflict.message),\n\t\t\t\t\t`altered payload for ${action.actionId} was refused, but not as an idempotency conflict: ${conflict.message}`,\n\t\t\t\t);\n\t\t\t\treturn [`key:${idempotencyKey}`, `refusal:${conflictReason(conflict)}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.idempotency.concurrent-submission.v1\",\n\t\t\ttitle: \"concurrent identical submissions collapse to one invocation\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst input = { actionId: action.actionId, parameters: harness.parameters(action.actionId), idempotencyKey: key(\"concurrent\", action) };\n\t\t\t\tconst before = await harness.sideEffects?.(action.actionId);\n\t\t\t\tconst results = await Promise.all([harness.submit(input), harness.submit(input), harness.submit(input)]);\n\t\t\t\tconst ids = new Set(results.map((result) => result.actionInvocationId));\n\t\t\t\texpect(ids.size === 1, `concurrent submissions of ${action.actionId} produced ${ids.size} invocations: ${[...ids].join(\", \")}`);\n\t\t\t\tconst after = await harness.sideEffects?.(action.actionId);\n\t\t\t\tif (before !== undefined && after !== undefined) {\n\t\t\t\t\tconst executions = after - before;\n\t\t\t\t\texpect(executions <= 1, `${results.length} concurrent submissions of ${action.actionId} collapsed to one invocation but produced ${executions} executions' worth of effects`);\n\t\t\t\t}\n\t\t\t\treturn [`invocation:${[...ids][0]}`, `attempts:${results.length}`, `effects:${after ?? \"unobserved\"}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.authorization.governing-moment.v1\",\n\t\t\ttitle: \"an authorization binding must match the action's declared governing moment\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.authorityMoment !== undefined),\n\t\t\t\t\"module declares no action with an authority moment\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst mismatched = action.authorityMoment === \"capture\" ? \"execution\" : \"capture\";\n\t\t\t\t\tconst rejection = await conflictOf(() => harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tauthorizationBinding: { governingMoment: mismatched, capturedAt: new Date(Date.now() - 60_000).toISOString() },\n\t\t\t\t\t}));\n\t\t\t\t\texpect(rejection.thrown, `a binding declaring governingMoment \"${mismatched}\" was accepted for ${action.actionId}, governed at \"${action.authorityMoment}\"`);\n\t\t\t\t\texpect(\n\t\t\t\t\t\t/governingmoment|governing moment/i.test(conflictReason(rejection)),\n\t\t\t\t\t\t`the binding for ${action.actionId} was refused, but not for its governing moment: ${conflictReason(rejection)}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn [`action:${action.actionId}`, `declared:${action.authorityMoment}`, `refused:${mismatched}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.authorization.offline-replay.v1\",\n\t\t\ttitle: \"an offline capture replayed after authority is withdrawn is refused into reconciliation\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) =>\n\t\t\t\t\taction.connectivity === \"offline-capturable\" && action.authorityMoment !== undefined && action.authorityMoment !== \"capture\"),\n\t\t\t\t\"module declares no offline-capturable action governed at execution\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tawait harness.revokeAuthority(action.actionId);\n\t\t\t\t\tconst replay = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tidempotencyKey: key(\"offline-replay\", action),\n\t\t\t\t\t\texecutionReason: \"offline_replay\",\n\t\t\t\t\t});\n\t\t\t\t\texpect(\n\t\t\t\t\t\treplay.status === \"reconciliation_required\",\n\t\t\t\t\t\t`replay of ${action.actionId} after authority withdrawal returned status \"${replay.status}\" instead of reconciliation_required`,\n\t\t\t\t\t);\n\t\t\t\t\texpect(replay.reconciliation !== undefined, `reconciliation_required was returned for ${action.actionId} without a reconciliation outcome`);\n\t\t\t\t\treturn [`action:${action.actionId}`, `reconciliation:${replay.reconciliation?.kind}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.events.compatibility.v1\",\n\t\t\ttitle: \"every consumed event version is one the module still declares\",\n\t\t\tasync run(_harness, plan) {\n\t\t\t\tif (plan.views.length === 0) return { status: \"not-applicable\", reason: \"module declares no views\" };\n\t\t\t\tconst declared = new Map(plan.eventTypes.map((event) => [event.eventType, event.schemaVersion]));\n\t\t\t\tconst evidence: string[] = [];\n\t\t\t\tfor (const view of plan.views) {\n\t\t\t\t\tfor (const consumption of view.consumes) {\n\t\t\t\t\t\tconst current = declared.get(consumption.eventType);\n\t\t\t\t\t\tif (current === undefined) continue;\n\t\t\t\t\t\texpect(\n\t\t\t\t\t\t\tconsumption.schemaVersions.includes(current),\n\t\t\t\t\t\t\t`view ${view.name}@${view.version} consumes ${consumption.eventType} at [${consumption.schemaVersions.join(\", \")}] but the module now emits version ${current}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tevidence.push(`${view.name}@${view.version}:${consumption.eventType}=${current}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (evidence.length === 0) return { status: \"not-applicable\", reason: \"no view consumes an event this module declares\" };\n\t\t\t\treturn { status: \"passed\", evidence };\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.provenance.propagation.v1\",\n\t\t\ttitle: \"submission provenance reaches the events the action emits\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.mutatesDomain),\n\t\t\t\t\"module declares no domain-mutating action\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst correlationId = `conformance-corr-${action.actionId}`;\n\t\t\t\t\tconst submitted = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tcorrelationId,\n\t\t\t\t\t\t// Audit attributes are allowlisted per application, so provenance identity is asserted on correlation alone.\n\t\t\t\t\t\tprovenance: { source: \"system\", correlationId },\n\t\t\t\t\t});\n\t\t\t\t\tconst emitted = (await harness.events()).filter((event) => event.actionInvocationId === submitted.actionInvocationId);\n\t\t\t\t\texpect(emitted.length > 0, `action ${action.actionId} mutates domain but emitted no events`);\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\texpect(event.correlationId === correlationId, `event ${event.eventType} carried correlationId ${String(event.correlationId)} instead of ${correlationId}`);\n\t\t\t\t\t}\n\t\t\t\t\treturn [`invocation:${submitted.actionInvocationId}`, `events:${emitted.length}`, `correlationId:${correlationId}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.consumers.tolerant-envelope.v1\",\n\t\t\ttitle: \"emitted envelopes are complete, and a consumer tolerates fields it does not know\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.mutatesDomain),\n\t\t\t\t\"module declares no domain-mutating action\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst submitted = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tidempotencyKey: key(\"envelope\", action),\n\t\t\t\t\t});\n\t\t\t\t\tconst emitted = (await harness.events()).filter((event) => event.actionInvocationId === submitted.actionInvocationId);\n\t\t\t\t\texpect(emitted.length > 0, `action ${action.actionId} mutates domain but emitted no events`);\n\t\t\t\t\tconst required = [\"eventType\", \"tenantId\", \"spaceId\", \"subjectType\", \"subjectId\", \"sequence\", \"correlationId\"] as const;\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\tfor (const field of required) {\n\t\t\t\t\t\t\texpect(event[field] !== undefined && event[field] !== null, `event ${event.eventType} omits the canonical envelope field \"${field}\"`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst evidence = emitted.map((event) => `${event.eventType}@${event.sequence}`);\n\t\t\t\t\tif (!harness.acceptsEnvelope) return [...evidence, \"consumer:unobserved\"];\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\t// Additive fields are exactly what a future schema version introduces.\n\t\t\t\t\t\tconst extended = { ...event, \"x-conformance-unknown\": true, consistency: \"provisional-until-reconciled\" };\n\t\t\t\t\t\tconst accepted = await harness.acceptsEnvelope(extended);\n\t\t\t\t\t\texpect(accepted, `a consumer rejected ${event.eventType} once it carried a field it did not recognise; additive event changes would break it`);\n\t\t\t\t\t}\n\t\t\t\t\treturn [...evidence, `consumer:tolerated:${emitted.length}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t];\n}\n\n// ── Certification evidence ──────────────────────────────────────────────────\n\nexport function createCertificationResult(input: Omit<CertificationResult, \"formatVersion\" | \"passed\">): CertificationResult {\n\tconst results = new Map(input.checks.map((check) => [check.id, check]));\n\tif (results.size !== input.checks.length) throw new Error(\"Certification evidence contains duplicate check identifiers.\");\n\tconst missing = PHASE_1_CONFORMANCE_CHECKS.filter((id) => !results.has(id));\n\tif (missing.length) throw new Error(`Certification evidence is missing mandatory checks: ${missing.join(\", \")}`);\n\tif (!/^[0-9a-f]{64}$/.test(input.manifestDigest)) throw new Error(\"Certification manifestDigest must be a lowercase SHA-256 digest.\");\n\tconst generatorDigests = Object.entries(input.generatorDigests);\n\tif (!generatorDigests.length || generatorDigests.some(([, digest]) => !/^[0-9a-f]{64}$/.test(digest))) throw new Error(\"Certification generatorDigests must contain SHA-256 evidence.\");\n\tif (input.checks.some((check) => check.status === \"passed\" && check.evidence.length === 0)) throw new Error(\"Passed certification checks require evidence references.\");\n\treturn { ...input, formatVersion: 1, checks: [...input.checks].sort((a, b) => a.id.localeCompare(b.id)), passed: input.checks.every((check) => check.status === \"passed\") };\n}\n\n// ── Generator ───────────────────────────────────────────────────────────────\n\nexport function buildModuleConformancePlan(module: ModuleManifest, manifestDigest: string): ModuleConformancePlan {\n\treturn {\n\t\tformatVersion: 1,\n\t\tmodule: module.namespace,\n\t\tmanifestDigest,\n\t\trequiredChecks: MODULE_CONFORMANCE_CHECKS,\n\t\tplatformChecks: PLATFORM_CONFORMANCE_CHECKS,\n\t\tactions: module.actions.map((action) => ({\n\t\t\tactionId: action.actionId,\n\t\t\tversion: action.version,\n\t\t\tmutatesDomain: action.mutatesDomain,\n\t\t\tidempotent: action.idempotent,\n\t\t\t...(action.execution?.idempotency ? { idempotency: action.execution.idempotency } : {}),\n\t\t\t...(action.execution?.authorityMoment ? { authorityMoment: action.execution.authorityMoment } : {}),\n\t\t\t...(action.execution?.connectivity ? { connectivity: action.execution.connectivity } : {}),\n\t\t\t...(action.execution?.consistency ? { consistency: action.execution.consistency } : {}),\n\t\t})),\n\t\tviews: module.views.map((view) => ({\n\t\t\tname: view.name,\n\t\t\tversion: view.version,\n\t\t\t...(view.parameterSchema ? { parameterSchema: view.parameterSchema } : {}),\n\t\t\tconsumes: view.consumes.map((consumption) => ({ eventType: consumption.eventType, schemaVersions: [...consumption.schemaVersions] })),\n\t\t})),\n\t\teventTypes: module.eventTypes.map((event) => ({ eventType: event.eventType, schemaVersion: event.schemaVersion })),\n\t};\n}\n\nfunction suiteSource(plan: ModuleConformancePlan, generator: { name: string; version: string }): string {\n\treturn [\n\t\t`// Generated by ${generator.name}@${generator.version}. Do not edit.`,\n\t\t`// Manifest digest: ${plan.manifestDigest}`,\n\t\t`// Supply ./conformance.harness with a createConformanceHarness() factory returning a fresh, isolated harness.`,\n\t\t'import { expect, it } from \"vitest\";',\n\t\t'import { moduleConformanceChecks, type ModuleConformancePlan } from \"@fabricorg/gen-conformance\";',\n\t\t'import { createConformanceHarness } from \"./conformance.harness\";',\n\t\t\"\",\n\t\t`export const plan: ModuleConformancePlan = ${JSON.stringify(plan, null, 2)};`,\n\t\t\"\",\n\t\t\"for (const check of moduleConformanceChecks()) {\",\n\t\t\" it(`${check.id} — ${check.title}`, async () => {\",\n\t\t\" const outcome = await check.run(await createConformanceHarness(), plan);\",\n\t\t' expect([\"passed\", \"not-applicable\"]).toContain(outcome.status);',\n\t\t\" });\",\n\t\t\"}\",\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\nexport const conformanceGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-conformance\",\n\tversion: \"0.3.0\",\n\tgenerate(ir: FabricCompilerIr) {\n\t\treturn ir.modules.flatMap((module) => {\n\t\t\tconst plan = buildModuleConformancePlan(module, ir.manifestDigest);\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tpath: `${module.namespace}/conformance-plan.json`,\n\t\t\t\t\tcontent: stableStringify({\n\t\t\t\t\t\t...plan,\n\t\t\t\t\t\tgenerator: { name: conformanceGenerator.name, version: conformanceGenerator.version },\n\t\t\t\t\t\tcompilerVersion: ir.compilerVersion,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: `${module.namespace}/conformance.test.ts`,\n\t\t\t\t\tcontent: suiteSource(plan, { name: conformanceGenerator.name, version: conformanceGenerator.version }),\n\t\t\t\t},\n\t\t\t];\n\t\t});\n\t},\n};\n"],"mappings":"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","names":["module"]}
package/dist/index.d.cts CHANGED
@@ -38,6 +38,7 @@ interface PlannedAction {
38
38
  interface PlannedView {
39
39
  name: string;
40
40
  version: string;
41
+ parameterSchema?: ModuleManifest["views"][number]["parameterSchema"];
41
42
  consumes: Array<{
42
43
  eventType: string;
43
44
  schemaVersions: number[];
package/dist/index.d.ts CHANGED
@@ -38,6 +38,7 @@ interface PlannedAction {
38
38
  interface PlannedView {
39
39
  name: string;
40
40
  version: string;
41
+ parameterSchema?: ModuleManifest["views"][number]["parameterSchema"];
41
42
  consumes: Array<{
42
43
  eventType: string;
43
44
  schemaVersions: number[];
package/dist/index.js CHANGED
@@ -249,6 +249,7 @@ function buildModuleConformancePlan(module, manifestDigest) {
249
249
  views: module.views.map((view) => ({
250
250
  name: view.name,
251
251
  version: view.version,
252
+ ...view.parameterSchema ? { parameterSchema: view.parameterSchema } : {},
252
253
  consumes: view.consumes.map((consumption) => ({ eventType: consumption.eventType, schemaVersions: [...consumption.schemaVersions] }))
253
254
  })),
254
255
  eventTypes: module.eventTypes.map((event) => ({ eventType: event.eventType, schemaVersion: event.schemaVersion }))
@@ -276,7 +277,7 @@ function suiteSource(plan, generator) {
276
277
  }
277
278
  var conformanceGenerator = {
278
279
  name: "@fabricorg/gen-conformance",
279
- version: "0.2.0",
280
+ version: "0.3.0",
280
281
  generate(ir) {
281
282
  return ir.modules.flatMap((module) => {
282
283
  const plan = buildModuleConformancePlan(module, ir.manifestDigest);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["import { stableStringify, type FabricCompilerIr, type GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { ModuleManifest } from \"@fabricorg/platform\";\n\n/** Checks a single module's own behaviour, verifiable against a governed host. */\nexport const MODULE_CONFORMANCE_CHECKS = [\n\t\"fabric.idempotency.same-command-replay.v1\",\n\t\"fabric.idempotency.conflicting-payload.v1\",\n\t\"fabric.idempotency.concurrent-submission.v1\",\n\t\"fabric.authorization.governing-moment.v1\",\n\t\"fabric.authorization.offline-replay.v1\",\n\t\"fabric.events.compatibility.v1\",\n\t\"fabric.provenance.propagation.v1\",\n\t\"fabric.consumers.tolerant-envelope.v1\",\n] as const;\n\n/**\n * Checks that belong to a repository rather than a module. They are certification\n * evidence like any other check, but no per-module suite can produce them.\n */\nexport const PLATFORM_CONFORMANCE_CHECKS = [\n\t\"fabric.documentation.parity.v1\",\n\t\"fabric.documentation.llms-contract.v1\",\n] as const;\n\nexport const PHASE_1_CONFORMANCE_CHECKS = [...MODULE_CONFORMANCE_CHECKS, ...PLATFORM_CONFORMANCE_CHECKS] as const;\n\nexport type ModuleConformanceCheckId = typeof MODULE_CONFORMANCE_CHECKS[number];\nexport type PlatformConformanceCheckId = typeof PLATFORM_CONFORMANCE_CHECKS[number];\nexport type Phase1ConformanceCheckId = ModuleConformanceCheckId | PlatformConformanceCheckId;\n\nexport interface ConformanceEvidence { id: Phase1ConformanceCheckId; status: \"passed\" | \"failed\"; evidence: string[] }\n\nexport interface CertificationResult {\n\tformatVersion: 1;\n\tmanifestDigest: string;\n\tcompilerVersion: string;\n\tgeneratorDigests: Record<string, string>;\n\tchecks: ConformanceEvidence[];\n\tpassed: boolean;\n}\n\n// ── Plan ────────────────────────────────────────────────────────────────────\n\nexport interface PlannedAction {\n\tactionId: string;\n\tversion: number;\n\tmutatesDomain: boolean;\n\tidempotent: boolean;\n\tidempotency?: \"required\" | \"supported\" | \"prohibited\";\n\tauthorityMoment?: \"capture\" | \"execution\" | \"both\";\n\tconnectivity?: \"online-required\" | \"offline-capturable\";\n\tconsistency?: \"authoritative-now\" | \"provisional-until-reconciled\";\n}\n\nexport interface PlannedView {\n\tname: string;\n\tversion: string;\n\tconsumes: Array<{ eventType: string; schemaVersions: number[] }>;\n}\n\nexport interface ModuleConformancePlan {\n\tformatVersion: 1;\n\tmodule: string;\n\tmanifestDigest: string;\n\trequiredChecks: readonly ModuleConformanceCheckId[];\n\tplatformChecks: readonly PlatformConformanceCheckId[];\n\tactions: PlannedAction[];\n\tviews: PlannedView[];\n\teventTypes: Array<{ eventType: string; schemaVersion: number }>;\n}\n\n// ── Harness contract ────────────────────────────────────────────────────────\n\nexport interface ConformanceScope { tenantId: string; spaceId: string; actorId: string; actorType: string }\n\nexport interface ConformanceSubmitInput {\n\tactionId: string;\n\tparameters: Record<string, unknown>;\n\tidempotencyKey?: string;\n\tcorrelationId?: string;\n\tprovenance?: { source: string; correlationId: string; auditAttributes?: Record<string, string> };\n\t/**\n\t * Declares only the intent of the binding. The harness completes tenant, actor,\n\t * action and parameter-digest identity, because only it knows the command shape.\n\t */\n\tauthorizationBinding?: { governingMoment: \"capture\" | \"execution\" | \"both\"; capturedAt?: string; expiresAt?: string };\n\texecutionReason?: \"initial\" | \"offline_replay\";\n}\n\nexport interface ConformanceSubmitResult {\n\tactionInvocationId: string;\n\tstatus: string;\n\treconciliation?: { kind: string };\n}\n\nexport interface ConformanceEventEnvelope {\n\teventType: string;\n\tcorrelationId?: string;\n\tactionInvocationId?: string;\n\ttenantId?: string;\n\tspaceId?: string;\n\tsubjectType?: string;\n\tsubjectId?: string;\n\tsequence?: number;\n\t[key: string]: unknown;\n}\n\n/**\n * What an application supplies so its module's generated suite can run. Structural\n * by design: any store or host that satisfies it is a valid subject.\n */\nexport interface ConformanceHarness {\n\tscope: ConformanceScope;\n\t/** Representative parameters for an action; the module owns its own fixtures. */\n\tparameters(actionId: string): Record<string, unknown>;\n\tsubmit(input: ConformanceSubmitInput): Promise<ConformanceSubmitResult>;\n\tevents(): Promise<ConformanceEventEnvelope[]>;\n\t/** Withdraw execution-time authority so a replay must be refused. */\n\trevokeAuthority(actionId: string): Promise<void>;\n\t/**\n\t * Observable effects an action has produced so far — events appended, rows written,\n\t * whatever the application counts. Supply it and the idempotency checks prove the\n\t * handler did not run twice, rather than only that the same identifier came back.\n\t */\n\tsideEffects?(actionId: string): Promise<number>;\n\t/**\n\t * Hand a real emitted envelope to a real consumer. Supply it and the\n\t * tolerant-envelope check stops being producer-side only: it proves a consumer\n\t * survives fields it does not recognise, which is what tolerance means.\n\t */\n\tacceptsEnvelope?(envelope: ConformanceEventEnvelope): Promise<boolean> | boolean;\n}\n\nexport type ConformanceOutcome =\n\t| { status: \"passed\"; evidence: string[] }\n\t| { status: \"not-applicable\"; reason: string };\n\nexport interface ConformanceCheck {\n\tid: ModuleConformanceCheckId;\n\ttitle: string;\n\trun(harness: ConformanceHarness, plan: ModuleConformancePlan): Promise<ConformanceOutcome>;\n}\n\nclass ConformanceFailure extends Error {\n\toverride readonly name = \"ConformanceFailure\";\n}\n\nfunction expect(condition: unknown, message: string): asserts condition {\n\tif (!condition) throw new ConformanceFailure(message);\n}\n\nconst idempotentActions = (plan: ModuleConformancePlan): PlannedAction[] =>\n\tplan.actions.filter((action) => action.idempotency !== \"prohibited\" && action.idempotent);\n\nconst key = (label: string, action: PlannedAction): string => `conformance:${label}:${action.actionId}`;\n\nconst conflictReason = (conflict: { code?: string; message: string }): string => conflict.code ?? conflict.message;\n\nasync function conflictOf(run: () => Promise<unknown>): Promise<{ thrown: boolean; code?: string; message: string }> {\n\ttry {\n\t\tawait run();\n\t\treturn { thrown: false, message: \"\" };\n\t} catch (error) {\n\t\tconst code = (error as { code?: string }).code;\n\t\treturn { thrown: true, ...(code ? { code } : {}), message: error instanceof Error ? error.message : String(error) };\n\t}\n}\n\n/**\n * Runs a check against every eligible action, not just the first. A module whose\n * first action conforms and whose second does not must fail, or certification\n * means nothing for the rest of the module.\n */\nasync function forEachAction(\n\tactions: PlannedAction[],\n\treason: string,\n\tbody: (action: PlannedAction) => Promise<string[]>,\n): Promise<ConformanceOutcome> {\n\tif (actions.length === 0) return { status: \"not-applicable\", reason };\n\tconst evidence: string[] = [];\n\tfor (const action of actions) evidence.push(...await body(action));\n\treturn { status: \"passed\", evidence };\n}\n\nexport function moduleConformanceChecks(): ConformanceCheck[] {\n\treturn [\n\t\t{\n\t\t\tid: \"fabric.idempotency.same-command-replay.v1\",\n\t\t\ttitle: \"replaying one command key with the same payload does not re-execute\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst input = { actionId: action.actionId, parameters: harness.parameters(action.actionId), idempotencyKey: key(\"replay\", action) };\n\t\t\t\tconst first = await harness.submit(input);\n\t\t\t\tconst before = await harness.sideEffects?.(action.actionId);\n\t\t\t\tconst second = await harness.submit(input);\n\t\t\t\texpect(first.actionInvocationId === second.actionInvocationId, `replay of ${action.actionId} produced a second invocation ${second.actionInvocationId} for key ${input.idempotencyKey}`);\n\t\t\t\tconst after = await harness.sideEffects?.(action.actionId);\n\t\t\t\tif (before !== undefined && after !== undefined) {\n\t\t\t\t\texpect(after === before, `replay of ${action.actionId} returned the original invocation but produced ${after - before} further effects; the handler ran again`);\n\t\t\t\t}\n\t\t\t\treturn [`invocation:${first.actionInvocationId}`, `key:${input.idempotencyKey}`, `effects:${after ?? \"unobserved\"}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.idempotency.conflicting-payload.v1\",\n\t\t\ttitle: \"reusing a command key with an altered payload is refused\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst idempotencyKey = key(\"conflict\", action);\n\t\t\t\tconst parameters = harness.parameters(action.actionId);\n\t\t\t\tawait harness.submit({ actionId: action.actionId, parameters, idempotencyKey });\n\t\t\t\tconst conflict = await conflictOf(() => harness.submit({\n\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\tparameters: { ...parameters, \"x-conformance-altered\": true },\n\t\t\t\t\tidempotencyKey,\n\t\t\t\t}));\n\t\t\t\texpect(conflict.thrown, `altered payload reusing key ${idempotencyKey} was accepted instead of refused`);\n\t\t\t\texpect(\n\t\t\t\t\tconflict.code === \"IDEMPOTENCY_CONFLICT\" || /idempotenc/i.test(conflict.message),\n\t\t\t\t\t`altered payload for ${action.actionId} was refused, but not as an idempotency conflict: ${conflict.message}`,\n\t\t\t\t);\n\t\t\t\treturn [`key:${idempotencyKey}`, `refusal:${conflictReason(conflict)}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.idempotency.concurrent-submission.v1\",\n\t\t\ttitle: \"concurrent identical submissions collapse to one invocation\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst input = { actionId: action.actionId, parameters: harness.parameters(action.actionId), idempotencyKey: key(\"concurrent\", action) };\n\t\t\t\tconst before = await harness.sideEffects?.(action.actionId);\n\t\t\t\tconst results = await Promise.all([harness.submit(input), harness.submit(input), harness.submit(input)]);\n\t\t\t\tconst ids = new Set(results.map((result) => result.actionInvocationId));\n\t\t\t\texpect(ids.size === 1, `concurrent submissions of ${action.actionId} produced ${ids.size} invocations: ${[...ids].join(\", \")}`);\n\t\t\t\tconst after = await harness.sideEffects?.(action.actionId);\n\t\t\t\tif (before !== undefined && after !== undefined) {\n\t\t\t\t\tconst executions = after - before;\n\t\t\t\t\texpect(executions <= 1, `${results.length} concurrent submissions of ${action.actionId} collapsed to one invocation but produced ${executions} executions' worth of effects`);\n\t\t\t\t}\n\t\t\t\treturn [`invocation:${[...ids][0]}`, `attempts:${results.length}`, `effects:${after ?? \"unobserved\"}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.authorization.governing-moment.v1\",\n\t\t\ttitle: \"an authorization binding must match the action's declared governing moment\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.authorityMoment !== undefined),\n\t\t\t\t\"module declares no action with an authority moment\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst mismatched = action.authorityMoment === \"capture\" ? \"execution\" : \"capture\";\n\t\t\t\t\tconst rejection = await conflictOf(() => harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tauthorizationBinding: { governingMoment: mismatched, capturedAt: new Date(Date.now() - 60_000).toISOString() },\n\t\t\t\t\t}));\n\t\t\t\t\texpect(rejection.thrown, `a binding declaring governingMoment \"${mismatched}\" was accepted for ${action.actionId}, governed at \"${action.authorityMoment}\"`);\n\t\t\t\t\texpect(\n\t\t\t\t\t\t/governingmoment|governing moment/i.test(conflictReason(rejection)),\n\t\t\t\t\t\t`the binding for ${action.actionId} was refused, but not for its governing moment: ${conflictReason(rejection)}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn [`action:${action.actionId}`, `declared:${action.authorityMoment}`, `refused:${mismatched}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.authorization.offline-replay.v1\",\n\t\t\ttitle: \"an offline capture replayed after authority is withdrawn is refused into reconciliation\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) =>\n\t\t\t\t\taction.connectivity === \"offline-capturable\" && action.authorityMoment !== undefined && action.authorityMoment !== \"capture\"),\n\t\t\t\t\"module declares no offline-capturable action governed at execution\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tawait harness.revokeAuthority(action.actionId);\n\t\t\t\t\tconst replay = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tidempotencyKey: key(\"offline-replay\", action),\n\t\t\t\t\t\texecutionReason: \"offline_replay\",\n\t\t\t\t\t});\n\t\t\t\t\texpect(\n\t\t\t\t\t\treplay.status === \"reconciliation_required\",\n\t\t\t\t\t\t`replay of ${action.actionId} after authority withdrawal returned status \"${replay.status}\" instead of reconciliation_required`,\n\t\t\t\t\t);\n\t\t\t\t\texpect(replay.reconciliation !== undefined, `reconciliation_required was returned for ${action.actionId} without a reconciliation outcome`);\n\t\t\t\t\treturn [`action:${action.actionId}`, `reconciliation:${replay.reconciliation?.kind}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.events.compatibility.v1\",\n\t\t\ttitle: \"every consumed event version is one the module still declares\",\n\t\t\tasync run(_harness, plan) {\n\t\t\t\tif (plan.views.length === 0) return { status: \"not-applicable\", reason: \"module declares no views\" };\n\t\t\t\tconst declared = new Map(plan.eventTypes.map((event) => [event.eventType, event.schemaVersion]));\n\t\t\t\tconst evidence: string[] = [];\n\t\t\t\tfor (const view of plan.views) {\n\t\t\t\t\tfor (const consumption of view.consumes) {\n\t\t\t\t\t\tconst current = declared.get(consumption.eventType);\n\t\t\t\t\t\tif (current === undefined) continue;\n\t\t\t\t\t\texpect(\n\t\t\t\t\t\t\tconsumption.schemaVersions.includes(current),\n\t\t\t\t\t\t\t`view ${view.name}@${view.version} consumes ${consumption.eventType} at [${consumption.schemaVersions.join(\", \")}] but the module now emits version ${current}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tevidence.push(`${view.name}@${view.version}:${consumption.eventType}=${current}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (evidence.length === 0) return { status: \"not-applicable\", reason: \"no view consumes an event this module declares\" };\n\t\t\t\treturn { status: \"passed\", evidence };\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.provenance.propagation.v1\",\n\t\t\ttitle: \"submission provenance reaches the events the action emits\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.mutatesDomain),\n\t\t\t\t\"module declares no domain-mutating action\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst correlationId = `conformance-corr-${action.actionId}`;\n\t\t\t\t\tconst submitted = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tcorrelationId,\n\t\t\t\t\t\t// Audit attributes are allowlisted per application, so provenance identity is asserted on correlation alone.\n\t\t\t\t\t\tprovenance: { source: \"system\", correlationId },\n\t\t\t\t\t});\n\t\t\t\t\tconst emitted = (await harness.events()).filter((event) => event.actionInvocationId === submitted.actionInvocationId);\n\t\t\t\t\texpect(emitted.length > 0, `action ${action.actionId} mutates domain but emitted no events`);\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\texpect(event.correlationId === correlationId, `event ${event.eventType} carried correlationId ${String(event.correlationId)} instead of ${correlationId}`);\n\t\t\t\t\t}\n\t\t\t\t\treturn [`invocation:${submitted.actionInvocationId}`, `events:${emitted.length}`, `correlationId:${correlationId}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.consumers.tolerant-envelope.v1\",\n\t\t\ttitle: \"emitted envelopes are complete, and a consumer tolerates fields it does not know\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.mutatesDomain),\n\t\t\t\t\"module declares no domain-mutating action\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst submitted = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tidempotencyKey: key(\"envelope\", action),\n\t\t\t\t\t});\n\t\t\t\t\tconst emitted = (await harness.events()).filter((event) => event.actionInvocationId === submitted.actionInvocationId);\n\t\t\t\t\texpect(emitted.length > 0, `action ${action.actionId} mutates domain but emitted no events`);\n\t\t\t\t\tconst required = [\"eventType\", \"tenantId\", \"spaceId\", \"subjectType\", \"subjectId\", \"sequence\", \"correlationId\"] as const;\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\tfor (const field of required) {\n\t\t\t\t\t\t\texpect(event[field] !== undefined && event[field] !== null, `event ${event.eventType} omits the canonical envelope field \"${field}\"`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst evidence = emitted.map((event) => `${event.eventType}@${event.sequence}`);\n\t\t\t\t\tif (!harness.acceptsEnvelope) return [...evidence, \"consumer:unobserved\"];\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\t// Additive fields are exactly what a future schema version introduces.\n\t\t\t\t\t\tconst extended = { ...event, \"x-conformance-unknown\": true, consistency: \"provisional-until-reconciled\" };\n\t\t\t\t\t\tconst accepted = await harness.acceptsEnvelope(extended);\n\t\t\t\t\t\texpect(accepted, `a consumer rejected ${event.eventType} once it carried a field it did not recognise; additive event changes would break it`);\n\t\t\t\t\t}\n\t\t\t\t\treturn [...evidence, `consumer:tolerated:${emitted.length}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t];\n}\n\n// ── Certification evidence ──────────────────────────────────────────────────\n\nexport function createCertificationResult(input: Omit<CertificationResult, \"formatVersion\" | \"passed\">): CertificationResult {\n\tconst results = new Map(input.checks.map((check) => [check.id, check]));\n\tif (results.size !== input.checks.length) throw new Error(\"Certification evidence contains duplicate check identifiers.\");\n\tconst missing = PHASE_1_CONFORMANCE_CHECKS.filter((id) => !results.has(id));\n\tif (missing.length) throw new Error(`Certification evidence is missing mandatory checks: ${missing.join(\", \")}`);\n\tif (!/^[0-9a-f]{64}$/.test(input.manifestDigest)) throw new Error(\"Certification manifestDigest must be a lowercase SHA-256 digest.\");\n\tconst generatorDigests = Object.entries(input.generatorDigests);\n\tif (!generatorDigests.length || generatorDigests.some(([, digest]) => !/^[0-9a-f]{64}$/.test(digest))) throw new Error(\"Certification generatorDigests must contain SHA-256 evidence.\");\n\tif (input.checks.some((check) => check.status === \"passed\" && check.evidence.length === 0)) throw new Error(\"Passed certification checks require evidence references.\");\n\treturn { ...input, formatVersion: 1, checks: [...input.checks].sort((a, b) => a.id.localeCompare(b.id)), passed: input.checks.every((check) => check.status === \"passed\") };\n}\n\n// ── Generator ───────────────────────────────────────────────────────────────\n\nexport function buildModuleConformancePlan(module: ModuleManifest, manifestDigest: string): ModuleConformancePlan {\n\treturn {\n\t\tformatVersion: 1,\n\t\tmodule: module.namespace,\n\t\tmanifestDigest,\n\t\trequiredChecks: MODULE_CONFORMANCE_CHECKS,\n\t\tplatformChecks: PLATFORM_CONFORMANCE_CHECKS,\n\t\tactions: module.actions.map((action) => ({\n\t\t\tactionId: action.actionId,\n\t\t\tversion: action.version,\n\t\t\tmutatesDomain: action.mutatesDomain,\n\t\t\tidempotent: action.idempotent,\n\t\t\t...(action.execution?.idempotency ? { idempotency: action.execution.idempotency } : {}),\n\t\t\t...(action.execution?.authorityMoment ? { authorityMoment: action.execution.authorityMoment } : {}),\n\t\t\t...(action.execution?.connectivity ? { connectivity: action.execution.connectivity } : {}),\n\t\t\t...(action.execution?.consistency ? { consistency: action.execution.consistency } : {}),\n\t\t})),\n\t\tviews: module.views.map((view) => ({\n\t\t\tname: view.name,\n\t\t\tversion: view.version,\n\t\t\tconsumes: view.consumes.map((consumption) => ({ eventType: consumption.eventType, schemaVersions: [...consumption.schemaVersions] })),\n\t\t})),\n\t\teventTypes: module.eventTypes.map((event) => ({ eventType: event.eventType, schemaVersion: event.schemaVersion })),\n\t};\n}\n\nfunction suiteSource(plan: ModuleConformancePlan, generator: { name: string; version: string }): string {\n\treturn [\n\t\t`// Generated by ${generator.name}@${generator.version}. Do not edit.`,\n\t\t`// Manifest digest: ${plan.manifestDigest}`,\n\t\t`// Supply ./conformance.harness with a createConformanceHarness() factory returning a fresh, isolated harness.`,\n\t\t'import { expect, it } from \"vitest\";',\n\t\t'import { moduleConformanceChecks, type ModuleConformancePlan } from \"@fabricorg/gen-conformance\";',\n\t\t'import { createConformanceHarness } from \"./conformance.harness\";',\n\t\t\"\",\n\t\t`export const plan: ModuleConformancePlan = ${JSON.stringify(plan, null, 2)};`,\n\t\t\"\",\n\t\t\"for (const check of moduleConformanceChecks()) {\",\n\t\t\" it(`${check.id} — ${check.title}`, async () => {\",\n\t\t\" const outcome = await check.run(await createConformanceHarness(), plan);\",\n\t\t' expect([\"passed\", \"not-applicable\"]).toContain(outcome.status);',\n\t\t\" });\",\n\t\t\"}\",\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\nexport const conformanceGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-conformance\",\n\tversion: \"0.2.0\",\n\tgenerate(ir: FabricCompilerIr) {\n\t\treturn ir.modules.flatMap((module) => {\n\t\t\tconst plan = buildModuleConformancePlan(module, ir.manifestDigest);\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tpath: `${module.namespace}/conformance-plan.json`,\n\t\t\t\t\tcontent: stableStringify({\n\t\t\t\t\t\t...plan,\n\t\t\t\t\t\tgenerator: { name: conformanceGenerator.name, version: conformanceGenerator.version },\n\t\t\t\t\t\tcompilerVersion: ir.compilerVersion,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: `${module.namespace}/conformance.test.ts`,\n\t\t\t\t\tcontent: suiteSource(plan, { name: conformanceGenerator.name, version: conformanceGenerator.version }),\n\t\t\t\t},\n\t\t\t];\n\t\t});\n\t},\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../index.ts"],"sourcesContent":["import { stableStringify, type FabricCompilerIr, type GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { ModuleManifest } from \"@fabricorg/platform\";\n\n/** Checks a single module's own behaviour, verifiable against a governed host. */\nexport const MODULE_CONFORMANCE_CHECKS = [\n\t\"fabric.idempotency.same-command-replay.v1\",\n\t\"fabric.idempotency.conflicting-payload.v1\",\n\t\"fabric.idempotency.concurrent-submission.v1\",\n\t\"fabric.authorization.governing-moment.v1\",\n\t\"fabric.authorization.offline-replay.v1\",\n\t\"fabric.events.compatibility.v1\",\n\t\"fabric.provenance.propagation.v1\",\n\t\"fabric.consumers.tolerant-envelope.v1\",\n] as const;\n\n/**\n * Checks that belong to a repository rather than a module. They are certification\n * evidence like any other check, but no per-module suite can produce them.\n */\nexport const PLATFORM_CONFORMANCE_CHECKS = [\n\t\"fabric.documentation.parity.v1\",\n\t\"fabric.documentation.llms-contract.v1\",\n] as const;\n\nexport const PHASE_1_CONFORMANCE_CHECKS = [...MODULE_CONFORMANCE_CHECKS, ...PLATFORM_CONFORMANCE_CHECKS] as const;\n\nexport type ModuleConformanceCheckId = typeof MODULE_CONFORMANCE_CHECKS[number];\nexport type PlatformConformanceCheckId = typeof PLATFORM_CONFORMANCE_CHECKS[number];\nexport type Phase1ConformanceCheckId = ModuleConformanceCheckId | PlatformConformanceCheckId;\n\nexport interface ConformanceEvidence { id: Phase1ConformanceCheckId; status: \"passed\" | \"failed\"; evidence: string[] }\n\nexport interface CertificationResult {\n\tformatVersion: 1;\n\tmanifestDigest: string;\n\tcompilerVersion: string;\n\tgeneratorDigests: Record<string, string>;\n\tchecks: ConformanceEvidence[];\n\tpassed: boolean;\n}\n\n// ── Plan ────────────────────────────────────────────────────────────────────\n\nexport interface PlannedAction {\n\tactionId: string;\n\tversion: number;\n\tmutatesDomain: boolean;\n\tidempotent: boolean;\n\tidempotency?: \"required\" | \"supported\" | \"prohibited\";\n\tauthorityMoment?: \"capture\" | \"execution\" | \"both\";\n\tconnectivity?: \"online-required\" | \"offline-capturable\";\n\tconsistency?: \"authoritative-now\" | \"provisional-until-reconciled\";\n}\n\nexport interface PlannedView {\n\tname: string;\n\tversion: string;\n\tparameterSchema?: ModuleManifest[\"views\"][number][\"parameterSchema\"];\n\tconsumes: Array<{ eventType: string; schemaVersions: number[] }>;\n}\n\nexport interface ModuleConformancePlan {\n\tformatVersion: 1;\n\tmodule: string;\n\tmanifestDigest: string;\n\trequiredChecks: readonly ModuleConformanceCheckId[];\n\tplatformChecks: readonly PlatformConformanceCheckId[];\n\tactions: PlannedAction[];\n\tviews: PlannedView[];\n\teventTypes: Array<{ eventType: string; schemaVersion: number }>;\n}\n\n// ── Harness contract ────────────────────────────────────────────────────────\n\nexport interface ConformanceScope { tenantId: string; spaceId: string; actorId: string; actorType: string }\n\nexport interface ConformanceSubmitInput {\n\tactionId: string;\n\tparameters: Record<string, unknown>;\n\tidempotencyKey?: string;\n\tcorrelationId?: string;\n\tprovenance?: { source: string; correlationId: string; auditAttributes?: Record<string, string> };\n\t/**\n\t * Declares only the intent of the binding. The harness completes tenant, actor,\n\t * action and parameter-digest identity, because only it knows the command shape.\n\t */\n\tauthorizationBinding?: { governingMoment: \"capture\" | \"execution\" | \"both\"; capturedAt?: string; expiresAt?: string };\n\texecutionReason?: \"initial\" | \"offline_replay\";\n}\n\nexport interface ConformanceSubmitResult {\n\tactionInvocationId: string;\n\tstatus: string;\n\treconciliation?: { kind: string };\n}\n\nexport interface ConformanceEventEnvelope {\n\teventType: string;\n\tcorrelationId?: string;\n\tactionInvocationId?: string;\n\ttenantId?: string;\n\tspaceId?: string;\n\tsubjectType?: string;\n\tsubjectId?: string;\n\tsequence?: number;\n\t[key: string]: unknown;\n}\n\n/**\n * What an application supplies so its module's generated suite can run. Structural\n * by design: any store or host that satisfies it is a valid subject.\n */\nexport interface ConformanceHarness {\n\tscope: ConformanceScope;\n\t/** Representative parameters for an action; the module owns its own fixtures. */\n\tparameters(actionId: string): Record<string, unknown>;\n\tsubmit(input: ConformanceSubmitInput): Promise<ConformanceSubmitResult>;\n\tevents(): Promise<ConformanceEventEnvelope[]>;\n\t/** Withdraw execution-time authority so a replay must be refused. */\n\trevokeAuthority(actionId: string): Promise<void>;\n\t/**\n\t * Observable effects an action has produced so far — events appended, rows written,\n\t * whatever the application counts. Supply it and the idempotency checks prove the\n\t * handler did not run twice, rather than only that the same identifier came back.\n\t */\n\tsideEffects?(actionId: string): Promise<number>;\n\t/**\n\t * Hand a real emitted envelope to a real consumer. Supply it and the\n\t * tolerant-envelope check stops being producer-side only: it proves a consumer\n\t * survives fields it does not recognise, which is what tolerance means.\n\t */\n\tacceptsEnvelope?(envelope: ConformanceEventEnvelope): Promise<boolean> | boolean;\n}\n\nexport type ConformanceOutcome =\n\t| { status: \"passed\"; evidence: string[] }\n\t| { status: \"not-applicable\"; reason: string };\n\nexport interface ConformanceCheck {\n\tid: ModuleConformanceCheckId;\n\ttitle: string;\n\trun(harness: ConformanceHarness, plan: ModuleConformancePlan): Promise<ConformanceOutcome>;\n}\n\nclass ConformanceFailure extends Error {\n\toverride readonly name = \"ConformanceFailure\";\n}\n\nfunction expect(condition: unknown, message: string): asserts condition {\n\tif (!condition) throw new ConformanceFailure(message);\n}\n\nconst idempotentActions = (plan: ModuleConformancePlan): PlannedAction[] =>\n\tplan.actions.filter((action) => action.idempotency !== \"prohibited\" && action.idempotent);\n\nconst key = (label: string, action: PlannedAction): string => `conformance:${label}:${action.actionId}`;\n\nconst conflictReason = (conflict: { code?: string; message: string }): string => conflict.code ?? conflict.message;\n\nasync function conflictOf(run: () => Promise<unknown>): Promise<{ thrown: boolean; code?: string; message: string }> {\n\ttry {\n\t\tawait run();\n\t\treturn { thrown: false, message: \"\" };\n\t} catch (error) {\n\t\tconst code = (error as { code?: string }).code;\n\t\treturn { thrown: true, ...(code ? { code } : {}), message: error instanceof Error ? error.message : String(error) };\n\t}\n}\n\n/**\n * Runs a check against every eligible action, not just the first. A module whose\n * first action conforms and whose second does not must fail, or certification\n * means nothing for the rest of the module.\n */\nasync function forEachAction(\n\tactions: PlannedAction[],\n\treason: string,\n\tbody: (action: PlannedAction) => Promise<string[]>,\n): Promise<ConformanceOutcome> {\n\tif (actions.length === 0) return { status: \"not-applicable\", reason };\n\tconst evidence: string[] = [];\n\tfor (const action of actions) evidence.push(...await body(action));\n\treturn { status: \"passed\", evidence };\n}\n\nexport function moduleConformanceChecks(): ConformanceCheck[] {\n\treturn [\n\t\t{\n\t\t\tid: \"fabric.idempotency.same-command-replay.v1\",\n\t\t\ttitle: \"replaying one command key with the same payload does not re-execute\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst input = { actionId: action.actionId, parameters: harness.parameters(action.actionId), idempotencyKey: key(\"replay\", action) };\n\t\t\t\tconst first = await harness.submit(input);\n\t\t\t\tconst before = await harness.sideEffects?.(action.actionId);\n\t\t\t\tconst second = await harness.submit(input);\n\t\t\t\texpect(first.actionInvocationId === second.actionInvocationId, `replay of ${action.actionId} produced a second invocation ${second.actionInvocationId} for key ${input.idempotencyKey}`);\n\t\t\t\tconst after = await harness.sideEffects?.(action.actionId);\n\t\t\t\tif (before !== undefined && after !== undefined) {\n\t\t\t\t\texpect(after === before, `replay of ${action.actionId} returned the original invocation but produced ${after - before} further effects; the handler ran again`);\n\t\t\t\t}\n\t\t\t\treturn [`invocation:${first.actionInvocationId}`, `key:${input.idempotencyKey}`, `effects:${after ?? \"unobserved\"}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.idempotency.conflicting-payload.v1\",\n\t\t\ttitle: \"reusing a command key with an altered payload is refused\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst idempotencyKey = key(\"conflict\", action);\n\t\t\t\tconst parameters = harness.parameters(action.actionId);\n\t\t\t\tawait harness.submit({ actionId: action.actionId, parameters, idempotencyKey });\n\t\t\t\tconst conflict = await conflictOf(() => harness.submit({\n\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\tparameters: { ...parameters, \"x-conformance-altered\": true },\n\t\t\t\t\tidempotencyKey,\n\t\t\t\t}));\n\t\t\t\texpect(conflict.thrown, `altered payload reusing key ${idempotencyKey} was accepted instead of refused`);\n\t\t\t\texpect(\n\t\t\t\t\tconflict.code === \"IDEMPOTENCY_CONFLICT\" || /idempotenc/i.test(conflict.message),\n\t\t\t\t\t`altered payload for ${action.actionId} was refused, but not as an idempotency conflict: ${conflict.message}`,\n\t\t\t\t);\n\t\t\t\treturn [`key:${idempotencyKey}`, `refusal:${conflictReason(conflict)}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.idempotency.concurrent-submission.v1\",\n\t\t\ttitle: \"concurrent identical submissions collapse to one invocation\",\n\t\t\trun: (harness, plan) => forEachAction(idempotentActions(plan), \"module declares no idempotent action\", async (action) => {\n\t\t\t\tconst input = { actionId: action.actionId, parameters: harness.parameters(action.actionId), idempotencyKey: key(\"concurrent\", action) };\n\t\t\t\tconst before = await harness.sideEffects?.(action.actionId);\n\t\t\t\tconst results = await Promise.all([harness.submit(input), harness.submit(input), harness.submit(input)]);\n\t\t\t\tconst ids = new Set(results.map((result) => result.actionInvocationId));\n\t\t\t\texpect(ids.size === 1, `concurrent submissions of ${action.actionId} produced ${ids.size} invocations: ${[...ids].join(\", \")}`);\n\t\t\t\tconst after = await harness.sideEffects?.(action.actionId);\n\t\t\t\tif (before !== undefined && after !== undefined) {\n\t\t\t\t\tconst executions = after - before;\n\t\t\t\t\texpect(executions <= 1, `${results.length} concurrent submissions of ${action.actionId} collapsed to one invocation but produced ${executions} executions' worth of effects`);\n\t\t\t\t}\n\t\t\t\treturn [`invocation:${[...ids][0]}`, `attempts:${results.length}`, `effects:${after ?? \"unobserved\"}`];\n\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.authorization.governing-moment.v1\",\n\t\t\ttitle: \"an authorization binding must match the action's declared governing moment\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.authorityMoment !== undefined),\n\t\t\t\t\"module declares no action with an authority moment\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst mismatched = action.authorityMoment === \"capture\" ? \"execution\" : \"capture\";\n\t\t\t\t\tconst rejection = await conflictOf(() => harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tauthorizationBinding: { governingMoment: mismatched, capturedAt: new Date(Date.now() - 60_000).toISOString() },\n\t\t\t\t\t}));\n\t\t\t\t\texpect(rejection.thrown, `a binding declaring governingMoment \"${mismatched}\" was accepted for ${action.actionId}, governed at \"${action.authorityMoment}\"`);\n\t\t\t\t\texpect(\n\t\t\t\t\t\t/governingmoment|governing moment/i.test(conflictReason(rejection)),\n\t\t\t\t\t\t`the binding for ${action.actionId} was refused, but not for its governing moment: ${conflictReason(rejection)}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn [`action:${action.actionId}`, `declared:${action.authorityMoment}`, `refused:${mismatched}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.authorization.offline-replay.v1\",\n\t\t\ttitle: \"an offline capture replayed after authority is withdrawn is refused into reconciliation\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) =>\n\t\t\t\t\taction.connectivity === \"offline-capturable\" && action.authorityMoment !== undefined && action.authorityMoment !== \"capture\"),\n\t\t\t\t\"module declares no offline-capturable action governed at execution\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tawait harness.revokeAuthority(action.actionId);\n\t\t\t\t\tconst replay = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tidempotencyKey: key(\"offline-replay\", action),\n\t\t\t\t\t\texecutionReason: \"offline_replay\",\n\t\t\t\t\t});\n\t\t\t\t\texpect(\n\t\t\t\t\t\treplay.status === \"reconciliation_required\",\n\t\t\t\t\t\t`replay of ${action.actionId} after authority withdrawal returned status \"${replay.status}\" instead of reconciliation_required`,\n\t\t\t\t\t);\n\t\t\t\t\texpect(replay.reconciliation !== undefined, `reconciliation_required was returned for ${action.actionId} without a reconciliation outcome`);\n\t\t\t\t\treturn [`action:${action.actionId}`, `reconciliation:${replay.reconciliation?.kind}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.events.compatibility.v1\",\n\t\t\ttitle: \"every consumed event version is one the module still declares\",\n\t\t\tasync run(_harness, plan) {\n\t\t\t\tif (plan.views.length === 0) return { status: \"not-applicable\", reason: \"module declares no views\" };\n\t\t\t\tconst declared = new Map(plan.eventTypes.map((event) => [event.eventType, event.schemaVersion]));\n\t\t\t\tconst evidence: string[] = [];\n\t\t\t\tfor (const view of plan.views) {\n\t\t\t\t\tfor (const consumption of view.consumes) {\n\t\t\t\t\t\tconst current = declared.get(consumption.eventType);\n\t\t\t\t\t\tif (current === undefined) continue;\n\t\t\t\t\t\texpect(\n\t\t\t\t\t\t\tconsumption.schemaVersions.includes(current),\n\t\t\t\t\t\t\t`view ${view.name}@${view.version} consumes ${consumption.eventType} at [${consumption.schemaVersions.join(\", \")}] but the module now emits version ${current}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tevidence.push(`${view.name}@${view.version}:${consumption.eventType}=${current}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (evidence.length === 0) return { status: \"not-applicable\", reason: \"no view consumes an event this module declares\" };\n\t\t\t\treturn { status: \"passed\", evidence };\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.provenance.propagation.v1\",\n\t\t\ttitle: \"submission provenance reaches the events the action emits\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.mutatesDomain),\n\t\t\t\t\"module declares no domain-mutating action\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst correlationId = `conformance-corr-${action.actionId}`;\n\t\t\t\t\tconst submitted = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tcorrelationId,\n\t\t\t\t\t\t// Audit attributes are allowlisted per application, so provenance identity is asserted on correlation alone.\n\t\t\t\t\t\tprovenance: { source: \"system\", correlationId },\n\t\t\t\t\t});\n\t\t\t\t\tconst emitted = (await harness.events()).filter((event) => event.actionInvocationId === submitted.actionInvocationId);\n\t\t\t\t\texpect(emitted.length > 0, `action ${action.actionId} mutates domain but emitted no events`);\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\texpect(event.correlationId === correlationId, `event ${event.eventType} carried correlationId ${String(event.correlationId)} instead of ${correlationId}`);\n\t\t\t\t\t}\n\t\t\t\t\treturn [`invocation:${submitted.actionInvocationId}`, `events:${emitted.length}`, `correlationId:${correlationId}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"fabric.consumers.tolerant-envelope.v1\",\n\t\t\ttitle: \"emitted envelopes are complete, and a consumer tolerates fields it does not know\",\n\t\t\trun: (harness, plan) => forEachAction(\n\t\t\t\tplan.actions.filter((action) => action.mutatesDomain),\n\t\t\t\t\"module declares no domain-mutating action\",\n\t\t\t\tasync (action) => {\n\t\t\t\t\tconst submitted = await harness.submit({\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tparameters: harness.parameters(action.actionId),\n\t\t\t\t\t\tidempotencyKey: key(\"envelope\", action),\n\t\t\t\t\t});\n\t\t\t\t\tconst emitted = (await harness.events()).filter((event) => event.actionInvocationId === submitted.actionInvocationId);\n\t\t\t\t\texpect(emitted.length > 0, `action ${action.actionId} mutates domain but emitted no events`);\n\t\t\t\t\tconst required = [\"eventType\", \"tenantId\", \"spaceId\", \"subjectType\", \"subjectId\", \"sequence\", \"correlationId\"] as const;\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\tfor (const field of required) {\n\t\t\t\t\t\t\texpect(event[field] !== undefined && event[field] !== null, `event ${event.eventType} omits the canonical envelope field \"${field}\"`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst evidence = emitted.map((event) => `${event.eventType}@${event.sequence}`);\n\t\t\t\t\tif (!harness.acceptsEnvelope) return [...evidence, \"consumer:unobserved\"];\n\t\t\t\t\tfor (const event of emitted) {\n\t\t\t\t\t\t// Additive fields are exactly what a future schema version introduces.\n\t\t\t\t\t\tconst extended = { ...event, \"x-conformance-unknown\": true, consistency: \"provisional-until-reconciled\" };\n\t\t\t\t\t\tconst accepted = await harness.acceptsEnvelope(extended);\n\t\t\t\t\t\texpect(accepted, `a consumer rejected ${event.eventType} once it carried a field it did not recognise; additive event changes would break it`);\n\t\t\t\t\t}\n\t\t\t\t\treturn [...evidence, `consumer:tolerated:${emitted.length}`];\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t];\n}\n\n// ── Certification evidence ──────────────────────────────────────────────────\n\nexport function createCertificationResult(input: Omit<CertificationResult, \"formatVersion\" | \"passed\">): CertificationResult {\n\tconst results = new Map(input.checks.map((check) => [check.id, check]));\n\tif (results.size !== input.checks.length) throw new Error(\"Certification evidence contains duplicate check identifiers.\");\n\tconst missing = PHASE_1_CONFORMANCE_CHECKS.filter((id) => !results.has(id));\n\tif (missing.length) throw new Error(`Certification evidence is missing mandatory checks: ${missing.join(\", \")}`);\n\tif (!/^[0-9a-f]{64}$/.test(input.manifestDigest)) throw new Error(\"Certification manifestDigest must be a lowercase SHA-256 digest.\");\n\tconst generatorDigests = Object.entries(input.generatorDigests);\n\tif (!generatorDigests.length || generatorDigests.some(([, digest]) => !/^[0-9a-f]{64}$/.test(digest))) throw new Error(\"Certification generatorDigests must contain SHA-256 evidence.\");\n\tif (input.checks.some((check) => check.status === \"passed\" && check.evidence.length === 0)) throw new Error(\"Passed certification checks require evidence references.\");\n\treturn { ...input, formatVersion: 1, checks: [...input.checks].sort((a, b) => a.id.localeCompare(b.id)), passed: input.checks.every((check) => check.status === \"passed\") };\n}\n\n// ── Generator ───────────────────────────────────────────────────────────────\n\nexport function buildModuleConformancePlan(module: ModuleManifest, manifestDigest: string): ModuleConformancePlan {\n\treturn {\n\t\tformatVersion: 1,\n\t\tmodule: module.namespace,\n\t\tmanifestDigest,\n\t\trequiredChecks: MODULE_CONFORMANCE_CHECKS,\n\t\tplatformChecks: PLATFORM_CONFORMANCE_CHECKS,\n\t\tactions: module.actions.map((action) => ({\n\t\t\tactionId: action.actionId,\n\t\t\tversion: action.version,\n\t\t\tmutatesDomain: action.mutatesDomain,\n\t\t\tidempotent: action.idempotent,\n\t\t\t...(action.execution?.idempotency ? { idempotency: action.execution.idempotency } : {}),\n\t\t\t...(action.execution?.authorityMoment ? { authorityMoment: action.execution.authorityMoment } : {}),\n\t\t\t...(action.execution?.connectivity ? { connectivity: action.execution.connectivity } : {}),\n\t\t\t...(action.execution?.consistency ? { consistency: action.execution.consistency } : {}),\n\t\t})),\n\t\tviews: module.views.map((view) => ({\n\t\t\tname: view.name,\n\t\t\tversion: view.version,\n\t\t\t...(view.parameterSchema ? { parameterSchema: view.parameterSchema } : {}),\n\t\t\tconsumes: view.consumes.map((consumption) => ({ eventType: consumption.eventType, schemaVersions: [...consumption.schemaVersions] })),\n\t\t})),\n\t\teventTypes: module.eventTypes.map((event) => ({ eventType: event.eventType, schemaVersion: event.schemaVersion })),\n\t};\n}\n\nfunction suiteSource(plan: ModuleConformancePlan, generator: { name: string; version: string }): string {\n\treturn [\n\t\t`// Generated by ${generator.name}@${generator.version}. Do not edit.`,\n\t\t`// Manifest digest: ${plan.manifestDigest}`,\n\t\t`// Supply ./conformance.harness with a createConformanceHarness() factory returning a fresh, isolated harness.`,\n\t\t'import { expect, it } from \"vitest\";',\n\t\t'import { moduleConformanceChecks, type ModuleConformancePlan } from \"@fabricorg/gen-conformance\";',\n\t\t'import { createConformanceHarness } from \"./conformance.harness\";',\n\t\t\"\",\n\t\t`export const plan: ModuleConformancePlan = ${JSON.stringify(plan, null, 2)};`,\n\t\t\"\",\n\t\t\"for (const check of moduleConformanceChecks()) {\",\n\t\t\" it(`${check.id} — ${check.title}`, async () => {\",\n\t\t\" const outcome = await check.run(await createConformanceHarness(), plan);\",\n\t\t' expect([\"passed\", \"not-applicable\"]).toContain(outcome.status);',\n\t\t\" });\",\n\t\t\"}\",\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\nexport const conformanceGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-conformance\",\n\tversion: \"0.3.0\",\n\tgenerate(ir: FabricCompilerIr) {\n\t\treturn ir.modules.flatMap((module) => {\n\t\t\tconst plan = buildModuleConformancePlan(module, ir.manifestDigest);\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tpath: `${module.namespace}/conformance-plan.json`,\n\t\t\t\t\tcontent: stableStringify({\n\t\t\t\t\t\t...plan,\n\t\t\t\t\t\tgenerator: { name: conformanceGenerator.name, version: conformanceGenerator.version },\n\t\t\t\t\t\tcompilerVersion: ir.compilerVersion,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: `${module.namespace}/conformance.test.ts`,\n\t\t\t\t\tcontent: suiteSource(plan, { name: conformanceGenerator.name, version: conformanceGenerator.version }),\n\t\t\t\t},\n\t\t\t];\n\t\t});\n\t},\n};\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabricorg/gen-conformance",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Deterministic Phase 1 capability conformance plans and certification evidence.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -36,15 +36,15 @@
36
36
  "LICENSE"
37
37
  ],
38
38
  "dependencies": {
39
- "@fabricorg/compiler": "^2.1.0"
39
+ "@fabricorg/compiler": "^2.2.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/node": "^22.10.0",
43
43
  "tsup": "^8.5.0",
44
44
  "typescript": "^5.7.3",
45
45
  "vitest": "^4.1.5",
46
- "@fabricorg/platform": "^1.1.0",
47
- "@fabricorg/platform-host": "^5.0.0"
46
+ "@fabricorg/platform": "^1.2.0",
47
+ "@fabricorg/platform-host": "^6.0.0"
48
48
  },
49
49
  "engines": {
50
50
  "node": ">=20"
@@ -53,8 +53,8 @@
53
53
  "access": "public"
54
54
  },
55
55
  "peerDependencies": {
56
- "@fabricorg/platform": "^1.1.0",
57
- "@fabricorg/platform-host": "^5.0.0"
56
+ "@fabricorg/platform-host": "^5.0.0 || ^6.0.0",
57
+ "@fabricorg/platform": "^1.2.0"
58
58
  },
59
59
  "scripts": {
60
60
  "clean": "rm -rf dist tsconfig.tsbuildinfo",