/** A resource as the merge sees it: its id and type, and its data fields. */ export type TwinResource = { id: string; type: string; updatedAt: string; } & Record; export type ReconcilePolicy = 'hub-wins' | 'twin-wins' | 'merge'; export type FieldDecision = { field: string; base: unknown; fork: unknown; real: unknown; forkChanged: boolean; realChanged: boolean; resolution: 'unchanged' | 'take-fork' | 'take-real' | 'conflict'; value: unknown; }; export type SubjectReconcile = { id: string; type: string; inFork: boolean; inReal: boolean; existence: 'both' | 'fork-only' | 'real-only'; fields: FieldDecision[]; conflicts: FieldDecision[]; }; export type ReconcilePlan = { policy: ReconcilePolicy; subjects: SubjectReconcile[]; toPush: Array<{ id: string; type: string; fields: Record; }>; toPull: Array<{ id: string; type: string; fields: Record; }>; conflictCount: number; }; /** * Compute a three-way reconciliation plan. Inputs are resource snapshots keyed * by id (base = at fork time, fork = twin now, real = fresh pull). Pure. */ export declare function reconcile(opts: { policy: ReconcilePolicy; base: TwinResource[]; fork: TwinResource[]; real: TwinResource[]; }): ReconcilePlan; /** True when the plan can be enacted without a human decision. */ export declare function isCleanlyReconcilable(plan: ReconcilePlan): boolean;