/* * **A twin made by one producer is not rebuilt by another.** Pure. * * ── What went wrong (2026-09-24) ───────────────────────────────────────────── * An import's instance id is the adapter's site id (`master.source`). Importing the warehouse connection * `wms-miratek` with site id `miratek` — the same as the plant connection's — landed on the running plant * mirror `miratek`, and `ingestMaster` gave it the warehouse structure as a new revision: 16 places, * 23 equipment, 17 people and 14 assets gone. The row already said who made it (`origin.source` was * `mes-miratek`); nothing asked. * * ── The rule (chief architect ruling, 2026-09-24) ──────────────────────────── * Compare producers by identity, not by the whole origin: a reference is kind + source, a template is * kind + templateId. The same import carries more or fewer fields at different call sites (siteId, * spaceId), and a template re-run has new params — those are the same producer re-reading its own twin. * * both declared, same producer allowed (resync, re-import, re-run) * both declared, different refused, naming the producer that owns it * prior undeclared, incoming not refused — nobody can say who made it; delete it first to replace it * prior declared, incoming not refused — same reason, the other way * neither declared allowed — the demo seed re-ingesting its own twin at boot. Closes when * the seed declares a template origin. */ export const INSTANCE_TAKEN = 'instance-taken-by-another-source' export interface ProducerRefusal { code: typeof INSTANCE_TAKEN params: { instance: string; producer: string } message: string } /** Who produced a twin, as one comparable string — or undefined when the origin says nothing usable. */ export function producerOf(origin: unknown): string | undefined { if (!origin || typeof origin !== 'object') return undefined const o = origin as { kind?: unknown; source?: unknown; templateId?: unknown } if (o.kind === 'reference' && typeof o.source === 'string' && o.source) return `reference:${o.source}` if (o.kind === 'template' && typeof o.templateId === 'string' && o.templateId) return `template:${o.templateId}` /* A kind this guard does not know is still somebody — keep it distinct rather than reading it as none. */ if (typeof o.kind === 'string' && o.kind) return `${o.kind}:${String(o.source ?? o.templateId ?? '')}` return undefined } function nameOf(origin: unknown): string { const o = (origin ?? {}) as { source?: unknown; templateId?: unknown } return String(o.source ?? o.templateId ?? '') || 'undeclared' } /** null when `incoming` may rebuild the twin `prior` was made by; otherwise the refusal. */ export function refuseOverwriteByAnotherProducer( instance: string, priorOrigin: unknown, incomingOrigin: unknown ): ProducerRefusal | null { const had = producerOf(priorOrigin) const comes = producerOf(incomingOrigin) if (!had && !comes) return null if (had && comes && had === comes) return null const producer = had ? nameOf(priorOrigin) : 'undeclared' return { code: INSTANCE_TAKEN, params: { instance, producer }, message: `twin "${instance}" was made by ${producer} — delete it first, or import this site under another id` } }