@odla-ai/chapter 0.47.10 → 0.48.1

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing-probe.ts","../src/testing-runner.ts","../src/testing.ts"],"sourcesContent":["import type {\n ChapterAcceptanceManifest,\n ChapterAcceptanceTarget,\n ChapterJoinContractFinding,\n ChapterJoinContractProbeResult,\n} from \"./testing-contract\";\nimport { validateChapterAcceptanceManifest } from \"./testing\";\n\nconst MAX_BODY_BYTES = 64 * 1024;\nconst TIMEOUT_MS = 10_000;\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown> : null;\n}\n\nasync function readBoundedJson(response: Response, signal: AbortSignal): Promise<unknown> {\n const reader = response.body?.getReader();\n if (!reader) throw new Error(\"invalid_json\");\n const chunks: Uint8Array[] = [];\n let size = 0;\n const abort = () => { void reader.cancel().catch(() => {}); };\n signal.addEventListener(\"abort\", abort, { once: true });\n try {\n if (signal.aborted) throw new Error(\"response_failed\");\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > MAX_BODY_BYTES) throw new Error(\"response_too_large\");\n chunks.push(value);\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.byteLength; }\n try { return JSON.parse(new TextDecoder().decode(bytes)); }\n catch { throw new Error(\"invalid_json\"); }\n } finally {\n signal.removeEventListener(\"abort\", abort);\n await reader.cancel().catch(() => {});\n reader.releaseLock();\n }\n}\n\ntype ProbeResponse = { status: number; json?: unknown; error?: string; identity?: Record<string, unknown> };\n\nasync function probe(url: string, fetcher: typeof fetch, json: boolean): Promise<ProbeResponse> {\n const controller = new AbortController();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<ProbeResponse>((resolve) => {\n timer = setTimeout(() => {\n controller.abort();\n resolve({ status: 0, error: \"request_timeout\" });\n }, TIMEOUT_MS);\n });\n try {\n return await Promise.race([timeout, (async (): Promise<ProbeResponse> => {\n let response: Response;\n try {\n response = await fetcher(url, {\n headers: { \"cache-control\": \"no-cache\" }, redirect: \"manual\", signal: controller.signal,\n });\n } catch { return { status: 0, error: \"request_failed\" }; }\n if (!json || !response.ok) {\n await response.body?.cancel().catch(() => {});\n return { status: response.status };\n }\n try {\n return {\n status: response.status, json: await readBoundedJson(response, controller.signal),\n identity: Object.fromEntries([\"app-id\", \"chapter-id\", \"data-environment\", \"runtime\"].map((name) =>\n [name, slug(response.headers.get(`x-odla-${name}`) ?? undefined)])),\n };\n }\n catch (error) {\n const code = error instanceof Error && [\"invalid_json\", \"response_too_large\"].includes(error.message)\n ? error.message : \"response_failed\";\n return { status: response.status, error: code };\n }\n })()]);\n } finally { clearTimeout(timer); }\n}\n\n// Findings are durable CI/PM data, not a mirror of an untrusted HTTP body.\nfunction slug(value: unknown): unknown {\n return value === undefined ? undefined : typeof value === \"string\" && /^[a-z0-9][a-z0-9-]{1,62}$/.test(value) ? value : \"invalid_value\";\n}\nfunction amount(value: unknown): unknown {\n return value === undefined ? undefined : Number.isSafeInteger(value) && Number(value) >= 0 ? value : \"invalid_value\";\n}\nfunction boolean(value: unknown): unknown {\n return value === undefined ? undefined : typeof value === \"boolean\" ? value : \"invalid_value\";\n}\n\nfunction activeMemberships(site: ChapterAcceptanceTarget) {\n return site.skus.filter((sku) => sku.active && sku.kind === \"membership\");\n}\n\n/**\n * Probe public deployed join contracts without creating applications or provider objects.\n * Each request, including its body, is limited to ten seconds and 64 KiB. Redirects\n * are refused. Malformed responses become per-target findings, never raw bodies\n * or exception text; one failed target does not suppress the remaining targets.\n */\nexport async function probeChapterJoinContracts(\n manifest: ChapterAcceptanceManifest,\n fetcher: typeof fetch = fetch,\n): Promise<ChapterJoinContractProbeResult> {\n const validation = validateChapterAcceptanceManifest(manifest);\n if (!validation.ok) throw new TypeError(`invalid Chapter acceptance manifest: ${validation.errors.join(\"; \")}`);\n const findings: ChapterJoinContractFinding[] = [];\n for (const site of manifest.targets) {\n const [health, configResponse] = await Promise.all([\n probe(`${site.origin}/api/health`, fetcher, true),\n probe(`${site.origin}/api/join-config`, fetcher, true),\n ]);\n const targetNote = (path: string, expected: unknown, actual: unknown): void => {\n if (JSON.stringify(expected) !== JSON.stringify(actual)) findings.push({ targetId: site.targetId, siteId: site.siteId, path, expected, actual });\n };\n targetNote(\"/api/health status\", 200, health.error ?? health.status);\n if (health.status === 200 && !health.error) targetNote(\"/api/health ok\", true, boolean(record(health.json)?.ok));\n if (health.status === 200 && !health.error) {\n for (const [name, expected] of Object.entries({\n \"app-id\": site.target.appId, \"chapter-id\": site.target.chapterId,\n \"data-environment\": site.target.dataEnvironment, \"runtime\": site.target.runtime,\n })) targetNote(`/api/health x-odla-${name}`, expected, health.identity?.[name]);\n }\n targetNote(\"/api/join-config status\", 200, configResponse.status || configResponse.error);\n if (configResponse.status !== 200) continue;\n if (configResponse.error) {\n targetNote(\"/api/join-config JSON\", \"object\", configResponse.error === \"invalid_json\" ? \"invalid JSON\" : configResponse.error);\n continue;\n }\n const config = record(configResponse.json);\n if (!config) {\n targetNote(\"/api/join-config JSON\", \"object\", \"invalid shape\");\n continue;\n }\n targetNote(\"id\", site.target.chapterId, slug(config.id));\n const actualTiers = Array.isArray(config.tiers) ? config.tiers : [];\n const expectedTiers = activeMemberships(site).map((sku) => ({\n id: sku.id, priceCents: sku.priceCents, currency: sku.currency,\n interval: sku.billing, free: sku.priceCents === 0,\n }));\n const projected = actualTiers.map((tier) => {\n const value = record(tier);\n if (!value) return \"invalid_tier\";\n return {\n id: slug(value.id), priceCents: amount(value.priceCents),\n currency: value.currency === undefined ? undefined : typeof value.currency === \"string\" && /^[a-z]{3}$/.test(value.currency) ? value.currency : \"invalid_value\",\n interval: value.interval === undefined ? undefined : [\"month\", \"year\", \"once\"].includes(String(value.interval)) ? value.interval : \"invalid_value\",\n free: boolean(value.free),\n };\n });\n targetNote(\"tiers\", expectedTiers, projected);\n targetNote(\"paymentsReady\", expectedTiers.some((tier) => !tier.free), boolean(config.paymentsReady));\n }\n return { ok: findings.length === 0, findings };\n}\n","import type {\n ChapterAcceptanceCaseResult,\n ChapterAcceptanceCleanupEvidence,\n ChapterAcceptanceEvidence,\n ChapterAcceptanceExecutionContext,\n ChapterAcceptanceExecutor,\n ChapterAcceptanceManifest,\n ChapterAcceptanceProviderReference,\n ChapterAcceptanceRunResult,\n} from \"./testing-contract\";\nimport { planChapterAcceptanceMatrix } from \"./testing\";\n\nconst SAFE_LABEL = /^[a-z0-9][a-z0-9._:-]{0,159}$/;\nconst SAFE_REFERENCE = /^[A-Za-z0-9_:.=-]{3,240}$/;\nconst CREDENTIAL = /(?:^|[_.:-])(?:sk|rk|pk)_(?:test|live)_|whsec_|_secret_|eyJ[A-Za-z0-9_-]+\\./i;\nconst ERROR_CODES = new Set([\"invalid_evidence\", \"assertion_failed\", \"preflight_failed\", \"unsupported_scenario\", \"execution_failed\"]);\n\nfunction safeValue(value: string, pattern: RegExp): boolean {\n return pattern.test(value) && !CREDENTIAL.test(value);\n}\n\nfunction safeErrorCode(error: unknown): string {\n if (error && typeof error === \"object\") {\n const code = (error as { code?: unknown }).code;\n if (typeof code === \"string\" && ERROR_CODES.has(code)) return code;\n }\n return \"execution_failed\";\n}\n\nfunction validateLabels(values: readonly string[], path: string): void {\n if (!Array.isArray(values) || values.length === 0) throw Object.assign(new TypeError(`${path} must be non-empty`), { code: \"invalid_evidence\" });\n if (values.length > 64 || values.some((value) => typeof value !== \"string\" || !safeValue(value, SAFE_LABEL))) {\n throw Object.assign(new TypeError(`${path} contains an unsafe or unbounded label`), { code: \"invalid_evidence\" });\n }\n}\n\nfunction validateReferences(values: readonly ChapterAcceptanceProviderReference[] | undefined): void {\n if (values === undefined) return;\n if (!Array.isArray(values) || values.length > 64) throw Object.assign(new TypeError(\"references must be bounded\"), { code: \"invalid_evidence\" });\n const kinds = new Set([\"stripe_event\", \"stripe_object\", \"clerk_user\", \"calendar_event\", \"email_message\", \"event_digest\"]);\n for (const reference of values) {\n if (!reference || !kinds.has(reference.kind) || typeof reference.value !== \"string\" ||\n !safeValue(reference.value, SAFE_REFERENCE) || reference.value.includes(\"@\")) {\n throw Object.assign(new TypeError(\"references may contain only opaque provider ids or digests\"), { code: \"invalid_evidence\" });\n }\n }\n}\n\nfunction validateEvidence(evidence: ChapterAcceptanceEvidence, provider: boolean): ChapterAcceptanceEvidence {\n if (!evidence || typeof evidence !== \"object\") throw Object.assign(new TypeError(\"executor returned no evidence\"), { code: \"invalid_evidence\" });\n validateLabels(evidence.checks, \"evidence.checks\");\n validateReferences(evidence.references);\n if ((provider || evidence.deploymentVersion !== undefined) &&\n (typeof evidence.deploymentVersion !== \"string\" || !safeValue(evidence.deploymentVersion, SAFE_REFERENCE))) {\n throw Object.assign(new TypeError(\"provider evidence requires a safe deploymentVersion\"), { code: \"invalid_evidence\" });\n }\n // Copy only the validated wire contract. Never retain provider response objects,\n // extra fields, custom toJSON methods, or arrays that an adapter can later mutate.\n return {\n checks: [...evidence.checks],\n ...(evidence.deploymentVersion !== undefined ? { deploymentVersion: evidence.deploymentVersion } : {}),\n ...(evidence.references !== undefined ? {\n references: evidence.references.map(({ kind, value }) => ({ kind, value })),\n } : {}),\n };\n}\n\nfunction validateCleanup(cleanup: ChapterAcceptanceCleanupEvidence): ChapterAcceptanceCleanupEvidence {\n if (!cleanup || (cleanup.status !== \"complete\" && cleanup.status !== \"incomplete\")) {\n throw Object.assign(new TypeError(\"executor returned invalid cleanup evidence\"), { code: \"cleanup_failed\" });\n }\n validateLabels(cleanup.checks, \"cleanup.checks\");\n return { status: cleanup.status, checks: [...cleanup.checks] };\n}\n\nfunction contextFor(manifest: ChapterAcceptanceManifest, id: string): ChapterAcceptanceExecutionContext {\n const scenario = planChapterAcceptanceMatrix(manifest).find((item) => item.id === id);\n if (!scenario) throw new TypeError(`unknown acceptance scenario ${id}`);\n const target = manifest.targets.find((item) => item.targetId === scenario.targetId)!;\n return {\n scenario,\n target,\n ...(scenario.skuId ? { sku: target.skus.find((item) => item.id === scenario.skuId) } : {}),\n ...(scenario.siblingTargetId ? {\n siblingTarget: manifest.targets.find((item) => item.targetId === scenario.siblingTargetId),\n } : {}),\n };\n}\n\n/**\n * Execute one suite serially. Provider runs fail before their first mutation\n * unless the app supplies cleanup, then invoke cleanup after every attempted\n * case even when execution throws. Unconfirmed cleanup stops subsequent cases;\n * those cases fail with `not_run_cleanup_failed` and are never executed.\n * Evidence is copied only after validation; raw provider errors and extra fields\n * are never retained. Adapter check labels must not contain personal data.\n */\nexport async function runChapterAcceptanceSuite(\n manifest: ChapterAcceptanceManifest,\n suite: \"hermetic\" | \"provider_dev\",\n executor: ChapterAcceptanceExecutor,\n): Promise<ChapterAcceptanceRunResult> {\n if (suite !== \"hermetic\" && suite !== \"provider_dev\") throw new TypeError(\"unknown acceptance suite\");\n const scenarios = planChapterAcceptanceMatrix(manifest).filter((item) => item.suite === suite);\n if (suite === \"provider_dev\" && typeof executor.cleanup !== \"function\") {\n throw new TypeError(\"provider_dev acceptance requires a cleanup executor before any case can run\");\n }\n const cases: ChapterAcceptanceCaseResult[] = [];\n let cleanupFailed = false;\n for (const scenario of scenarios) {\n if (cleanupFailed) {\n cases.push({ id: scenario.id, suite, outcome: \"failed\", errorCode: \"not_run_cleanup_failed\" });\n continue;\n }\n const context = contextFor(manifest, scenario.id);\n let evidence: ChapterAcceptanceEvidence | undefined;\n let errorCode: string | undefined;\n let cleanup: ChapterAcceptanceCleanupEvidence | undefined;\n try {\n evidence = validateEvidence(await executor.execute(context), suite === \"provider_dev\");\n } catch (error) {\n errorCode = safeErrorCode(error);\n } finally {\n if (suite === \"provider_dev\") {\n try {\n cleanup = validateCleanup(await executor.cleanup!(context));\n if (cleanup.status !== \"complete\") {\n cleanupFailed = true;\n errorCode = \"cleanup_incomplete\";\n }\n } catch {\n cleanupFailed = true;\n errorCode = \"cleanup_failed\";\n }\n }\n }\n cases.push({\n id: scenario.id,\n suite,\n outcome: errorCode ? \"failed\" : \"passed\",\n ...(evidence ? { evidence } : {}),\n ...(cleanup ? { cleanup } : {}),\n ...(errorCode ? { errorCode } : {}),\n });\n }\n return { ok: cases.every((item) => item.outcome === \"passed\"), suite, cases };\n}\n\n/** PII-free line report suitable for CI logs and PM evidence. */\nexport function formatChapterAcceptanceRun(result: ChapterAcceptanceRunResult): string {\n const passed = result.cases.filter((item) => item.outcome === \"passed\").length;\n const lines = [`${result.ok ? \"ok\" : \"failed\"}: ${result.suite} ${passed}/${result.cases.length}`];\n for (const item of result.cases) {\n lines.push(`${item.outcome === \"passed\" ? \"PASS\" : \"FAIL\"} ${item.id}${item.errorCode ? ` ${item.errorCode}` : \"\"}`);\n }\n return lines.join(\"\\n\");\n}\n","import type {\n ChapterAcceptanceManifest, ChapterAcceptanceScenario, ChapterAcceptanceSku, ChapterAcceptanceTarget, ChapterAcceptanceValidation,\n} from \"./testing-contract\";\nexport type * from \"./testing-contract\";\nexport { probeChapterJoinContracts } from \"./testing-probe\";\nexport { formatChapterAcceptanceRun, runChapterAcceptanceSuite } from \"./testing-runner\";\n\nconst SLUG = /^[a-z0-9][a-z0-9-]{1,62}$/;\nconst CURRENCY = /^[a-z]{3}$/;\nconst STRIPE_PRICE = /^price_[A-Za-z0-9]{8,}$/;\n\nfunction activeMemberships(site: ChapterAcceptanceTarget): ChapterAcceptanceSku[] {\n return site.skus.filter((sku) => sku.active && sku.kind === \"membership\");\n}\n\nfunction representativePaidMembership(site: ChapterAcceptanceTarget): ChapterAcceptanceSku | undefined {\n return activeMemberships(site).find((sku) => sku.priceCents > 0);\n}\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null;\n}\n\n/** Validate the exact facts a multi-site acceptance run needs before it writes anywhere. */\nexport function validateChapterAcceptanceManifest(value: unknown): ChapterAcceptanceValidation {\n const errors: string[] = [];\n const input = record(value);\n if (!input) return { ok: false, errors: [\"manifest must be an object\"] };\n if (input.schemaVersion !== 1) errors.push(\"schemaVersion must be 1\");\n const inputTargets = Array.isArray(input.targets) ? input.targets : [];\n if (inputTargets.length < 2) errors.push(\"targets must contain at least two deployed Chapter targets\");\n\n const targetIds = new Set<string>();\n const siteIds = new Set<string>();\n const targets = new Set<string>();\n const priceOwners = new Map<string, string>();\n for (const [siteIndex, rawSite] of inputTargets.entries()) {\n const path = `targets[${siteIndex}]`;\n const site = record(rawSite);\n if (!site) {\n errors.push(`${path} must be an object`);\n continue;\n }\n const targetId = typeof site.targetId === \"string\" ? site.targetId : \"\";\n const siteId = typeof site.siteId === \"string\" ? site.siteId : \"\";\n if (!SLUG.test(targetId)) errors.push(`${path}.targetId must be a stable lowercase slug`);\n if (targetIds.has(targetId)) errors.push(`${path}.targetId duplicates ${JSON.stringify(targetId)}`);\n if (targetId) targetIds.add(targetId);\n if (!SLUG.test(siteId)) errors.push(`${path}.siteId must be a stable lowercase slug`);\n if (siteId) siteIds.add(siteId);\n try {\n if (typeof site.origin !== \"string\") throw new TypeError(\"origin\");\n const origin = new URL(site.origin);\n if (origin.protocol !== \"https:\" || origin.pathname !== \"/\" || origin.search || origin.hash || origin.username || origin.password) {\n errors.push(`${path}.origin must be an HTTPS origin without a path, query, or fragment`);\n }\n } catch {\n errors.push(`${path}.origin must be a valid HTTPS origin`);\n }\n const target = record(site.target);\n const targetValues = {} as Record<\"appId\" | \"environment\" | \"dataEnvironment\" | \"runtime\" | \"chapterId\", string>;\n for (const key of [\"appId\", \"environment\", \"dataEnvironment\", \"runtime\", \"chapterId\"] as const) {\n targetValues[key] = typeof target?.[key] === \"string\" ? String(target[key]) : \"\";\n if (!targetValues[key]) errors.push(`${path}.target.${key} is required`);\n }\n const partition = Object.values(targetValues).join(\"\\u0000\");\n if (targets.has(partition)) errors.push(`${path}.target duplicates another site partition`);\n if (Object.values(targetValues).every(Boolean)) targets.add(partition);\n if (site.stripeMode !== \"test\" && site.stripeMode !== \"live\") {\n errors.push(`${path}.stripeMode must be test or live`);\n }\n if (site.stripeMode === \"live\" && targetValues.environment !== \"prod\" && targetValues.environment !== \"production\") {\n errors.push(`${path}.stripeMode cannot be live outside a production environment`);\n }\n\n const skuIds = new Set<string>();\n const inputSkus = Array.isArray(site.skus) ? site.skus : [];\n if (!Array.isArray(site.skus) || inputSkus.length === 0) errors.push(`${path}.skus must be a non-empty array`);\n const skus: ChapterAcceptanceSku[] = [];\n for (const [skuIndex, rawSku] of inputSkus.entries()) {\n const skuPath = `${path}.skus[${skuIndex}]`;\n const sku = record(rawSku);\n if (!sku) {\n errors.push(`${skuPath} must be an object`);\n continue;\n }\n const id = typeof sku.id === \"string\" ? sku.id : \"\";\n if (!SLUG.test(id)) errors.push(`${skuPath}.id must be a stable lowercase slug`);\n if (skuIds.has(id)) errors.push(`${skuPath}.id duplicates ${JSON.stringify(id)}`);\n if (id) skuIds.add(id);\n if (sku.kind !== \"membership\" && sku.kind !== \"add_on\") errors.push(`${skuPath}.kind must be membership or add_on`);\n if (typeof sku.active !== \"boolean\") errors.push(`${skuPath}.active must be boolean`);\n const priceCents = typeof sku.priceCents === \"number\" ? sku.priceCents : Number.NaN;\n if (!Number.isSafeInteger(priceCents) || priceCents < 0) errors.push(`${skuPath}.priceCents must be a non-negative integer`);\n if (typeof sku.currency !== \"string\" || !CURRENCY.test(sku.currency)) errors.push(`${skuPath}.currency must be a lowercase ISO currency code`);\n if (sku.billing !== \"month\" && sku.billing !== \"year\" && sku.billing !== \"once\") {\n errors.push(`${skuPath}.billing must be month, year, or once`);\n }\n if (sku.kind === \"membership\" && sku.billing === \"once\") {\n errors.push(`${skuPath}.billing must be month or year for a membership SKU`);\n }\n if (sku.active === true && priceCents > 0 && (typeof sku.stripePriceId !== \"string\" || !STRIPE_PRICE.test(sku.stripePriceId))) {\n errors.push(`${skuPath}.stripePriceId is required for an active paid SKU`);\n }\n if (priceCents === 0 && sku.stripePriceId) errors.push(`${skuPath}.stripePriceId must be absent for a free SKU`);\n if (typeof sku.stripePriceId === \"string\" && sku.stripePriceId) {\n const owner = `${siteId}/${id}`;\n const previous = priceOwners.get(sku.stripePriceId);\n if (previous && previous !== owner) errors.push(`${skuPath}.stripePriceId is already owned by ${previous}`);\n else priceOwners.set(sku.stripePriceId, owner);\n }\n if (sku.compareAtPriceCents !== undefined) {\n if (!Number.isSafeInteger(sku.compareAtPriceCents) || Number(sku.compareAtPriceCents) <= priceCents) {\n errors.push(`${skuPath}.compareAtPriceCents must be an integer greater than priceCents`);\n }\n if (sku.discountDuration !== \"first_term\" && sku.discountDuration !== \"while_active\") {\n errors.push(`${skuPath}.discountDuration is required with compareAtPriceCents`);\n }\n } else if (sku.discountDuration) {\n errors.push(`${skuPath}.compareAtPriceCents is required with discountDuration`);\n }\n skus.push(sku as unknown as ChapterAcceptanceSku);\n }\n if (!skus.some((sku) => sku.active && sku.kind === \"membership\")) errors.push(`${path}.skus must contain an active membership SKU`);\n const options = record(site.options);\n if (!options) errors.push(`${path}.options must be an object`);\n if (options?.ordinaryInterview !== true) errors.push(`${path}.options.ordinaryInterview must be true`);\n if (typeof options?.invitationInterviewWaiver !== \"boolean\") errors.push(`${path}.options.invitationInterviewWaiver must be boolean`);\n if (options?.autoRenew !== true) errors.push(`${path}.options.autoRenew must be true`);\n const seat = record(options?.additionalSeat);\n if (options?.additionalSeat !== undefined && !seat) errors.push(`${path}.options.additionalSeat must be an object`);\n if (seat) {\n const seatSku = skus.find((sku) => sku.id === seat.skuId);\n if (!seatSku || !seatSku.active || seatSku.kind !== \"add_on\") {\n errors.push(`${path}.options.additionalSeat.skuId must name an active add_on SKU`);\n } else if (seatSku.billing === \"once\") {\n errors.push(`${path}.options.additionalSeat.skuId must name a recurring add_on SKU`);\n }\n if (typeof seat.purchaseWindowCalendarMonths !== \"number\" ||\n !Number.isInteger(seat.purchaseWindowCalendarMonths) || seat.purchaseWindowCalendarMonths < 1) {\n errors.push(`${path}.options.additionalSeat.purchaseWindowCalendarMonths must be a positive integer`);\n }\n if (seat.named !== true || seat.uniqueEmail !== true || seat.renewal !== \"membership_aligned\" || seat.chargeTiming !== \"start\") {\n errors.push(`${path}.options.additionalSeat must require a named unique-email seat, membership-aligned renewal, and payment at start`);\n }\n }\n }\n if (siteIds.size < 2) errors.push(\"targets must cover at least two distinct logical sites\");\n return errors.length ? { ok: false, errors } : { ok: true, value: value as ChapterAcceptanceManifest };\n}\n\nfunction scenario(input: Omit<ChapterAcceptanceScenario, \"id\">): ChapterAcceptanceScenario {\n return {\n ...input,\n id: [input.suite, input.targetId, input.skuId, input.siblingTargetId, input.kind].filter(Boolean).join(\":\"),\n };\n}\n\n/**\n * Build exhaustive pure cases plus a bounded provider-backed development matrix.\n * Throws before returning provider work when the manifest is invalid or names live Stripe.\n */\nexport function planChapterAcceptanceMatrix(manifest: ChapterAcceptanceManifest): ChapterAcceptanceScenario[] {\n const validation = validateChapterAcceptanceManifest(manifest);\n if (!validation.ok) throw new TypeError(`invalid Chapter acceptance manifest: ${validation.errors.join(\"; \")}`);\n if (manifest.targets.some((site) => site.stripeMode !== \"test\" || site.target.environment !== \"dev\" || site.target.dataEnvironment !== \"dev\")) {\n throw new TypeError(\"provider acceptance runs are development-only and require Stripe test mode and dev runtime/data environments on every target\");\n }\n const scenarios: ChapterAcceptanceScenario[] = [];\n for (const site of manifest.targets) {\n for (const sku of site.skus.filter((candidate) => candidate.active)) {\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"catalog_contract\", targetId: site.targetId, siteId: site.siteId, skuId: sku.id }));\n if (sku.priceCents > 0) {\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"amount_tamper\", targetId: site.targetId, siteId: site.siteId, skuId: sku.id }));\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"wrong_environment_event\", targetId: site.targetId, siteId: site.siteId, skuId: sku.id }));\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"post_stripe_compensation\", targetId: site.targetId, siteId: site.siteId, skuId: sku.id }));\n for (const sibling of manifest.targets.filter((candidate) => candidate.targetId !== site.targetId)) {\n scenarios.push(scenario({\n suite: \"hermetic\", kind: \"sibling_event_isolation\", targetId: site.targetId, siteId: site.siteId,\n skuId: sku.id, siblingTargetId: sibling.targetId,\n }));\n }\n }\n }\n for (const sku of activeMemberships(site)) {\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"submit_replay\", targetId: site.targetId, siteId: site.siteId, skuId: sku.id }));\n scenarios.push(scenario({\n suite: \"provider_dev\", kind: sku.priceCents > 0 ? \"paid_signup\" : \"free_signup\",\n targetId: site.targetId, siteId: site.siteId, skuId: sku.id,\n }));\n }\n const paid = representativePaidMembership(site);\n if (paid) {\n scenarios.push(scenario({ suite: \"provider_dev\", kind: \"ordinary_interview\", targetId: site.targetId, siteId: site.siteId, skuId: paid.id }));\n scenarios.push(scenario({ suite: \"provider_dev\", kind: \"renewal\", targetId: site.targetId, siteId: site.siteId, skuId: paid.id }));\n scenarios.push(scenario({ suite: \"provider_dev\", kind: \"refund_cancel\", targetId: site.targetId, siteId: site.siteId, skuId: paid.id }));\n if (site.options.invitationInterviewWaiver) {\n scenarios.push(scenario({ suite: \"provider_dev\", kind: \"invitation_interview_waiver\", targetId: site.targetId, siteId: site.siteId, skuId: paid.id }));\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"expired_interview_waiver\", targetId: site.targetId, siteId: site.siteId, skuId: paid.id }));\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"replayed_interview_waiver\", targetId: site.targetId, siteId: site.siteId, skuId: paid.id }));\n }\n if (site.options.additionalSeat) {\n scenarios.push(scenario({\n suite: \"provider_dev\", kind: \"named_seat\", targetId: site.targetId, siteId: site.siteId,\n skuId: site.options.additionalSeat.skuId,\n }));\n scenarios.push(scenario({\n suite: \"hermetic\", kind: \"duplicate_seat_email\", targetId: site.targetId, siteId: site.siteId,\n skuId: site.options.additionalSeat.skuId,\n }));\n scenarios.push(scenario({\n suite: \"hermetic\", kind: \"expired_seat_window\", targetId: site.targetId, siteId: site.siteId,\n skuId: site.options.additionalSeat.skuId,\n }));\n }\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"canceled_membership\", targetId: site.targetId, siteId: site.siteId, skuId: paid.id }));\n }\n }\n return scenarios;\n}\n"],"mappings":";AAQA,IAAM,iBAAiB,KAAK;AAC5B,IAAM,aAAa;AAEnB,SAAS,OAAO,OAAgD;AAC9D,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACtE,QAAmC;AACzC;AAEA,eAAe,gBAAgB,UAAoB,QAAuC;AACxF,QAAM,SAAS,SAAS,MAAM,UAAU;AACxC,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,cAAc;AAC3C,QAAM,SAAuB,CAAC;AAC9B,MAAI,OAAO;AACX,QAAM,QAAQ,MAAM;AAAE,SAAK,OAAO,OAAO,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAAG;AAC5D,SAAO,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;AACtD,MAAI;AACF,QAAI,OAAO,QAAS,OAAM,IAAI,MAAM,iBAAiB;AACrD,eAAS;AACP,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,cAAQ,MAAM;AACd,UAAI,OAAO,eAAgB,OAAM,IAAI,MAAM,oBAAoB;AAC/D,aAAO,KAAK,KAAK;AAAA,IACnB;AACA,UAAM,QAAQ,IAAI,WAAW,IAAI;AACjC,QAAI,SAAS;AACb,eAAW,SAAS,QAAQ;AAAE,YAAM,IAAI,OAAO,MAAM;AAAG,gBAAU,MAAM;AAAA,IAAY;AACpF,QAAI;AAAE,aAAO,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,KAAK,CAAC;AAAA,IAAG,QACpD;AAAE,YAAM,IAAI,MAAM,cAAc;AAAA,IAAG;AAAA,EAC3C,UAAE;AACA,WAAO,oBAAoB,SAAS,KAAK;AACzC,UAAM,OAAO,OAAO,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AACpC,WAAO,YAAY;AAAA,EACrB;AACF;AAIA,eAAe,MAAM,KAAa,SAAuB,MAAuC;AAC9F,QAAM,aAAa,IAAI,gBAAgB;AACvC,MAAI;AACJ,QAAM,UAAU,IAAI,QAAuB,CAAC,YAAY;AACtD,YAAQ,WAAW,MAAM;AACvB,iBAAW,MAAM;AACjB,cAAQ,EAAE,QAAQ,GAAG,OAAO,kBAAkB,CAAC;AAAA,IACjD,GAAG,UAAU;AAAA,EACf,CAAC;AACD,MAAI;AACF,WAAO,MAAM,QAAQ,KAAK,CAAC,UAAU,YAAoC;AACvE,UAAI;AACJ,UAAI;AACF,mBAAW,MAAM,QAAQ,KAAK;AAAA,UAC5B,SAAS,EAAE,iBAAiB,WAAW;AAAA,UAAG,UAAU;AAAA,UAAU,QAAQ,WAAW;AAAA,QACnF,CAAC;AAAA,MACH,QAAQ;AAAE,eAAO,EAAE,QAAQ,GAAG,OAAO,iBAAiB;AAAA,MAAG;AACzD,UAAI,CAAC,QAAQ,CAAC,SAAS,IAAI;AACzB,cAAM,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAC5C,eAAO,EAAE,QAAQ,SAAS,OAAO;AAAA,MACnC;AACA,UAAI;AACF,eAAO;AAAA,UACL,QAAQ,SAAS;AAAA,UAAQ,MAAM,MAAM,gBAAgB,UAAU,WAAW,MAAM;AAAA,UAChF,UAAU,OAAO,YAAY,CAAC,UAAU,cAAc,oBAAoB,SAAS,EAAE,IAAI,CAAC,SACxF,CAAC,MAAM,KAAK,SAAS,QAAQ,IAAI,UAAU,IAAI,EAAE,KAAK,MAAS,CAAC,CAAC,CAAC;AAAA,QACtE;AAAA,MACF,SACO,OAAO;AACZ,cAAM,OAAO,iBAAiB,SAAS,CAAC,gBAAgB,oBAAoB,EAAE,SAAS,MAAM,OAAO,IAChG,MAAM,UAAU;AACpB,eAAO,EAAE,QAAQ,SAAS,QAAQ,OAAO,KAAK;AAAA,MAChD;AAAA,IACF,GAAG,CAAC,CAAC;AAAA,EACP,UAAE;AAAU,iBAAa,KAAK;AAAA,EAAG;AACnC;AAGA,SAAS,KAAK,OAAyB;AACrC,SAAO,UAAU,SAAY,SAAY,OAAO,UAAU,YAAY,4BAA4B,KAAK,KAAK,IAAI,QAAQ;AAC1H;AACA,SAAS,OAAO,OAAyB;AACvC,SAAO,UAAU,SAAY,SAAY,OAAO,cAAc,KAAK,KAAK,OAAO,KAAK,KAAK,IAAI,QAAQ;AACvG;AACA,SAAS,QAAQ,OAAyB;AACxC,SAAO,UAAU,SAAY,SAAY,OAAO,UAAU,YAAY,QAAQ;AAChF;AAEA,SAAS,kBAAkB,MAA+B;AACxD,SAAO,KAAK,KAAK,OAAO,CAAC,QAAQ,IAAI,UAAU,IAAI,SAAS,YAAY;AAC1E;AAQA,eAAsB,0BACpB,UACA,UAAwB,OACiB;AACzC,QAAM,aAAa,kCAAkC,QAAQ;AAC7D,MAAI,CAAC,WAAW,GAAI,OAAM,IAAI,UAAU,wCAAwC,WAAW,OAAO,KAAK,IAAI,CAAC,EAAE;AAC9G,QAAM,WAAyC,CAAC;AAChD,aAAW,QAAQ,SAAS,SAAS;AACnC,UAAM,CAAC,QAAQ,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,MACjD,MAAM,GAAG,KAAK,MAAM,eAAe,SAAS,IAAI;AAAA,MAChD,MAAM,GAAG,KAAK,MAAM,oBAAoB,SAAS,IAAI;AAAA,IACvD,CAAC;AACD,UAAM,aAAa,CAAC,MAAc,UAAmB,WAA0B;AAC7E,UAAI,KAAK,UAAU,QAAQ,MAAM,KAAK,UAAU,MAAM,EAAG,UAAS,KAAK,EAAE,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,MAAM,UAAU,OAAO,CAAC;AAAA,IACjJ;AACA,eAAW,sBAAsB,KAAK,OAAO,SAAS,OAAO,MAAM;AACnE,QAAI,OAAO,WAAW,OAAO,CAAC,OAAO,MAAO,YAAW,kBAAkB,MAAM,QAAQ,OAAO,OAAO,IAAI,GAAG,EAAE,CAAC;AAC/G,QAAI,OAAO,WAAW,OAAO,CAAC,OAAO,OAAO;AAC1C,iBAAW,CAAC,MAAM,QAAQ,KAAK,OAAO,QAAQ;AAAA,QAC5C,UAAU,KAAK,OAAO;AAAA,QAAO,cAAc,KAAK,OAAO;AAAA,QACvD,oBAAoB,KAAK,OAAO;AAAA,QAAiB,WAAW,KAAK,OAAO;AAAA,MAC1E,CAAC,EAAG,YAAW,sBAAsB,IAAI,IAAI,UAAU,OAAO,WAAW,IAAI,CAAC;AAAA,IAChF;AACA,eAAW,2BAA2B,KAAK,eAAe,UAAU,eAAe,KAAK;AACxF,QAAI,eAAe,WAAW,IAAK;AACnC,QAAI,eAAe,OAAO;AACxB,iBAAW,yBAAyB,UAAU,eAAe,UAAU,iBAAiB,iBAAiB,eAAe,KAAK;AAC7H;AAAA,IACF;AACA,UAAM,SAAS,OAAO,eAAe,IAAI;AACzC,QAAI,CAAC,QAAQ;AACX,iBAAW,yBAAyB,UAAU,eAAe;AAC7D;AAAA,IACF;AACA,eAAW,MAAM,KAAK,OAAO,WAAW,KAAK,OAAO,EAAE,CAAC;AACvD,UAAM,cAAc,MAAM,QAAQ,OAAO,KAAK,IAAI,OAAO,QAAQ,CAAC;AAClE,UAAM,gBAAgB,kBAAkB,IAAI,EAAE,IAAI,CAAC,SAAS;AAAA,MAC1D,IAAI,IAAI;AAAA,MAAI,YAAY,IAAI;AAAA,MAAY,UAAU,IAAI;AAAA,MACtD,UAAU,IAAI;AAAA,MAAS,MAAM,IAAI,eAAe;AAAA,IAClD,EAAE;AACF,UAAM,YAAY,YAAY,IAAI,CAAC,SAAS;AAC1C,YAAM,QAAQ,OAAO,IAAI;AACzB,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO;AAAA,QACL,IAAI,KAAK,MAAM,EAAE;AAAA,QAAG,YAAY,OAAO,MAAM,UAAU;AAAA,QACvD,UAAU,MAAM,aAAa,SAAY,SAAY,OAAO,MAAM,aAAa,YAAY,aAAa,KAAK,MAAM,QAAQ,IAAI,MAAM,WAAW;AAAA,QAChJ,UAAU,MAAM,aAAa,SAAY,SAAY,CAAC,SAAS,QAAQ,MAAM,EAAE,SAAS,OAAO,MAAM,QAAQ,CAAC,IAAI,MAAM,WAAW;AAAA,QACnI,MAAM,QAAQ,MAAM,IAAI;AAAA,MAC1B;AAAA,IACF,CAAC;AACD,eAAW,SAAS,eAAe,SAAS;AAC5C,eAAW,iBAAiB,cAAc,KAAK,CAAC,SAAS,CAAC,KAAK,IAAI,GAAG,QAAQ,OAAO,aAAa,CAAC;AAAA,EACrG;AACA,SAAO,EAAE,IAAI,SAAS,WAAW,GAAG,SAAS;AAC/C;;;AClJA,IAAM,aAAa;AACnB,IAAM,iBAAiB;AACvB,IAAM,aAAa;AACnB,IAAM,cAAc,oBAAI,IAAI,CAAC,oBAAoB,oBAAoB,oBAAoB,wBAAwB,kBAAkB,CAAC;AAEpI,SAAS,UAAU,OAAe,SAA0B;AAC1D,SAAO,QAAQ,KAAK,KAAK,KAAK,CAAC,WAAW,KAAK,KAAK;AACtD;AAEA,SAAS,cAAc,OAAwB;AAC7C,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,OAAQ,MAA6B;AAC3C,QAAI,OAAO,SAAS,YAAY,YAAY,IAAI,IAAI,EAAG,QAAO;AAAA,EAChE;AACA,SAAO;AACT;AAEA,SAAS,eAAe,QAA2B,MAAoB;AACrE,MAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,EAAG,OAAM,OAAO,OAAO,IAAI,UAAU,GAAG,IAAI,oBAAoB,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC/I,MAAI,OAAO,SAAS,MAAM,OAAO,KAAK,CAAC,UAAU,OAAO,UAAU,YAAY,CAAC,UAAU,OAAO,UAAU,CAAC,GAAG;AAC5G,UAAM,OAAO,OAAO,IAAI,UAAU,GAAG,IAAI,wCAAwC,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAAA,EAClH;AACF;AAEA,SAAS,mBAAmB,QAAyE;AACnG,MAAI,WAAW,OAAW;AAC1B,MAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,OAAO,SAAS,GAAI,OAAM,OAAO,OAAO,IAAI,UAAU,4BAA4B,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC/I,QAAM,QAAQ,oBAAI,IAAI,CAAC,gBAAgB,iBAAiB,cAAc,kBAAkB,iBAAiB,cAAc,CAAC;AACxH,aAAW,aAAa,QAAQ;AAC9B,QAAI,CAAC,aAAa,CAAC,MAAM,IAAI,UAAU,IAAI,KAAK,OAAO,UAAU,UAAU,YACvE,CAAC,UAAU,UAAU,OAAO,cAAc,KAAK,UAAU,MAAM,SAAS,GAAG,GAAG;AAChF,YAAM,OAAO,OAAO,IAAI,UAAU,4DAA4D,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAAA,IAC/H;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,UAAqC,UAA8C;AAC3G,MAAI,CAAC,YAAY,OAAO,aAAa,SAAU,OAAM,OAAO,OAAO,IAAI,UAAU,+BAA+B,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC/I,iBAAe,SAAS,QAAQ,iBAAiB;AACjD,qBAAmB,SAAS,UAAU;AACtC,OAAK,YAAY,SAAS,sBAAsB,YAC3C,OAAO,SAAS,sBAAsB,YAAY,CAAC,UAAU,SAAS,mBAAmB,cAAc,IAAI;AAC9G,UAAM,OAAO,OAAO,IAAI,UAAU,qDAAqD,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAAA,EACxH;AAGA,SAAO;AAAA,IACL,QAAQ,CAAC,GAAG,SAAS,MAAM;AAAA,IAC3B,GAAI,SAAS,sBAAsB,SAAY,EAAE,mBAAmB,SAAS,kBAAkB,IAAI,CAAC;AAAA,IACpG,GAAI,SAAS,eAAe,SAAY;AAAA,MACtC,YAAY,SAAS,WAAW,IAAI,CAAC,EAAE,MAAM,MAAM,OAAO,EAAE,MAAM,MAAM,EAAE;AAAA,IAC5E,IAAI,CAAC;AAAA,EACP;AACF;AAEA,SAAS,gBAAgB,SAA6E;AACpG,MAAI,CAAC,WAAY,QAAQ,WAAW,cAAc,QAAQ,WAAW,cAAe;AAClF,UAAM,OAAO,OAAO,IAAI,UAAU,4CAA4C,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAAA,EAC7G;AACA,iBAAe,QAAQ,QAAQ,gBAAgB;AAC/C,SAAO,EAAE,QAAQ,QAAQ,QAAQ,QAAQ,CAAC,GAAG,QAAQ,MAAM,EAAE;AAC/D;AAEA,SAAS,WAAW,UAAqC,IAA+C;AACtG,QAAMA,YAAW,4BAA4B,QAAQ,EAAE,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AACpF,MAAI,CAACA,UAAU,OAAM,IAAI,UAAU,+BAA+B,EAAE,EAAE;AACtE,QAAM,SAAS,SAAS,QAAQ,KAAK,CAAC,SAAS,KAAK,aAAaA,UAAS,QAAQ;AAClF,SAAO;AAAA,IACL,UAAAA;AAAA,IACA;AAAA,IACA,GAAIA,UAAS,QAAQ,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC,SAAS,KAAK,OAAOA,UAAS,KAAK,EAAE,IAAI,CAAC;AAAA,IACxF,GAAIA,UAAS,kBAAkB;AAAA,MAC7B,eAAe,SAAS,QAAQ,KAAK,CAAC,SAAS,KAAK,aAAaA,UAAS,eAAe;AAAA,IAC3F,IAAI,CAAC;AAAA,EACP;AACF;AAUA,eAAsB,0BACpB,UACA,OACA,UACqC;AACrC,MAAI,UAAU,cAAc,UAAU,eAAgB,OAAM,IAAI,UAAU,0BAA0B;AACpG,QAAM,YAAY,4BAA4B,QAAQ,EAAE,OAAO,CAAC,SAAS,KAAK,UAAU,KAAK;AAC7F,MAAI,UAAU,kBAAkB,OAAO,SAAS,YAAY,YAAY;AACtE,UAAM,IAAI,UAAU,6EAA6E;AAAA,EACnG;AACA,QAAM,QAAuC,CAAC;AAC9C,MAAI,gBAAgB;AACpB,aAAWA,aAAY,WAAW;AAChC,QAAI,eAAe;AACjB,YAAM,KAAK,EAAE,IAAIA,UAAS,IAAI,OAAO,SAAS,UAAU,WAAW,yBAAyB,CAAC;AAC7F;AAAA,IACF;AACA,UAAM,UAAU,WAAW,UAAUA,UAAS,EAAE;AAChD,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI;AACF,iBAAW,iBAAiB,MAAM,SAAS,QAAQ,OAAO,GAAG,UAAU,cAAc;AAAA,IACvF,SAAS,OAAO;AACd,kBAAY,cAAc,KAAK;AAAA,IACjC,UAAE;AACA,UAAI,UAAU,gBAAgB;AAC5B,YAAI;AACF,oBAAU,gBAAgB,MAAM,SAAS,QAAS,OAAO,CAAC;AAC1D,cAAI,QAAQ,WAAW,YAAY;AACjC,4BAAgB;AAChB,wBAAY;AAAA,UACd;AAAA,QACF,QAAQ;AACN,0BAAgB;AAChB,sBAAY;AAAA,QACd;AAAA,MACF;AAAA,IACF;AACA,UAAM,KAAK;AAAA,MACT,IAAIA,UAAS;AAAA,MACb;AAAA,MACA,SAAS,YAAY,WAAW;AAAA,MAChC,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,MAC/B,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC7B,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACnC,CAAC;AAAA,EACH;AACA,SAAO,EAAE,IAAI,MAAM,MAAM,CAAC,SAAS,KAAK,YAAY,QAAQ,GAAG,OAAO,MAAM;AAC9E;AAGO,SAAS,2BAA2B,QAA4C;AACrF,QAAM,SAAS,OAAO,MAAM,OAAO,CAAC,SAAS,KAAK,YAAY,QAAQ,EAAE;AACxE,QAAM,QAAQ,CAAC,GAAG,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO,KAAK,IAAI,MAAM,IAAI,OAAO,MAAM,MAAM,EAAE;AACjG,aAAW,QAAQ,OAAO,OAAO;AAC/B,UAAM,KAAK,GAAG,KAAK,YAAY,WAAW,SAAS,MAAM,IAAI,KAAK,EAAE,GAAG,KAAK,YAAY,IAAI,KAAK,SAAS,KAAK,EAAE,EAAE;AAAA,EACrH;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACrJA,IAAM,OAAO;AACb,IAAM,WAAW;AACjB,IAAM,eAAe;AAErB,SAASC,mBAAkB,MAAuD;AAChF,SAAO,KAAK,KAAK,OAAO,CAAC,QAAQ,IAAI,UAAU,IAAI,SAAS,YAAY;AAC1E;AAEA,SAAS,6BAA6B,MAAiE;AACrG,SAAOA,mBAAkB,IAAI,EAAE,KAAK,CAAC,QAAQ,IAAI,aAAa,CAAC;AACjE;AAEA,SAASC,QAAO,OAAgD;AAC9D,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACtE,QACA;AACN;AAGO,SAAS,kCAAkC,OAA6C;AAC7F,QAAM,SAAmB,CAAC;AAC1B,QAAM,QAAQA,QAAO,KAAK;AAC1B,MAAI,CAAC,MAAO,QAAO,EAAE,IAAI,OAAO,QAAQ,CAAC,4BAA4B,EAAE;AACvE,MAAI,MAAM,kBAAkB,EAAG,QAAO,KAAK,yBAAyB;AACpE,QAAM,eAAe,MAAM,QAAQ,MAAM,OAAO,IAAI,MAAM,UAAU,CAAC;AACrE,MAAI,aAAa,SAAS,EAAG,QAAO,KAAK,4DAA4D;AAErG,QAAM,YAAY,oBAAI,IAAY;AAClC,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,cAAc,oBAAI,IAAoB;AAC5C,aAAW,CAAC,WAAW,OAAO,KAAK,aAAa,QAAQ,GAAG;AACzD,UAAM,OAAO,WAAW,SAAS;AACjC,UAAM,OAAOA,QAAO,OAAO;AAC3B,QAAI,CAAC,MAAM;AACT,aAAO,KAAK,GAAG,IAAI,oBAAoB;AACvC;AAAA,IACF;AACA,UAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,UAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC/D,QAAI,CAAC,KAAK,KAAK,QAAQ,EAAG,QAAO,KAAK,GAAG,IAAI,2CAA2C;AACxF,QAAI,UAAU,IAAI,QAAQ,EAAG,QAAO,KAAK,GAAG,IAAI,wBAAwB,KAAK,UAAU,QAAQ,CAAC,EAAE;AAClG,QAAI,SAAU,WAAU,IAAI,QAAQ;AACpC,QAAI,CAAC,KAAK,KAAK,MAAM,EAAG,QAAO,KAAK,GAAG,IAAI,yCAAyC;AACpF,QAAI,OAAQ,SAAQ,IAAI,MAAM;AAC9B,QAAI;AACF,UAAI,OAAO,KAAK,WAAW,SAAU,OAAM,IAAI,UAAU,QAAQ;AACjE,YAAM,SAAS,IAAI,IAAI,KAAK,MAAM;AAClC,UAAI,OAAO,aAAa,YAAY,OAAO,aAAa,OAAO,OAAO,UAAU,OAAO,QAAQ,OAAO,YAAY,OAAO,UAAU;AACjI,eAAO,KAAK,GAAG,IAAI,oEAAoE;AAAA,MACzF;AAAA,IACF,QAAQ;AACN,aAAO,KAAK,GAAG,IAAI,sCAAsC;AAAA,IAC3D;AACA,UAAM,SAASA,QAAO,KAAK,MAAM;AACjC,UAAM,eAAe,CAAC;AACtB,eAAW,OAAO,CAAC,SAAS,eAAe,mBAAmB,WAAW,WAAW,GAAY;AAC9F,mBAAa,GAAG,IAAI,OAAO,SAAS,GAAG,MAAM,WAAW,OAAO,OAAO,GAAG,CAAC,IAAI;AAC9E,UAAI,CAAC,aAAa,GAAG,EAAG,QAAO,KAAK,GAAG,IAAI,WAAW,GAAG,cAAc;AAAA,IACzE;AACA,UAAM,YAAY,OAAO,OAAO,YAAY,EAAE,KAAK,IAAQ;AAC3D,QAAI,QAAQ,IAAI,SAAS,EAAG,QAAO,KAAK,GAAG,IAAI,2CAA2C;AAC1F,QAAI,OAAO,OAAO,YAAY,EAAE,MAAM,OAAO,EAAG,SAAQ,IAAI,SAAS;AACrE,QAAI,KAAK,eAAe,UAAU,KAAK,eAAe,QAAQ;AAC5D,aAAO,KAAK,GAAG,IAAI,kCAAkC;AAAA,IACvD;AACA,QAAI,KAAK,eAAe,UAAU,aAAa,gBAAgB,UAAU,aAAa,gBAAgB,cAAc;AAClH,aAAO,KAAK,GAAG,IAAI,6DAA6D;AAAA,IAClF;AAEA,UAAM,SAAS,oBAAI,IAAY;AAC/B,UAAM,YAAY,MAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,OAAO,CAAC;AAC1D,QAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,UAAU,WAAW,EAAG,QAAO,KAAK,GAAG,IAAI,iCAAiC;AAC7G,UAAM,OAA+B,CAAC;AACtC,eAAW,CAAC,UAAU,MAAM,KAAK,UAAU,QAAQ,GAAG;AACpD,YAAM,UAAU,GAAG,IAAI,SAAS,QAAQ;AACxC,YAAM,MAAMA,QAAO,MAAM;AACzB,UAAI,CAAC,KAAK;AACR,eAAO,KAAK,GAAG,OAAO,oBAAoB;AAC1C;AAAA,MACF;AACA,YAAM,KAAK,OAAO,IAAI,OAAO,WAAW,IAAI,KAAK;AACjD,UAAI,CAAC,KAAK,KAAK,EAAE,EAAG,QAAO,KAAK,GAAG,OAAO,qCAAqC;AAC/E,UAAI,OAAO,IAAI,EAAE,EAAG,QAAO,KAAK,GAAG,OAAO,kBAAkB,KAAK,UAAU,EAAE,CAAC,EAAE;AAChF,UAAI,GAAI,QAAO,IAAI,EAAE;AACrB,UAAI,IAAI,SAAS,gBAAgB,IAAI,SAAS,SAAU,QAAO,KAAK,GAAG,OAAO,oCAAoC;AAClH,UAAI,OAAO,IAAI,WAAW,UAAW,QAAO,KAAK,GAAG,OAAO,yBAAyB;AACpF,YAAM,aAAa,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa,OAAO;AAChF,UAAI,CAAC,OAAO,cAAc,UAAU,KAAK,aAAa,EAAG,QAAO,KAAK,GAAG,OAAO,4CAA4C;AAC3H,UAAI,OAAO,IAAI,aAAa,YAAY,CAAC,SAAS,KAAK,IAAI,QAAQ,EAAG,QAAO,KAAK,GAAG,OAAO,iDAAiD;AAC7I,UAAI,IAAI,YAAY,WAAW,IAAI,YAAY,UAAU,IAAI,YAAY,QAAQ;AAC/E,eAAO,KAAK,GAAG,OAAO,uCAAuC;AAAA,MAC/D;AACA,UAAI,IAAI,SAAS,gBAAgB,IAAI,YAAY,QAAQ;AACvD,eAAO,KAAK,GAAG,OAAO,qDAAqD;AAAA,MAC7E;AACA,UAAI,IAAI,WAAW,QAAQ,aAAa,MAAM,OAAO,IAAI,kBAAkB,YAAY,CAAC,aAAa,KAAK,IAAI,aAAa,IAAI;AAC7H,eAAO,KAAK,GAAG,OAAO,mDAAmD;AAAA,MAC3E;AACA,UAAI,eAAe,KAAK,IAAI,cAAe,QAAO,KAAK,GAAG,OAAO,8CAA8C;AAC/G,UAAI,OAAO,IAAI,kBAAkB,YAAY,IAAI,eAAe;AAC9D,cAAM,QAAQ,GAAG,MAAM,IAAI,EAAE;AAC7B,cAAM,WAAW,YAAY,IAAI,IAAI,aAAa;AAClD,YAAI,YAAY,aAAa,MAAO,QAAO,KAAK,GAAG,OAAO,sCAAsC,QAAQ,EAAE;AAAA,YACrG,aAAY,IAAI,IAAI,eAAe,KAAK;AAAA,MAC/C;AACA,UAAI,IAAI,wBAAwB,QAAW;AACzC,YAAI,CAAC,OAAO,cAAc,IAAI,mBAAmB,KAAK,OAAO,IAAI,mBAAmB,KAAK,YAAY;AACnG,iBAAO,KAAK,GAAG,OAAO,iEAAiE;AAAA,QACzF;AACA,YAAI,IAAI,qBAAqB,gBAAgB,IAAI,qBAAqB,gBAAgB;AACpF,iBAAO,KAAK,GAAG,OAAO,wDAAwD;AAAA,QAChF;AAAA,MACF,WAAW,IAAI,kBAAkB;AAC/B,eAAO,KAAK,GAAG,OAAO,wDAAwD;AAAA,MAChF;AACA,WAAK,KAAK,GAAsC;AAAA,IAClD;AACA,QAAI,CAAC,KAAK,KAAK,CAAC,QAAQ,IAAI,UAAU,IAAI,SAAS,YAAY,EAAG,QAAO,KAAK,GAAG,IAAI,6CAA6C;AAClI,UAAM,UAAUA,QAAO,KAAK,OAAO;AACnC,QAAI,CAAC,QAAS,QAAO,KAAK,GAAG,IAAI,4BAA4B;AAC7D,QAAI,SAAS,sBAAsB,KAAM,QAAO,KAAK,GAAG,IAAI,yCAAyC;AACrG,QAAI,OAAO,SAAS,8BAA8B,UAAW,QAAO,KAAK,GAAG,IAAI,oDAAoD;AACpI,QAAI,SAAS,cAAc,KAAM,QAAO,KAAK,GAAG,IAAI,iCAAiC;AACrF,UAAM,OAAOA,QAAO,SAAS,cAAc;AAC3C,QAAI,SAAS,mBAAmB,UAAa,CAAC,KAAM,QAAO,KAAK,GAAG,IAAI,2CAA2C;AAClH,QAAI,MAAM;AACR,YAAM,UAAU,KAAK,KAAK,CAAC,QAAQ,IAAI,OAAO,KAAK,KAAK;AACxD,UAAI,CAAC,WAAW,CAAC,QAAQ,UAAU,QAAQ,SAAS,UAAU;AAC5D,eAAO,KAAK,GAAG,IAAI,8DAA8D;AAAA,MACnF,WAAW,QAAQ,YAAY,QAAQ;AACrC,eAAO,KAAK,GAAG,IAAI,gEAAgE;AAAA,MACrF;AACA,UAAI,OAAO,KAAK,iCAAiC,YAC7C,CAAC,OAAO,UAAU,KAAK,4BAA4B,KAAK,KAAK,+BAA+B,GAAG;AACjG,eAAO,KAAK,GAAG,IAAI,iFAAiF;AAAA,MACtG;AACA,UAAI,KAAK,UAAU,QAAQ,KAAK,gBAAgB,QAAQ,KAAK,YAAY,wBAAwB,KAAK,iBAAiB,SAAS;AAC9H,eAAO,KAAK,GAAG,IAAI,kHAAkH;AAAA,MACvI;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,OAAO,EAAG,QAAO,KAAK,wDAAwD;AAC1F,SAAO,OAAO,SAAS,EAAE,IAAI,OAAO,OAAO,IAAI,EAAE,IAAI,MAAM,MAA0C;AACvG;AAEA,SAAS,SAAS,OAAyE;AACzF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,CAAC,MAAM,OAAO,MAAM,UAAU,MAAM,OAAO,MAAM,iBAAiB,MAAM,IAAI,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,EAC5G;AACF;AAMO,SAAS,4BAA4B,UAAkE;AAC5G,QAAM,aAAa,kCAAkC,QAAQ;AAC7D,MAAI,CAAC,WAAW,GAAI,OAAM,IAAI,UAAU,wCAAwC,WAAW,OAAO,KAAK,IAAI,CAAC,EAAE;AAC9G,MAAI,SAAS,QAAQ,KAAK,CAAC,SAAS,KAAK,eAAe,UAAU,KAAK,OAAO,gBAAgB,SAAS,KAAK,OAAO,oBAAoB,KAAK,GAAG;AAC7I,UAAM,IAAI,UAAU,8HAA8H;AAAA,EACpJ;AACA,QAAM,YAAyC,CAAC;AAChD,aAAW,QAAQ,SAAS,SAAS;AACnC,eAAW,OAAO,KAAK,KAAK,OAAO,CAAC,cAAc,UAAU,MAAM,GAAG;AACnE,gBAAU,KAAK,SAAS,EAAE,OAAO,YAAY,MAAM,oBAAoB,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,IAAI,GAAG,CAAC,CAAC;AACrI,UAAI,IAAI,aAAa,GAAG;AACtB,kBAAU,KAAK,SAAS,EAAE,OAAO,YAAY,MAAM,iBAAiB,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,IAAI,GAAG,CAAC,CAAC;AAClI,kBAAU,KAAK,SAAS,EAAE,OAAO,YAAY,MAAM,2BAA2B,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,IAAI,GAAG,CAAC,CAAC;AAC5I,kBAAU,KAAK,SAAS,EAAE,OAAO,YAAY,MAAM,4BAA4B,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,IAAI,GAAG,CAAC,CAAC;AAC7I,mBAAW,WAAW,SAAS,QAAQ,OAAO,CAAC,cAAc,UAAU,aAAa,KAAK,QAAQ,GAAG;AAClG,oBAAU,KAAK,SAAS;AAAA,YACtB,OAAO;AAAA,YAAY,MAAM;AAAA,YAA2B,UAAU,KAAK;AAAA,YAAU,QAAQ,KAAK;AAAA,YAC1F,OAAO,IAAI;AAAA,YAAI,iBAAiB,QAAQ;AAAA,UAC1C,CAAC,CAAC;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AACA,eAAW,OAAOD,mBAAkB,IAAI,GAAG;AACzC,gBAAU,KAAK,SAAS,EAAE,OAAO,YAAY,MAAM,iBAAiB,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,IAAI,GAAG,CAAC,CAAC;AAClI,gBAAU,KAAK,SAAS;AAAA,QACtB,OAAO;AAAA,QAAgB,MAAM,IAAI,aAAa,IAAI,gBAAgB;AAAA,QAClE,UAAU,KAAK;AAAA,QAAU,QAAQ,KAAK;AAAA,QAAQ,OAAO,IAAI;AAAA,MAC3D,CAAC,CAAC;AAAA,IACJ;AACA,UAAM,OAAO,6BAA6B,IAAI;AAC9C,QAAI,MAAM;AACR,gBAAU,KAAK,SAAS,EAAE,OAAO,gBAAgB,MAAM,sBAAsB,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,KAAK,GAAG,CAAC,CAAC;AAC5I,gBAAU,KAAK,SAAS,EAAE,OAAO,gBAAgB,MAAM,WAAW,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,KAAK,GAAG,CAAC,CAAC;AACjI,gBAAU,KAAK,SAAS,EAAE,OAAO,gBAAgB,MAAM,iBAAiB,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,KAAK,GAAG,CAAC,CAAC;AACvI,UAAI,KAAK,QAAQ,2BAA2B;AAC1C,kBAAU,KAAK,SAAS,EAAE,OAAO,gBAAgB,MAAM,+BAA+B,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,KAAK,GAAG,CAAC,CAAC;AACrJ,kBAAU,KAAK,SAAS,EAAE,OAAO,YAAY,MAAM,4BAA4B,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,KAAK,GAAG,CAAC,CAAC;AAC9I,kBAAU,KAAK,SAAS,EAAE,OAAO,YAAY,MAAM,6BAA6B,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,KAAK,GAAG,CAAC,CAAC;AAAA,MACjJ;AACA,UAAI,KAAK,QAAQ,gBAAgB;AAC/B,kBAAU,KAAK,SAAS;AAAA,UACtB,OAAO;AAAA,UAAgB,MAAM;AAAA,UAAc,UAAU,KAAK;AAAA,UAAU,QAAQ,KAAK;AAAA,UACjF,OAAO,KAAK,QAAQ,eAAe;AAAA,QACrC,CAAC,CAAC;AACF,kBAAU,KAAK,SAAS;AAAA,UACtB,OAAO;AAAA,UAAY,MAAM;AAAA,UAAwB,UAAU,KAAK;AAAA,UAAU,QAAQ,KAAK;AAAA,UACvF,OAAO,KAAK,QAAQ,eAAe;AAAA,QACrC,CAAC,CAAC;AACF,kBAAU,KAAK,SAAS;AAAA,UACtB,OAAO;AAAA,UAAY,MAAM;AAAA,UAAuB,UAAU,KAAK;AAAA,UAAU,QAAQ,KAAK;AAAA,UACtF,OAAO,KAAK,QAAQ,eAAe;AAAA,QACrC,CAAC,CAAC;AAAA,MACJ;AACA,gBAAU,KAAK,SAAS,EAAE,OAAO,YAAY,MAAM,uBAAuB,UAAU,KAAK,UAAU,QAAQ,KAAK,QAAQ,OAAO,KAAK,GAAG,CAAC,CAAC;AAAA,IAC3I;AAAA,EACF;AACA,SAAO;AACT;","names":["scenario","activeMemberships","record"]}
1
+ {"version":3,"sources":["../src/testing-commercial.ts","../src/testing-probe.ts","../src/testing-runner.ts","../src/testing-release.ts","../src/testing.ts"],"sourcesContent":["import type { ChapterAcceptanceCommercialCase, ChapterAcceptanceSku } from \"./testing-contract\";\n\nconst object = (value: unknown): Record<string, unknown> | null =>\n value !== null && typeof value === \"object\" && !Array.isArray(value) ? value as Record<string, unknown> : null;\nconst id = (value: unknown): boolean => typeof value === \"string\" && /^[a-z0-9][a-z0-9_.:-]{1,159}$/.test(value);\nconst time = (value: unknown): value is number => Number.isSafeInteger(value) && Number(value) > 0;\n\n/** Keep commercial acceptance vectors separate from base SKUs and fail before provider writes. */\nexport function validateCommercialCases(value: unknown, skus: readonly ChapterAcceptanceSku[], path: string): string[] {\n if (value === undefined) return [];\n if (!Array.isArray(value) || !value.length || value.length > 32) return [`${path} must be a non-empty array of at most 32 cases`];\n const errors: string[] = [];\n const ids = new Set<string>();\n for (const [index, raw] of value.entries()) {\n const item = object(raw);\n const at = `${path}[${index}]`;\n if (!item) { errors.push(`${at} must be an object`); continue; }\n if (!id(item.id) || ids.has(String(item.id))) errors.push(`${at}.id must be a unique stable id`);\n ids.add(String(item.id));\n const sku = skus.find(candidate => candidate.id === item.skuId && candidate.active && candidate.kind === \"membership\" && candidate.priceCents > 0);\n if (!sku) errors.push(`${at}.skuId must name an active paid base membership SKU`);\n if (sku?.compareAtPriceCents !== undefined || sku?.discountDuration !== undefined) {\n errors.push(`${at} must not combine a discounted SKU with a separate commercial policy`);\n }\n if (!id(item.offeringVersionId)) errors.push(`${at}.offeringVersionId is required`);\n if (typeof item.founding !== \"boolean\" || (item.founding && !id(item.cohortPolicyVersionId)) ||\n (item.cohortPolicyVersionId !== undefined && !id(item.cohortPolicyVersionId))) errors.push(`${at}.founding requires a stable cohort policy identity`);\n if (!time(item.purchasedAt) || !time(item.initialTermEndsAt) || item.initialTermEndsAt <= item.purchasedAt) {\n errors.push(`${at} must specify a purchase instant and a later initial term end`);\n }\n const discount = object(item.discount);\n if (item.discount !== undefined && (!discount || !id(discount.policyVersionId) ||\n !Number.isInteger(discount.percentOffBps) || Number(discount.percentOffBps) <= 0 || Number(discount.percentOffBps) >= 10000 ||\n ![\"first_term\", \"while_active\", \"fixed_end\"].includes(String(discount.duration)) ||\n (discount.duration === \"fixed_end\" ? !time(discount.endsAt) || Number(discount.endsAt) <= Number(item.purchasedAt) : discount.endsAt !== undefined))) {\n errors.push(`${at}.discount must specify a version, percentage, and explicit expiry policy`);\n }\n if (sku) {\n const due = Math.round(sku.priceCents * (10000 - Number(discount?.percentOffBps ?? 0)) / 10000);\n const ongoing = discount?.duration === \"while_active\" || (discount?.duration === \"fixed_end\" && Number(discount.endsAt) > Number(item.initialTermEndsAt));\n if (item.dueTodayCents !== due || item.renewalCents !== (ongoing ? due : sku.priceCents)) {\n errors.push(`${at} expected initial and renewal amounts must match the separate policy on the base price`);\n }\n }\n }\n return errors;\n}\n\n/** Compare real observed checkout terms against a separately authored acceptance vector. */\nexport function assertCommercialQuote(expected: ChapterAcceptanceCommercialCase, sku: ChapterAcceptanceSku, actual: unknown): boolean {\n const quote = object(actual), lines = object(quote?.lineItems), terms = object(quote?.commercial);\n return Boolean(quote && terms && sku.id === expected.skuId && quote.tierId === expected.skuId &&\n quote.currency === sku.currency && quote.interval === sku.billing && lines?.standardCents === sku.priceCents &&\n lines.discountCents === sku.priceCents - expected.dueTodayCents && lines.dueTodayCents === expected.dueTodayCents &&\n terms.offeringVersionId === expected.offeringVersionId && terms.initialTermEndsAt === expected.initialTermEndsAt &&\n terms.renewalCents === expected.renewalCents && terms.autoRenew === true &&\n terms.discountPolicyVersionId === expected.discount?.policyVersionId &&\n terms.discountDuration === expected.discount?.duration);\n}\n","import type {\n ChapterAcceptanceManifest,\n ChapterAcceptanceTarget,\n ChapterJoinContractFinding,\n ChapterJoinContractProbeResult,\n} from \"./testing-contract\";\nimport { validateChapterAcceptanceManifest } from \"./testing\";\n\nconst MAX_BODY_BYTES = 64 * 1024;\nconst TIMEOUT_MS = 10_000;\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown> : null;\n}\n\nasync function readBoundedJson(response: Response, signal: AbortSignal): Promise<unknown> {\n const reader = response.body?.getReader();\n if (!reader) throw new Error(\"invalid_json\");\n const chunks: Uint8Array[] = [];\n let size = 0;\n const abort = () => { void reader.cancel().catch(() => {}); };\n signal.addEventListener(\"abort\", abort, { once: true });\n try {\n if (signal.aborted) throw new Error(\"response_failed\");\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > MAX_BODY_BYTES) throw new Error(\"response_too_large\");\n chunks.push(value);\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.byteLength; }\n try { return JSON.parse(new TextDecoder().decode(bytes)); }\n catch { throw new Error(\"invalid_json\"); }\n } finally {\n signal.removeEventListener(\"abort\", abort);\n await reader.cancel().catch(() => {});\n reader.releaseLock();\n }\n}\n\ntype ProbeResponse = { status: number; json?: unknown; error?: string; identity?: Record<string, unknown> };\n\nasync function probe(url: string, fetcher: typeof fetch, json: boolean): Promise<ProbeResponse> {\n const controller = new AbortController();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<ProbeResponse>((resolve) => {\n timer = setTimeout(() => {\n controller.abort();\n resolve({ status: 0, error: \"request_timeout\" });\n }, TIMEOUT_MS);\n });\n try {\n return await Promise.race([timeout, (async (): Promise<ProbeResponse> => {\n let response: Response;\n try {\n response = await fetcher(url, {\n headers: { \"cache-control\": \"no-cache\" }, redirect: \"manual\", signal: controller.signal,\n });\n } catch { return { status: 0, error: \"request_failed\" }; }\n if (!json || !response.ok) {\n await response.body?.cancel().catch(() => {});\n return { status: response.status };\n }\n try {\n return {\n status: response.status, json: await readBoundedJson(response, controller.signal),\n identity: Object.fromEntries([\"app-id\", \"chapter-id\", \"data-environment\", \"runtime\"].map((name) =>\n [name, slug(response.headers.get(`x-odla-${name}`) ?? undefined)])),\n };\n }\n catch (error) {\n const code = error instanceof Error && [\"invalid_json\", \"response_too_large\"].includes(error.message)\n ? error.message : \"response_failed\";\n return { status: response.status, error: code };\n }\n })()]);\n } finally { clearTimeout(timer); }\n}\n\n// Findings are durable CI/PM data, not a mirror of an untrusted HTTP body.\nfunction slug(value: unknown): unknown {\n return value === undefined ? undefined : typeof value === \"string\" && /^[a-z0-9][a-z0-9-]{1,62}$/.test(value) ? value : \"invalid_value\";\n}\nfunction amount(value: unknown): unknown {\n return value === undefined ? undefined : Number.isSafeInteger(value) && Number(value) >= 0 ? value : \"invalid_value\";\n}\nfunction boolean(value: unknown): unknown {\n return value === undefined ? undefined : typeof value === \"boolean\" ? value : \"invalid_value\";\n}\n\nfunction activeMemberships(site: ChapterAcceptanceTarget) {\n return site.skus.filter((sku) => sku.active && sku.kind === \"membership\");\n}\n\n/**\n * Probe public deployed join contracts without creating applications or provider objects.\n * Each request, including its body, is limited to ten seconds and 64 KiB. Redirects\n * are refused. Malformed responses become per-target findings, never raw bodies\n * or exception text; one failed target does not suppress the remaining targets.\n */\nexport async function probeChapterJoinContracts(\n manifest: ChapterAcceptanceManifest,\n fetcher: typeof fetch = fetch,\n): Promise<ChapterJoinContractProbeResult> {\n const validation = validateChapterAcceptanceManifest(manifest);\n if (!validation.ok) throw new TypeError(`invalid Chapter acceptance manifest: ${validation.errors.join(\"; \")}`);\n const findings: ChapterJoinContractFinding[] = [];\n for (const site of manifest.targets) {\n const [health, configResponse] = await Promise.all([\n probe(`${site.origin}/api/health`, fetcher, true),\n probe(`${site.origin}/api/join-config`, fetcher, true),\n ]);\n const targetNote = (path: string, expected: unknown, actual: unknown): void => {\n if (JSON.stringify(expected) !== JSON.stringify(actual)) findings.push({ targetId: site.targetId, siteId: site.siteId, path, expected, actual });\n };\n targetNote(\"/api/health status\", 200, health.error ?? health.status);\n if (health.status === 200 && !health.error) targetNote(\"/api/health ok\", true, boolean(record(health.json)?.ok));\n if (health.status === 200 && !health.error) {\n for (const [name, expected] of Object.entries({\n \"app-id\": site.target.appId, \"chapter-id\": site.target.chapterId,\n \"data-environment\": site.target.dataEnvironment, \"runtime\": site.target.runtime,\n })) targetNote(`/api/health x-odla-${name}`, expected, health.identity?.[name]);\n }\n targetNote(\"/api/join-config status\", 200, configResponse.status || configResponse.error);\n if (configResponse.status !== 200) continue;\n if (configResponse.error) {\n targetNote(\"/api/join-config JSON\", \"object\", configResponse.error === \"invalid_json\" ? \"invalid JSON\" : configResponse.error);\n continue;\n }\n const config = record(configResponse.json);\n if (!config) {\n targetNote(\"/api/join-config JSON\", \"object\", \"invalid shape\");\n continue;\n }\n targetNote(\"id\", site.target.chapterId, slug(config.id));\n const actualTiers = Array.isArray(config.tiers) ? config.tiers : [];\n const expectedTiers = activeMemberships(site).map((sku) => ({\n id: sku.id, priceCents: sku.priceCents, currency: sku.currency,\n interval: sku.billing, free: sku.priceCents === 0,\n }));\n const projected = actualTiers.map((tier) => {\n const value = record(tier);\n if (!value) return \"invalid_tier\";\n return {\n id: slug(value.id), priceCents: amount(value.priceCents),\n currency: value.currency === undefined ? undefined : typeof value.currency === \"string\" && /^[a-z]{3}$/.test(value.currency) ? value.currency : \"invalid_value\",\n interval: value.interval === undefined ? undefined : [\"month\", \"year\", \"once\"].includes(String(value.interval)) ? value.interval : \"invalid_value\",\n free: boolean(value.free),\n };\n });\n targetNote(\"tiers\", expectedTiers, projected);\n targetNote(\"paymentsReady\", expectedTiers.some((tier) => !tier.free), boolean(config.paymentsReady));\n }\n return { ok: findings.length === 0, findings };\n}\n","import type {\n ChapterAcceptanceCaseResult,\n ChapterAcceptanceCleanupEvidence,\n ChapterAcceptanceEvidence,\n ChapterAcceptanceExecutionContext,\n ChapterAcceptanceExecutor,\n ChapterAcceptanceManifest,\n ChapterAcceptanceProviderReference,\n ChapterAcceptanceRunResult,\n} from \"./testing-contract\";\nimport { planChapterAcceptanceMatrix } from \"./testing\";\n\nconst SAFE_LABEL = /^[a-z0-9][a-z0-9._:-]{0,159}$/;\nconst SAFE_REFERENCE = /^[A-Za-z0-9_:.=-]{3,240}$/;\nconst CREDENTIAL = /(?:^|[_.:-])(?:sk|rk|pk)_(?:test|live)_|whsec_|_secret_|eyJ[A-Za-z0-9_-]+\\./i;\nconst ERROR_CODES = new Set([\"invalid_evidence\", \"assertion_failed\", \"preflight_failed\", \"unsupported_scenario\", \"execution_failed\"]);\n\nfunction safeValue(value: string, pattern: RegExp): boolean {\n return pattern.test(value) && !CREDENTIAL.test(value);\n}\n\nfunction safeErrorCode(error: unknown): string {\n if (error && typeof error === \"object\") {\n const code = (error as { code?: unknown }).code;\n if (typeof code === \"string\" && ERROR_CODES.has(code)) return code;\n }\n return \"execution_failed\";\n}\n\nfunction validateLabels(values: readonly string[], path: string): void {\n if (!Array.isArray(values) || values.length === 0) throw Object.assign(new TypeError(`${path} must be non-empty`), { code: \"invalid_evidence\" });\n if (values.length > 64 || values.some((value) => typeof value !== \"string\" || !safeValue(value, SAFE_LABEL))) {\n throw Object.assign(new TypeError(`${path} contains an unsafe or unbounded label`), { code: \"invalid_evidence\" });\n }\n}\n\nfunction validateReferences(values: readonly ChapterAcceptanceProviderReference[] | undefined): void {\n if (values === undefined) return;\n if (!Array.isArray(values) || values.length > 64) throw Object.assign(new TypeError(\"references must be bounded\"), { code: \"invalid_evidence\" });\n const kinds = new Set([\"stripe_event\", \"stripe_object\", \"clerk_user\", \"calendar_event\", \"email_message\", \"event_digest\"]);\n for (const reference of values) {\n if (!reference || !kinds.has(reference.kind) || typeof reference.value !== \"string\" ||\n !safeValue(reference.value, SAFE_REFERENCE) || reference.value.includes(\"@\")) {\n throw Object.assign(new TypeError(\"references may contain only opaque provider ids or digests\"), { code: \"invalid_evidence\" });\n }\n }\n}\n\nfunction validateEvidence(evidence: ChapterAcceptanceEvidence, provider: boolean): ChapterAcceptanceEvidence {\n if (!evidence || typeof evidence !== \"object\") throw Object.assign(new TypeError(\"executor returned no evidence\"), { code: \"invalid_evidence\" });\n validateLabels(evidence.checks, \"evidence.checks\");\n validateReferences(evidence.references);\n if ((provider || evidence.deploymentVersion !== undefined) &&\n (typeof evidence.deploymentVersion !== \"string\" || !safeValue(evidence.deploymentVersion, SAFE_REFERENCE))) {\n throw Object.assign(new TypeError(\"provider evidence requires a safe deploymentVersion\"), { code: \"invalid_evidence\" });\n }\n // Copy only the validated wire contract. Never retain provider response objects,\n // extra fields, custom toJSON methods, or arrays that an adapter can later mutate.\n return {\n checks: [...evidence.checks],\n ...(evidence.deploymentVersion !== undefined ? { deploymentVersion: evidence.deploymentVersion } : {}),\n ...(evidence.references !== undefined ? {\n references: evidence.references.map(({ kind, value }) => ({ kind, value })),\n } : {}),\n };\n}\n\nfunction validateCleanup(cleanup: ChapterAcceptanceCleanupEvidence): ChapterAcceptanceCleanupEvidence {\n if (!cleanup || (cleanup.status !== \"complete\" && cleanup.status !== \"incomplete\")) {\n throw Object.assign(new TypeError(\"executor returned invalid cleanup evidence\"), { code: \"cleanup_failed\" });\n }\n validateLabels(cleanup.checks, \"cleanup.checks\");\n return { status: cleanup.status, checks: [...cleanup.checks] };\n}\n\nfunction contextFor(manifest: ChapterAcceptanceManifest, id: string): ChapterAcceptanceExecutionContext {\n const scenario = planChapterAcceptanceMatrix(manifest).find((item) => item.id === id);\n if (!scenario) throw new TypeError(`unknown acceptance scenario ${id}`);\n const target = manifest.targets.find((item) => item.targetId === scenario.targetId)!;\n return {\n scenario,\n target,\n ...(scenario.skuId ? { sku: target.skus.find((item) => item.id === scenario.skuId) } : {}),\n ...(scenario.parentSkuId ? { parentSku: target.skus.find((item) => item.id === scenario.parentSkuId) } : {}),\n ...(scenario.commercialCaseId ? { commercialCase: target.commercialCases?.find(item => item.id === scenario.commercialCaseId) } : {}),\n ...(scenario.siblingTargetId ? {\n siblingTarget: manifest.targets.find((item) => item.targetId === scenario.siblingTargetId),\n } : {}),\n };\n}\n\n/**\n * Execute one suite serially. Provider runs fail before their first mutation\n * unless the app supplies cleanup, then invoke cleanup after every attempted\n * case even when execution throws. Unconfirmed cleanup stops subsequent cases;\n * those cases fail with `not_run_cleanup_failed` and are never executed.\n * Evidence is copied only after validation; raw provider errors and extra fields\n * are never retained. Adapter check labels must not contain personal data.\n */\nexport async function runChapterAcceptanceSuite(\n manifest: ChapterAcceptanceManifest,\n suite: \"hermetic\" | \"provider_dev\",\n executor: ChapterAcceptanceExecutor,\n): Promise<ChapterAcceptanceRunResult> {\n if (suite !== \"hermetic\" && suite !== \"provider_dev\") throw new TypeError(\"unknown acceptance suite\");\n const scenarios = planChapterAcceptanceMatrix(manifest).filter((item) => item.suite === suite);\n if (suite === \"provider_dev\" && typeof executor.cleanup !== \"function\") {\n throw new TypeError(\"provider_dev acceptance requires a cleanup executor before any case can run\");\n }\n const cases: ChapterAcceptanceCaseResult[] = [];\n let cleanupFailed = false;\n for (const scenario of scenarios) {\n if (cleanupFailed) {\n cases.push({ id: scenario.id, suite, outcome: \"failed\", errorCode: \"not_run_cleanup_failed\" });\n continue;\n }\n const context = contextFor(manifest, scenario.id);\n let evidence: ChapterAcceptanceEvidence | undefined;\n let errorCode: string | undefined;\n let cleanup: ChapterAcceptanceCleanupEvidence | undefined;\n try {\n evidence = validateEvidence(await executor.execute(context), suite === \"provider_dev\");\n } catch (error) {\n errorCode = safeErrorCode(error);\n } finally {\n if (suite === \"provider_dev\") {\n try {\n cleanup = validateCleanup(await executor.cleanup!(context));\n if (cleanup.status !== \"complete\") {\n cleanupFailed = true;\n errorCode = \"cleanup_incomplete\";\n }\n } catch {\n cleanupFailed = true;\n errorCode = \"cleanup_failed\";\n }\n }\n }\n cases.push({\n id: scenario.id,\n suite,\n outcome: errorCode ? \"failed\" : \"passed\",\n ...(evidence ? { evidence } : {}),\n ...(cleanup ? { cleanup } : {}),\n ...(errorCode ? { errorCode } : {}),\n });\n }\n return { ok: cases.every((item) => item.outcome === \"passed\"), suite, cases };\n}\n\n/** PII-free line report suitable for CI logs and PM evidence. */\nexport function formatChapterAcceptanceRun(result: ChapterAcceptanceRunResult): string {\n const passed = result.cases.filter((item) => item.outcome === \"passed\").length;\n const lines = [`${result.ok ? \"ok\" : \"failed\"}: ${result.suite} ${passed}/${result.cases.length}`];\n for (const item of result.cases) {\n lines.push(`${item.outcome === \"passed\" ? \"PASS\" : \"FAIL\"} ${item.id}${item.errorCode ? ` ${item.errorCode}` : \"\"}`);\n }\n return lines.join(\"\\n\");\n}\n","/** A release proof is tied to a reviewed source commit and one exact dev deployment. */\nexport interface ChapterReleaseTarget {\n targetId: string;\n appId: string;\n chapterId: string;\n runtime: string;\n environment: \"dev\";\n dataEnvironment: \"dev\";\n stripeMode: \"test\";\n sourceCommit: string;\n deploymentVersion: string;\n}\n\n/** Required behavior is defined independently of currently enabled feature flags. */\nexport interface ChapterReleaseRequirement {\n id: string;\n targetId: string;\n phase: \"deterministic\" | \"deployed_contract\" | \"provider_dev\" | \"browser_dev\";\n assertions: readonly string[];\n /** Each provider kind needs at least one opaque id/digest from the real attempt. */\n providers: readonly (\"stripe\" | \"clerk\" | \"calendar\" | \"email\")[];\n cleanup: readonly string[];\n}\n\n/** An independent release contract, not a list inferred from whichever tests happened to run. */\nexport interface ChapterReleasePlan {\n schemaVersion: 1;\n targets: readonly ChapterReleaseTarget[];\n requirements: readonly ChapterReleaseRequirement[];\n}\n\n/** Structured result from an actual driver; this completeness check does not execute or authenticate a driver. */\nexport interface ChapterReleaseProof {\n requirementId: string;\n target: ChapterReleaseTarget;\n phase: ChapterReleaseRequirement[\"phase\"];\n outcome: \"passed\" | \"failed\" | \"blocked\";\n assertions: Readonly<Record<string, boolean>>;\n references: readonly { provider: ChapterReleaseRequirement[\"providers\"][number]; id: string }[];\n cleanup: Readonly<Record<string, boolean>>;\n}\n\n/** Bounded release blockers. Passing requests a human review, never permission to deploy. */\nexport interface ChapterReleaseAssessment {\n readyForReview: boolean;\n productionAuthorized: false;\n required: number;\n passed: number;\n blockers: readonly { requirementId: string; code: string }[];\n}\n\nconst ID = /^[a-z0-9][a-z0-9_.:-]{1,199}$/;\nconst validId = (value: unknown): value is string => typeof value === \"string\" && ID.test(value);\nconst opaque = (value: unknown): value is string => typeof value === \"string\" &&\n /^[A-Za-z0-9][A-Za-z0-9_:-]{2,159}$/.test(value) && !/(?:sk|rk|pk|whsec)_(?:test_|live_)?|_secret_|bearer|password|token/i.test(value);\nconst keys = [\"targetId\", \"appId\", \"chapterId\", \"runtime\", \"environment\", \"dataEnvironment\", \"stripeMode\", \"sourceCommit\", \"deploymentVersion\"] as const;\n\n/**\n * Require a complete, exact-candidate release evidence set. Missing, duplicate,\n * failed, stale, wrong-runtime, skipped, or incompletely cleaned attempts block\n * review. This is evidence validation, not provider execution: callers must use\n * real drivers and retain their independently inspectable run artifacts.\n */\nexport function assessChapterReleaseEvidence(plan: ChapterReleasePlan, proofs: readonly ChapterReleaseProof[]): ChapterReleaseAssessment {\n const blockers: { requirementId: string; code: string }[] = [];\n const block = (requirementId: string, code: string) => blockers.push({ requirementId, code });\n const targets = new Map<string, ChapterReleaseTarget>();\n if (!plan || plan.schemaVersion !== 1 || !Array.isArray(plan.targets) || !plan.targets.length ||\n plan.targets.length > 64 || !Array.isArray(plan.requirements) || !plan.requirements.length ||\n plan.requirements.length > 4096 || !Array.isArray(proofs) || proofs.length > 8192) {\n return { readyForReview: false, productionAuthorized: false, required: 0, passed: 0,\n blockers: [{ requirementId: \"plan\", code: \"invalid_release_plan\" }] };\n }\n for (const target of plan.targets) {\n if (!target || !validId(target.targetId) || targets.has(target.targetId) ||\n ![target.appId, target.chapterId, target.runtime].every(validId) ||\n target.environment !== \"dev\" || target.dataEnvironment !== \"dev\" || target.stripeMode !== \"test\" ||\n typeof target.sourceCommit !== \"string\" || !/^[0-9a-f]{40}$/.test(target.sourceCommit) || !opaque(target.deploymentVersion)) {\n block(\"plan\", \"invalid_or_undeployed_target\");\n continue;\n }\n targets.set(target.targetId, target);\n }\n const requirementIds = new Set<string>();\n let passed = 0;\n for (const requirement of plan.requirements) {\n if (!requirement || !validId(requirement.id) || requirementIds.has(requirement.id) ||\n ![\"deterministic\", \"deployed_contract\", \"provider_dev\", \"browser_dev\"].includes(requirement.phase) ||\n !Array.isArray(requirement.assertions) || !requirement.assertions.length ||\n !requirement.assertions.every(validId) || new Set(requirement.assertions).size !== requirement.assertions.length ||\n !Array.isArray(requirement.providers) || requirement.providers.some((kind: string) => ![\"stripe\", \"clerk\", \"calendar\", \"email\"].includes(kind)) ||\n !Array.isArray(requirement.cleanup) || !requirement.cleanup.every(validId) ||\n (requirement.phase === \"provider_dev\" && (!requirement.providers.length || !requirement.cleanup.length))) {\n block(\"plan\", \"invalid_requirement\");\n continue;\n }\n requirementIds.add(requirement.id);\n const target = targets.get(requirement.targetId);\n if (!target) { block(requirement.id, \"missing_candidate_target\"); continue; }\n const matching = proofs.filter((proof) => proof?.requirementId === requirement.id);\n if (matching.length !== 1) { block(requirement.id, matching.length ? \"duplicate_proof\" : \"missing_proof\"); continue; }\n const proof = matching[0]!;\n const before = blockers.length;\n if (!proof.target || keys.some((key) => proof.target[key] !== target[key])) block(requirement.id, \"candidate_mismatch\");\n if (proof.phase !== requirement.phase) block(requirement.id, \"wrong_execution_phase\");\n if (proof.outcome !== \"passed\") block(requirement.id, \"attempt_not_passed\");\n if (!proof.assertions || requirement.assertions.some((id: string) => proof.assertions[id] !== true)) block(requirement.id, \"assertions_incomplete\");\n if (!Array.isArray(proof.references) || proof.references.some((reference: ChapterReleaseProof[\"references\"][number]) => !reference || !opaque(reference.id) ||\n ![\"stripe\", \"clerk\", \"calendar\", \"email\"].includes(reference.provider)) ||\n requirement.providers.some((provider: string) => !proof.references.some((reference: ChapterReleaseProof[\"references\"][number]) => reference.provider === provider))) block(requirement.id, \"provider_evidence_incomplete\");\n if (!proof.cleanup || requirement.cleanup.some((id: string) => proof.cleanup[id] !== true)) block(requirement.id, \"cleanup_incomplete\");\n if (blockers.length === before) passed++;\n }\n if (proofs.some((proof) => !proof || !requirementIds.has(proof.requirementId))) block(\"plan\", \"unexpected_proof\");\n for (const target of targets.values()) {\n if (!plan.requirements.some((requirement) => requirement?.targetId === target.targetId)) block(\"plan\", \"uncovered_target\");\n }\n return { readyForReview: blockers.length === 0, productionAuthorized: false, required: plan.requirements.length, passed, blockers };\n}\n","import type {\n ChapterAcceptanceManifest, ChapterAcceptanceScenario, ChapterAcceptanceSku, ChapterAcceptanceTarget, ChapterAcceptanceValidation,\n} from \"./testing-contract\";\nimport { validateCommercialCases } from \"./testing-commercial\";\nexport { assertCommercialQuote } from \"./testing-commercial\";\nexport type * from \"./testing-contract\";\nexport { probeChapterJoinContracts } from \"./testing-probe\";\nexport { formatChapterAcceptanceRun, runChapterAcceptanceSuite } from \"./testing-runner\";\nexport { assessChapterReleaseEvidence } from \"./testing-release\";\nexport type * from \"./testing-release\";\n\nconst SLUG = /^[a-z0-9][a-z0-9-]{1,62}$/;\nconst CURRENCY = /^[a-z]{3}$/;\nconst STRIPE_PRICE = /^price_[A-Za-z0-9]{8,}$/;\n\nfunction activeMemberships(site: ChapterAcceptanceTarget): ChapterAcceptanceSku[] {\n return site.skus.filter((sku) => sku.active && sku.kind === \"membership\");\n}\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null;\n}\n\n/** Validate the exact facts a multi-site acceptance run needs before it writes anywhere. */\nexport function validateChapterAcceptanceManifest(value: unknown): ChapterAcceptanceValidation {\n const errors: string[] = [];\n const input = record(value);\n if (!input) return { ok: false, errors: [\"manifest must be an object\"] };\n if (input.schemaVersion !== 1) errors.push(\"schemaVersion must be 1\");\n const inputTargets = Array.isArray(input.targets) ? input.targets : [];\n if (inputTargets.length < 2) errors.push(\"targets must contain at least two deployed Chapter targets\");\n\n const targetIds = new Set<string>();\n const siteIds = new Set<string>();\n const targets = new Set<string>();\n const priceOwners = new Map<string, string>();\n for (const [siteIndex, rawSite] of inputTargets.entries()) {\n const path = `targets[${siteIndex}]`;\n const site = record(rawSite);\n if (!site) {\n errors.push(`${path} must be an object`);\n continue;\n }\n const targetId = typeof site.targetId === \"string\" ? site.targetId : \"\";\n const siteId = typeof site.siteId === \"string\" ? site.siteId : \"\";\n if (!SLUG.test(targetId)) errors.push(`${path}.targetId must be a stable lowercase slug`);\n if (targetIds.has(targetId)) errors.push(`${path}.targetId duplicates ${JSON.stringify(targetId)}`);\n if (targetId) targetIds.add(targetId);\n if (!SLUG.test(siteId)) errors.push(`${path}.siteId must be a stable lowercase slug`);\n if (siteId) siteIds.add(siteId);\n try {\n if (typeof site.origin !== \"string\") throw new TypeError(\"origin\");\n const origin = new URL(site.origin);\n if (origin.protocol !== \"https:\" || origin.pathname !== \"/\" || origin.search || origin.hash || origin.username || origin.password) {\n errors.push(`${path}.origin must be an HTTPS origin without a path, query, or fragment`);\n }\n } catch {\n errors.push(`${path}.origin must be a valid HTTPS origin`);\n }\n const target = record(site.target);\n const targetValues = {} as Record<\"appId\" | \"environment\" | \"dataEnvironment\" | \"runtime\" | \"chapterId\", string>;\n for (const key of [\"appId\", \"environment\", \"dataEnvironment\", \"runtime\", \"chapterId\"] as const) {\n targetValues[key] = typeof target?.[key] === \"string\" ? String(target[key]) : \"\";\n if (!targetValues[key]) errors.push(`${path}.target.${key} is required`);\n }\n const partition = Object.values(targetValues).join(\"\\u0000\");\n if (targets.has(partition)) errors.push(`${path}.target duplicates another site partition`);\n if (Object.values(targetValues).every(Boolean)) targets.add(partition);\n if (site.stripeMode !== \"test\" && site.stripeMode !== \"live\") {\n errors.push(`${path}.stripeMode must be test or live`);\n }\n if (site.stripeMode === \"live\" && targetValues.environment !== \"prod\" && targetValues.environment !== \"production\") {\n errors.push(`${path}.stripeMode cannot be live outside a production environment`);\n }\n\n const skuIds = new Set<string>();\n const inputSkus = Array.isArray(site.skus) ? site.skus : [];\n if (!Array.isArray(site.skus) || inputSkus.length === 0) errors.push(`${path}.skus must be a non-empty array`);\n const skus: ChapterAcceptanceSku[] = [];\n for (const [skuIndex, rawSku] of inputSkus.entries()) {\n const skuPath = `${path}.skus[${skuIndex}]`;\n const sku = record(rawSku);\n if (!sku) {\n errors.push(`${skuPath} must be an object`);\n continue;\n }\n const id = typeof sku.id === \"string\" ? sku.id : \"\";\n if (!SLUG.test(id)) errors.push(`${skuPath}.id must be a stable lowercase slug`);\n if (skuIds.has(id)) errors.push(`${skuPath}.id duplicates ${JSON.stringify(id)}`);\n if (id) skuIds.add(id);\n if (sku.kind !== \"membership\" && sku.kind !== \"add_on\") errors.push(`${skuPath}.kind must be membership or add_on`);\n if (typeof sku.active !== \"boolean\") errors.push(`${skuPath}.active must be boolean`);\n const priceCents = typeof sku.priceCents === \"number\" ? sku.priceCents : Number.NaN;\n if (!Number.isSafeInteger(priceCents) || priceCents < 0) errors.push(`${skuPath}.priceCents must be a non-negative integer`);\n if (typeof sku.currency !== \"string\" || !CURRENCY.test(sku.currency)) errors.push(`${skuPath}.currency must be a lowercase ISO currency code`);\n if (sku.billing !== \"month\" && sku.billing !== \"year\" && sku.billing !== \"once\") {\n errors.push(`${skuPath}.billing must be month, year, or once`);\n }\n if (sku.kind === \"membership\" && sku.billing === \"once\") {\n errors.push(`${skuPath}.billing must be month or year for a membership SKU`);\n }\n if (sku.active === true && priceCents > 0 && (typeof sku.stripePriceId !== \"string\" || !STRIPE_PRICE.test(sku.stripePriceId))) {\n errors.push(`${skuPath}.stripePriceId is required for an active paid SKU`);\n }\n if (priceCents === 0 && sku.stripePriceId) errors.push(`${skuPath}.stripePriceId must be absent for a free SKU`);\n if (typeof sku.stripePriceId === \"string\" && sku.stripePriceId) {\n const owner = `${siteId}/${id}`;\n const previous = priceOwners.get(sku.stripePriceId);\n if (previous && previous !== owner) errors.push(`${skuPath}.stripePriceId is already owned by ${previous}`);\n else priceOwners.set(sku.stripePriceId, owner);\n }\n if (sku.compareAtPriceCents !== undefined) {\n if (!Number.isSafeInteger(sku.compareAtPriceCents) || Number(sku.compareAtPriceCents) <= priceCents) {\n errors.push(`${skuPath}.compareAtPriceCents must be an integer greater than priceCents`);\n }\n if (sku.discountDuration !== \"first_term\" && sku.discountDuration !== \"while_active\") {\n errors.push(`${skuPath}.discountDuration is required with compareAtPriceCents`);\n }\n } else if (sku.discountDuration) {\n errors.push(`${skuPath}.compareAtPriceCents is required with discountDuration`);\n }\n skus.push(sku as unknown as ChapterAcceptanceSku);\n }\n if (!skus.some((sku) => sku.active && sku.kind === \"membership\")) errors.push(`${path}.skus must contain an active membership SKU`);\n errors.push(...validateCommercialCases(site.commercialCases, skus, `${path}.commercialCases`));\n const options = record(site.options);\n if (!options) errors.push(`${path}.options must be an object`);\n if (options?.ordinaryInterview !== true) errors.push(`${path}.options.ordinaryInterview must be true`);\n if (typeof options?.invitationInterviewWaiver !== \"boolean\") errors.push(`${path}.options.invitationInterviewWaiver must be boolean`);\n if (options?.autoRenew !== true) errors.push(`${path}.options.autoRenew must be true`);\n const seat = record(options?.additionalSeat);\n if (options?.additionalSeat !== undefined && !seat) errors.push(`${path}.options.additionalSeat must be an object`);\n if (seat) {\n const seatSku = skus.find((sku) => sku.id === seat.skuId);\n if (!seatSku || !seatSku.active || seatSku.kind !== \"add_on\") {\n errors.push(`${path}.options.additionalSeat.skuId must name an active add_on SKU`);\n } else if (seatSku.billing === \"once\") {\n errors.push(`${path}.options.additionalSeat.skuId must name a recurring add_on SKU`);\n }\n if (typeof seat.purchaseWindowCalendarMonths !== \"number\" ||\n !Number.isInteger(seat.purchaseWindowCalendarMonths) || seat.purchaseWindowCalendarMonths < 1) {\n errors.push(`${path}.options.additionalSeat.purchaseWindowCalendarMonths must be a positive integer`);\n }\n if (seat.named !== true || seat.uniqueEmail !== true || seat.renewal !== \"membership_aligned\" || seat.chargeTiming !== \"start\") {\n errors.push(`${path}.options.additionalSeat must require a named unique-email seat, membership-aligned renewal, and payment at start`);\n }\n }\n }\n if (siteIds.size < 2) errors.push(\"targets must cover at least two distinct logical sites\");\n return errors.length ? { ok: false, errors } : { ok: true, value: value as ChapterAcceptanceManifest };\n}\n\nfunction scenario(input: Omit<ChapterAcceptanceScenario, \"id\">): ChapterAcceptanceScenario {\n return {\n ...input,\n id: [input.suite, input.targetId, input.skuId, input.parentSkuId, input.commercialCaseId, input.siblingTargetId, input.kind].filter(Boolean).join(\":\"),\n };\n}\n\n/**\n * Build exhaustive pure cases plus a bounded provider-backed development matrix.\n * Throws before returning provider work when the manifest is invalid or names live Stripe.\n */\nexport function planChapterAcceptanceMatrix(manifest: ChapterAcceptanceManifest): ChapterAcceptanceScenario[] {\n const validation = validateChapterAcceptanceManifest(manifest);\n if (!validation.ok) throw new TypeError(`invalid Chapter acceptance manifest: ${validation.errors.join(\"; \")}`);\n if (manifest.targets.some((site) => site.stripeMode !== \"test\" || site.target.environment !== \"dev\" || site.target.dataEnvironment !== \"dev\")) {\n throw new TypeError(\"provider acceptance runs are development-only and require Stripe test mode and dev runtime/data environments on every target\");\n }\n const scenarios: ChapterAcceptanceScenario[] = [];\n for (const site of manifest.targets) {\n for (const vector of site.commercialCases ?? []) {\n const base = { targetId: site.targetId, siteId: site.siteId, skuId: vector.skuId, commercialCaseId: vector.id };\n scenarios.push(scenario({ ...base, suite: \"hermetic\", kind: \"commercial_policy_replay\" }));\n scenarios.push(scenario({ ...base, suite: \"provider_dev\", kind: \"commercial_quote\" }));\n scenarios.push(scenario({ ...base, suite: \"provider_dev\", kind: \"commercial_renewal\" }));\n }\n for (const sku of site.skus.filter((candidate) => candidate.active)) {\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"catalog_contract\", targetId: site.targetId, siteId: site.siteId, skuId: sku.id }));\n if (sku.priceCents > 0) {\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"amount_tamper\", targetId: site.targetId, siteId: site.siteId, skuId: sku.id }));\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"wrong_environment_event\", targetId: site.targetId, siteId: site.siteId, skuId: sku.id }));\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"post_stripe_compensation\", targetId: site.targetId, siteId: site.siteId, skuId: sku.id }));\n for (const sibling of manifest.targets.filter((candidate) => candidate.targetId !== site.targetId)) {\n scenarios.push(scenario({\n suite: \"hermetic\", kind: \"sibling_event_isolation\", targetId: site.targetId, siteId: site.siteId,\n skuId: sku.id, siblingTargetId: sibling.targetId,\n }));\n }\n }\n }\n for (const sku of activeMemberships(site)) {\n scenarios.push(scenario({ suite: \"hermetic\", kind: \"submit_replay\", targetId: site.targetId, siteId: site.siteId, skuId: sku.id }));\n scenarios.push(scenario({\n suite: \"provider_dev\", kind: sku.priceCents > 0 ? \"paid_signup\" : \"free_signup\",\n targetId: site.targetId, siteId: site.siteId, skuId: sku.id,\n }));\n }\n for (const membership of activeMemberships(site)) {\n const base = { targetId: site.targetId, siteId: site.siteId, skuId: membership.id };\n scenarios.push(scenario({ ...base, suite: \"provider_dev\", kind: \"ordinary_interview\" }));\n if (site.options.invitationInterviewWaiver) {\n scenarios.push(scenario({ ...base, suite: \"provider_dev\", kind: \"invitation_interview_waiver\" }));\n scenarios.push(scenario({ ...base, suite: \"hermetic\", kind: \"expired_interview_waiver\" }));\n scenarios.push(scenario({ ...base, suite: \"hermetic\", kind: \"replayed_interview_waiver\" }));\n }\n if (membership.priceCents === 0) continue;\n scenarios.push(scenario({ ...base, suite: \"provider_dev\", kind: \"renewal\" }));\n scenarios.push(scenario({ ...base, suite: \"provider_dev\", kind: \"refund_cancel\" }));\n if (site.options.additionalSeat) {\n const seat = { ...base, skuId: site.options.additionalSeat.skuId, parentSkuId: membership.id };\n for (const kind of [\"named_seat\", \"seat_declined_refund\", \"unaccepted_seat_refund\", \"seat_membership_alignment\"] as const) {\n scenarios.push(scenario({ ...seat, suite: \"provider_dev\", kind }));\n }\n for (const kind of [\"duplicate_seat_email\", \"expired_seat_window\"] as const) {\n scenarios.push(scenario({ ...seat, suite: \"hermetic\", kind }));\n }\n }\n scenarios.push(scenario({ ...base, suite: \"hermetic\", kind: \"canceled_membership\" }));\n }\n }\n return scenarios;\n}\n"],"mappings":"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","names":["id","scenario","proof","id","activeMemberships","record","id"]}
@@ -1,8 +1,8 @@
1
1
  import * as preact from 'preact';
