Read the source and its declared rule
The original forward step collapses id 1/A and id 2/B into id 1/Group, then drops the original SQLite table. Target alone no longer contains the two original records. The approved exact data rollback uses a retained preimage; without it, the correction holds rather than inventing labels.
| Record | Input JSON |
|---|---|
| Base input | {"original":[{"id":1,"label":"A"},{"id":2,"label":"B"}],"collapse":true,"keepPreimage":true} |
Compare the actual paths
Corrected restoration recreates 1/A and 2/B from the actual preimage table. Merely copying target back produces only Group and does not undo the information loss.
| Path | Output JSON |
|---|---|
| Misleading path | {"error":null,"target":[{"id":1,"label":"Group"}],"restored":[{"id":1,"label":"Group"}]} |
| Corrected path | {"error":null,"target":[{"id":1,"label":"Group"}],"restored":[{"id":1,"label":"A"},{"id":2,"label":"B"}]} |
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};
import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
const db=new DatabaseSync(':memory:');try{db.exec('CREATE TABLE original(id INTEGER PRIMARY KEY,label TEXT);CREATE TABLE target(id INTEGER PRIMARY KEY,label TEXT);CREATE TABLE restored(id INTEGER PRIMARY KEY,label TEXT);');
for(const r of i.original)db.prepare('INSERT INTO original VALUES(?,?)').run(r.id,r.label);
if(i.keepPreimage)db.exec('CREATE TABLE preimage AS SELECT * FROM original;');
if(i.collapse&&i.original.length)db.exec("INSERT INTO target VALUES(1,'Group');");else db.exec('INSERT INTO target SELECT * FROM original;');
db.exec('DROP TABLE original;');let error=null;
if(corrected&&i.collapse){if(!i.keepPreimage)error='missing-preimage';else db.exec('INSERT INTO restored SELECT * FROM preimage;');}
else db.exec('INSERT INTO restored SELECT * FROM target;');
return {error,target:rows(db,'SELECT * FROM target ORDER BY id'),restored:rows(db,'SELECT * FROM restored ORDER BY id')};
}finally{db.close();}
};
const cases=[{"label":"misleading base","input":{"original":[{"id":1,"label":"A"},{"id":2,"label":"B"}],"collapse":true,"keepPreimage":true},"expected":{"error":null,"target":[{"id":1,"label":"Group"}],"restored":[{"id":1,"label":"Group"}]},"corrected":false},{"label":"corrected base","input":{"original":[{"id":1,"label":"A"},{"id":2,"label":"B"}],"collapse":true,"keepPreimage":true},"expected":{"error":null,"target":[{"id":1,"label":"Group"}],"restored":[{"id":1,"label":"A"},{"id":2,"label":"B"}]},"corrected":true},{"label":"lossy target without preimage cannot restore","input":{"original":[{"id":1,"label":"A"},{"id":2,"label":"B"}],"collapse":true,"keepPreimage":false},"expected":{"error":"missing-preimage","target":[{"id":1,"label":"Group"}],"restored":[]},"corrected":true},{"label":"identity transition has direct inverse","input":{"original":[{"id":1,"label":"A"},{"id":2,"label":"B"}],"collapse":false,"keepPreimage":false},"expected":{"error":null,"target":[{"id":1,"label":"A"},{"id":2,"label":"B"}],"restored":[{"id":1,"label":"A"},{"id":2,"label":"B"}]},"corrected":true}];
for(const test of cases){
const actual=run(test.input,test.corrected);
assert.deepEqual(actual,test.expected,test.label);
console.log(test.label,actual);
}
Check boundaries before the next load
Lossy target without a preimage is held. An identity transition with no collapse has a direct exact inverse.
| Case | Input JSON | Expected output JSON |
|---|---|---|
| No preimage for a lossy target | {"original":[{"id":1,"label":"A"},{"id":2,"label":"B"}],"collapse":true,"keepPreimage":false} | {"error":"missing-preimage","target":[{"id":1,"label":"Group"}],"restored":[]} |
| Injective identity transition | {"original":[{"id":1,"label":"A"},{"id":2,"label":"B"}],"collapse":false,"keepPreimage":false} | {"error":null,"target":[{"id":1,"label":"A"},{"id":2,"label":"B"}],"restored":[{"id":1,"label":"A"},{"id":2,"label":"B"}]} |
Can Group establish whether the old labels were A, B?
Show the worked answer
No. Use the retained preimage for those exact rows; otherwise do not claim an exact rollback.