2
2
  import { ComponentChildren, JSX } from 'preact';
3
- import { CrmClient, Crm, CrmRecord } from '@odla-ai/crm';
4
- import { a as Chapter, b as ChapterCopy, M as MemberContentDocument, E as EffectiveMemberContent, c as MemberContentTierAuthority } from '../../copy-context-Dorxp-WK.js';
5
- export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-Dorxp-WK.js';
3
+ import { CrmClient, Crm, CrmRecord, FieldType } from '@odla-ai/crm';
4
+ import { a as Chapter, b as ChapterCopy, M as MemberContentDocument, E as EffectiveMemberContent, c as MemberContentTierAuthority } from '../../copy-context-BveBZglM.js';
5
+ export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-BveBZglM.js';
6
6
  import { CrmLifecycleAdapter, CrmWorkspaceMasterContext, CrmWorkspaceRecordContext, RecordPanelTab } from '@odla-ai/crm/ui';
7
7
 
8
8
  /** Normalized public auth configuration consumed by the Clerk gate. */
@@ -79,6 +79,8 @@ interface AdminSectionContext {
79
79
  interface AdminWorkspace {
80
80
  id: string;
81
81
  label: string;
82
+ /** Optional host-rendered navigation icon; the workspace list is the registry. */
83
+ icon?: ComponentChildren;
82
84
  /** Canonical nested view used when a workspace is opened without one. */
83
85
  defaultViewId?: string;
84
86
  /** Optional named @odla-ai/ui accent scoped to this workspace's content. */
@@ -103,6 +105,13 @@ interface AdminWorkspaceNavProps {
103
105
  navigate: (target: AdminRouteTarget) => void;
104
106
  href: (target: AdminRouteTarget) => string;
105
107
  }
108
+ /** Host-owned geometry around the already-composed active workspace. Chapter
109
+ * retains authentication, routing, accent scope and active-only rendering. */
110
+ interface AdminWorkspaceFrameProps extends AdminWorkspaceNavProps, AdminAccountMenuProps {
111
+ activeWorkspace: AdminWorkspace | undefined;
112
+ context: AdminSectionContext;
113
+ children: ComponentChildren;
114
+ }
106
115
  interface AdminShellProps {
107
116
  workspaces: AdminWorkspace[];
108
117
  basePath: string;
@@ -117,6 +126,8 @@ interface AdminShellProps {
117
126
  renderHeader?: (props: AdminAccountMenuProps) => ComponentChildren;
118
127
  renderAccountMenu?: (props: AdminAccountMenuProps) => ComponentChildren;
119
128
  renderWorkspaceNav?: (props: AdminWorkspaceNavProps) => ComponentChildren;
129
+ /** Replaces packaged navigation/main geometry; a custom header stays outside. */
130
+ renderWorkspaceFrame?: (props: AdminWorkspaceFrameProps) => ComponentChildren;
120
131
  }
121
132
 
122
133
  /** Configuration for the Clerk-gated, brand-scoped Chapter admin console. */
@@ -141,6 +152,8 @@ interface ChapterAdminProps {
141
152
  renderHeader?: AdminShellProps["renderHeader"];
142
153
  renderAccountMenu?: (props: AdminAccountMenuProps) => ComponentChildren;
143
154
  renderWorkspaceNav?: (props: AdminWorkspaceNavProps) => ComponentChildren;
155
+ /** Host geometry with the active workspace, account and navigation context. */
156
+ renderWorkspaceFrame?: AdminShellProps["renderWorkspaceFrame"];
144
157
  /** Adapt existing config/current-user endpoints without rewriting auth. */
145
158
  auth?: ChapterAdminAuthAdapter;
146
159
  }
@@ -262,6 +275,61 @@ interface RecordActionsProps {
262
275
  * actions the record supports. */
263
276
  declare function RecordActions({ getToken, record, roles, onChanged }: RecordActionsProps): preact.JSX.Element | null;
264
277
 
278
+ /** Privacy-bounded CRM record returned by a follower to one configured,
279
+ * authenticated reader. */
280
+ interface NetworkRecord {
281
+ id: string;
282
+ type: string;
283
+ name: string;
284
+ stage?: string;
285
+ fields: Record<string, unknown>;
286
+ createdAt: number;
287
+ updatedAt: number;
288
+ /** Optimistic concurrency token authored by the follower. */
289
+ revision: number;
290
+ /** Follower-authored edit contract. Omitted when this edge is read-only. */
291
+ edit?: NetworkRecordEdit;
292
+ }
293
+ /** One follower CRM field a leader may patch. */
294
+ interface NetworkEditableField {
295
+ id: string;
296
+ label: string;
297
+ type: FieldType;
298
+ required: boolean;
299
+ options?: readonly string[];
300
+ }
301
+ /** One follower-authoritative lifecycle destination currently allowed. */
302
+ interface NetworkStageTransition {
303
+ id: string;
304
+ label: string;
305
+ }
306
+ /** Edit metadata computed from the follower schema, pipeline, and record. */
307
+ interface NetworkRecordEdit {
308
+ fields: NetworkEditableField[];
309
+ allowedStages: NetworkStageTransition[];
310
+ /** Durable application operation awaiting reconciliation by its original operator. */
311
+ pendingAction?: {
312
+ mutationId: string;
313
+ stage: string;
314
+ expectedStage: string;
315
+ expectedRevision: number;
316
+ actorId: string;
317
+ actorEmail?: string;
318
+ };
319
+ }
320
+
321
+ /** Follower-authored fields and actions; no client-side membership policy. */
322
+ declare function NetworkRecordEditor(props: {
323
+ ctx: AdminSectionContext;
324
+ targetId: string;
325
+ targetName: string;
326
+ leaderName: string;
327
+ record: NetworkRecord;
328
+ sharedNotes?: boolean;
329
+ admissionGrants?: boolean;
330
+ onChanged: () => void;
331
+ }): preact.JSX.Element;
332
+
265
333
  /** Props for {@link NetworkShareActions}. */
266
334
  interface NetworkShareActionsProps {
267
335
  recordId: string;
@@ -296,7 +364,9 @@ declare function admissionGrantsWorkspace(label?: string): AdminWorkspace;
296
364
  interface LeaderAdmissionActionProps {
297
365
  getToken: () => Promise<string | null>;
298
366
  targetId: string;
299
- personId: string;
367
+ personId?: string;
368
+ /** Exact follower-owned record, without importing it into the leader CRM. */
369
+ sourceRecordId?: string;
300
370
  onSaved?: (result: unknown) => void;
301
371
  }
302
372
  /** Bounded leader-side composition seam for assigning an existing CRM person
@@ -467,4 +537,4 @@ declare function AdminNote({ children }: {
467
537
  children: ComponentChildren;
468
538
  }): JSX.Element;
469
539
 
470
- export { type AdminAccountMenuProps, type AdminBuilderLibraryData, type AdminChrome, type AdminMemberContentData, AdminNote, AdminPage, type AdminResource, type AdminRouteState, type AdminRouteTarget, type AdminRouting, type AdminSection, type AdminSectionContext, type AdminWorkspace, type AdminWorkspaceNavProps, AdmissionGrantsWorkspace, type AvailabilitySectionOptions, type BillingSectionOptions, BuilderLibraryAdmin, ChapterAdmin, type ChapterAdminAuthAdapter, type ChapterAdminAuthConfig, type ChapterAdminAuthLoadContext, type ChapterAdminProps, type ChapterAdminUser, type CollectionSectionOptions, type DashboardSectionOptions, type EmailSectionOptions, LeaderAdmissionAction, type LeaderAdmissionActionProps, LeaderNetworkOverview, type MeetingsSectionOptions, MemberContentAdmin, NetworkRecordsWorkspace, NetworkShareActions, type NetworkShareActionsProps, Panel, type PeopleSectionOptions, RecordActions, type RecordActionsProps, ThemeWarning, adminFetch, adminRouteFromUrl, adminRouteHref, adminSectionFromUrl, adminSectionHref, admissionGrantsWorkspace, applicationLifecycleAdapter, availabilitySection, billingSection, builderLibrarySection, collectionSection, dashboardSection, defaultAdminSections, defaultAdminWorkspaces, emailSection, loadChapterAdminConfig, loadChapterAdminUser, meetingsSection, memberContentSection, networkRecordsWorkspace, peopleSection, useAdminResource };
540
+ export { type AdminAccountMenuProps, type AdminBuilderLibraryData, type AdminChrome, type AdminMemberContentData, AdminNote, AdminPage, type AdminResource, type AdminRouteState, type AdminRouteTarget, type AdminRouting, type AdminSection, type AdminSectionContext, type AdminWorkspace, type AdminWorkspaceFrameProps, type AdminWorkspaceNavProps, AdmissionGrantsWorkspace, type AvailabilitySectionOptions, type BillingSectionOptions, BuilderLibraryAdmin, ChapterAdmin, type ChapterAdminAuthAdapter, type ChapterAdminAuthConfig, type ChapterAdminAuthLoadContext, type ChapterAdminProps, type ChapterAdminUser, type CollectionSectionOptions, type DashboardSectionOptions, type EmailSectionOptions, LeaderAdmissionAction, type LeaderAdmissionActionProps, LeaderNetworkOverview, type MeetingsSectionOptions, MemberContentAdmin, NetworkRecordEditor, NetworkRecordsWorkspace, NetworkShareActions, type NetworkShareActionsProps, Panel, type PeopleSectionOptions, RecordActions, type RecordActionsProps, ThemeWarning, adminFetch, adminRouteFromUrl, adminRouteHref, adminSectionFromUrl, adminSectionHref, admissionGrantsWorkspace, applicationLifecycleAdapter, availabilitySection, billingSection, builderLibrarySection, collectionSection, dashboardSection, defaultAdminSections, defaultAdminWorkspaces, emailSection, loadChapterAdminConfig, loadChapterAdminUser, meetingsSection, memberContentSection, networkRecordsWorkspace, peopleSection, useAdminResource };
@@ -7,6 +7,7 @@ import {
7
7
  LeaderAdmissionAction,
8
8
  LeaderNetworkOverview,
9
9
  MemberContentAdmin,
10
+ NetworkRecordEditor,
10
11
  NetworkRecordsWorkspace,
11
12
  NetworkShareActions,
12
13
  Panel,
@@ -34,7 +35,7 @@ import {
34
35
  networkRecordsWorkspace,
35
36
  peopleSection,
36
37
  useAdminResource
37
- } from "../../chunk-7MEVZEL2.js";
38
+ } from "../../chunk-MQ4OPZCS.js";
38
39
  import {
39
40
  ChapterCopyProvider,
40
41
  useChapterCopy
@@ -49,6 +50,7 @@ export {
49
50
  LeaderAdmissionAction,
50
51
  LeaderNetworkOverview,
51
52
  MemberContentAdmin,
53
+ NetworkRecordEditor,
52
54
  NetworkRecordsWorkspace,
53
55
  NetworkShareActions,
54
56
  Panel,
@@ -1,5 +1,5 @@
1
- export { AdminAccountMenuProps, AdminBuilderLibraryData, AdminChrome, AdminMemberContentData, AdminNote, AdminPage, AdminResource, AdminRouteState, AdminRouteTarget, AdminRouting, AdminSection, AdminSectionContext, AdminWorkspace, AdminWorkspaceNavProps, AdmissionGrantsWorkspace, AvailabilitySectionOptions, BillingSectionOptions, BuilderLibraryAdmin, ChapterAdmin, ChapterAdminAuthAdapter, ChapterAdminAuthConfig, ChapterAdminAuthLoadContext, ChapterAdminProps, ChapterAdminUser, CollectionSectionOptions, DashboardSectionOptions, EmailSectionOptions, LeaderAdmissionAction, LeaderAdmissionActionProps, LeaderNetworkOverview, MeetingsSectionOptions, MemberContentAdmin, NetworkRecordsWorkspace, NetworkShareActions, NetworkShareActionsProps, Panel, PeopleSectionOptions, RecordActions, RecordActionsProps, ThemeWarning, adminFetch, adminRouteFromUrl, adminRouteHref, adminSectionFromUrl, adminSectionHref, admissionGrantsWorkspace, applicationLifecycleAdapter, availabilitySection, billingSection, builderLibrarySection, collectionSection, dashboardSection, defaultAdminSections, defaultAdminWorkspaces, emailSection, loadChapterAdminConfig, loadChapterAdminUser, meetingsSection, memberContentSection, networkRecordsWorkspace, peopleSection, useAdminResource } from './admin/index.js';
2
- export { C as ChapterCopyProvider, u as useChapterCopy } from '../copy-context-Dorxp-WK.js';
1
+ export { AdminAccountMenuProps, AdminBuilderLibraryData, AdminChrome, AdminMemberContentData, AdminNote, AdminPage, AdminResource, AdminRouteState, AdminRouteTarget, AdminRouting, AdminSection, AdminSectionContext, AdminWorkspace, AdminWorkspaceFrameProps, AdminWorkspaceNavProps, AdmissionGrantsWorkspace, AvailabilitySectionOptions, BillingSectionOptions, BuilderLibraryAdmin, ChapterAdmin, ChapterAdminAuthAdapter, ChapterAdminAuthConfig, ChapterAdminAuthLoadContext, ChapterAdminProps, ChapterAdminUser, CollectionSectionOptions, DashboardSectionOptions, EmailSectionOptions, LeaderAdmissionAction, LeaderAdmissionActionProps, LeaderNetworkOverview, MeetingsSectionOptions, MemberContentAdmin, NetworkRecordEditor, NetworkRecordsWorkspace, NetworkShareActions, NetworkShareActionsProps, Panel, PeopleSectionOptions, RecordActions, RecordActionsProps, ThemeWarning, adminFetch, adminRouteFromUrl, adminRouteHref, adminSectionFromUrl, adminSectionHref, admissionGrantsWorkspace, applicationLifecycleAdapter, availabilitySection, billingSection, builderLibrarySection, collectionSection, dashboardSection, defaultAdminSections, defaultAdminWorkspaces, emailSection, loadChapterAdminConfig, loadChapterAdminUser, meetingsSection, memberContentSection, networkRecordsWorkspace, peopleSection, useAdminResource } from './admin/index.js';
2
+ export { C as ChapterCopyProvider, u as useChapterCopy } from '../copy-context-BveBZglM.js';
3
3
  export { ApiFn, BrandStyle, BrandStyleProps, GiftCodeRedeemResult, GiftCodeRedeemer, GiftCodeRedeemerCopy, GiftCodeRedeemerProps, GiftOfferCards, GiftOfferCardsMode, GiftOfferCardsProps, GiftPurchases, GiftPurchasesProps, JoinBookingSimulation, JoinConfig, JoinFlowState, JoinIsland, JoinIslandProps, JoinSimulation, JoinStepRenderContext, JoinSubmitRenderContext, JoinTier, JoinTierRenderContext, MEMBERSHIP_CARD_TOKEN_DEFAULTS, MemberContentArea, MemberContentAreaProps, MemberGifts, MemberProvisionalRenderContext, MembersArea, MembersAreaProps, MembershipCardTokenName, MembershipCards, MembershipCardsMode, MembershipCardsProps, PaymentPriceLines, PaymentStep, PaymentStepProps, PaymentStepSimulation, RescheduleProps, Rescheduler, Slot, SlotPicker, SlotPickerClasses, SlotPickerProps, SubResponse, TierPlaceholder, dayKey, dayLabel, fmtDate, fmtMoney, fullLabel, groupSlotsByDay, loadJoinResume, membershipApplicationHref, tierNeedsPayment, timeLabel, tzShort, useTierSelection } from './member/index.js';
4
4
  import 'preact';
5
5
  import '@odla-ai/crm';
package/dist/ui/index.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  timeLabel,
25
25
  tzShort,
26
26
  useTierSelection
27
- } from "../chunk-VWDEHUNI.js";
27
+ } from "../chunk-KZ2AXEZW.js";
28
28
  import {
29
29
  AdminNote,
30
30
  AdminPage,
@@ -34,6 +34,7 @@ import {
34
34
  LeaderAdmissionAction,
35
35
  LeaderNetworkOverview,
36
36
  MemberContentAdmin,
37
+ NetworkRecordEditor,
37
38
  NetworkRecordsWorkspace,
38
39
  NetworkShareActions,
39
40
  Panel,
@@ -61,7 +62,7 @@ import {
61
62
  networkRecordsWorkspace,
62
63
  peopleSection,
63
64
  useAdminResource
64
- } from "../chunk-7MEVZEL2.js";
65
+ } from "../chunk-MQ4OPZCS.js";
65
66
  import {
66
67
  BrandStyle,
67
68
  ChapterCopyProvider,
@@ -88,6 +89,7 @@ export {
88
89
  MemberGifts,
89
90
  MembersArea,
90
91
  MembershipCards,
92
+ NetworkRecordEditor,
91
93
  NetworkRecordsWorkspace,
92
94
  NetworkShareActions,
93
95
  Panel,
@@ -1,7 +1,7 @@
1
1
  import * as preact from 'preact';
2
2
  import { ComponentChildren, JSX } from 'preact';
3
- import { d as MemberContentProjection, e as MemberContentPageProjection, b as ChapterCopy, f as ChapterBrand } from '../../copy-context-Dorxp-WK.js';
4
- export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-Dorxp-WK.js';
3
+ import { d as MemberContentProjection, e as MemberContentPageProjection, b as ChapterCopy, f as ChapterBrand } from '../../copy-context-BveBZglM.js';
4
+ export { C as ChapterCopyProvider, u as useChapterCopy } from '../../copy-context-BveBZglM.js';
5
5
  import { FieldType, FieldConditions } from '@odla-ai/crm';
6
6
 
7
7
  /** A bookable slot: a start instant in epoch milliseconds. */
@@ -369,6 +369,9 @@ type JoinFlowState = {
369
369
  } | {
370
370
  step: "accepted";
371
371
  applicationId: string;
372
+ } | {
373
+ step: "closed";
374
+ applicationId: string;
372
375
  } | {
373
376
  step: "gift";
374
377
  applicationId: string;
@@ -449,6 +452,10 @@ interface JoinIslandProps {
449
452
  * application. When absent, JoinIsland cannot offer recipient claiming.
450
453
  */
451
454
  giftClaimApi?: ApiFn;
455
+ /** Authenticated adapter for accepting a paid named seat using the recipient's own application. */
456
+ namedSeatClaimApi?: ApiFn;
457
+ /** Invitation reference from the join link; the server verifies the named recipient, scope, SKU, and expiry. */
458
+ initialNamedSeatId?: string;
452
459
  /** Run the canonical journey without network, Stripe, or calendar writes. */
453
460
  simulation?: JoinSimulation;
454
461
  }
@@ -24,7 +24,7 @@ import {
24
24
  timeLabel,
25
25
  tzShort,
26
26
  useTierSelection
27
- } from "../../chunk-VWDEHUNI.js";
27
+ } from "../../chunk-KZ2AXEZW.js";
28
28
  import {
29
29
  BrandStyle,
30
30
  ChapterCopyProvider,