Skip to content
Astera Technology

Why did editing an old field leave its new representation inconsistent?

Enforce the supplied old-field authority and update both representations atomically.

Download complete case notes and answer keys ↓

Read the source and its declared rule

The original interim schema stores old 2 and scaled 20 with invariant scaled=old×10. Both representations must already be present, and only the old side is authorised for edits. The incoming value must be a safe whole JavaScript number whose tenfold value is also a safe integer; NULL is held. Corrected code checks existing presence, divergence, authority and the proposed value before its paired transaction update.

Filled synthetic input
RecordInput JSON
Base input{"old":2,"scaled":20,"edit":{"side":"old","value":3}}
Download editable CSV ↓

Compare the actual paths

For incoming old 3, good actual state is 3/30. Existing 2/21 is held untouched rather than silently choosing an authority after discovering contradictory stored values.

Misleading and corrected outputs
PathOutput JSON
Misleading path{"error":null,"records":[{"id":1,"size_old":3,"size_new":20}]}
Corrected path{"error":null,"records":[{"id":1,"size_old":3,"size_new":30}]}
Download editable CSV ↓
Local Node.js program: 22.23.3 or 24.14.1
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 target(id INTEGER PRIMARY KEY,size_old INTEGER,size_new INTEGER);');db.prepare('INSERT INTO target VALUES(1,?,?)').run(i.old,i.scaled);let error=null;
      if(corrected){db.exec('BEGIN;');if(db.prepare('SELECT COUNT(*) AS n FROM target WHERE size_old IS NULL OR size_new IS NULL').get().n)error='missing-representation';
        else if(db.prepare('SELECT COUNT(*) AS n FROM target WHERE size_new<>size_old*10').get().n)error='divergent-existing-pair';
        else if(i.edit.side!=='old')error='non-authoritative-edit';else if(i.edit.value===null)error='missing-edit-value';
        else if(!Number.isSafeInteger(i.edit.value)||!Number.isSafeInteger(i.edit.value*10))error='invalid-edit-value';
        else db.prepare('UPDATE target SET size_old=?,size_new=? WHERE id=1').run(i.edit.value,i.edit.value*10);
        db.exec(error?'ROLLBACK;':'COMMIT;');}
      else db.prepare('UPDATE target SET '+(i.edit.side==='old'?'size_old':'size_new')+'=? WHERE id=1').run(i.edit.value);
      return {error,records:rows(db,'SELECT * FROM target')};
    }finally{db.close();}
  };
const cases=[{"label":"misleading base","input":{"old":2,"scaled":20,"edit":{"side":"old","value":3}},"expected":{"error":null,"records":[{"id":1,"size_old":3,"size_new":20}]},"corrected":false},{"label":"corrected base","input":{"old":2,"scaled":20,"edit":{"side":"old","value":3}},"expected":{"error":null,"records":[{"id":1,"size_old":3,"size_new":30}]},"corrected":true},{"label":"existing divergence blocks a new edit","input":{"old":2,"scaled":21,"edit":{"side":"old","value":3}},"expected":{"error":"divergent-existing-pair","records":[{"id":1,"size_old":2,"size_new":21}]},"corrected":true},{"label":"new-side direct edit lacks authority","input":{"old":2,"scaled":20,"edit":{"side":"new","value":30}},"expected":{"error":"non-authoritative-edit","records":[{"id":1,"size_old":2,"size_new":20}]},"corrected":true},{"label":"missing scaled counterpart held","input":{"old":2,"scaled":null,"edit":{"side":"old","value":3}},"expected":{"error":"missing-representation","records":[{"id":1,"size_old":2,"size_new":null}]},"corrected":true},{"label":"missing old counterpart held","input":{"old":null,"scaled":20,"edit":{"side":"old","value":3}},"expected":{"error":"missing-representation","records":[{"id":1,"size_old":null,"size_new":20}]},"corrected":true},{"label":"missing incoming old value held","input":{"old":2,"scaled":20,"edit":{"side":"old","value":null}},"expected":{"error":"missing-edit-value","records":[{"id":1,"size_old":2,"size_new":20}]},"corrected":true},{"label":"numeric zero edit is present","input":{"old":2,"scaled":20,"edit":{"side":"old","value":0}},"expected":{"error":null,"records":[{"id":1,"size_old":0,"size_new":0}]},"corrected":true},{"label":"text numeral is not a numeric edit","input":{"old":2,"scaled":20,"edit":{"side":"old","value":"3"}},"expected":{"error":"invalid-edit-value","records":[{"id":1,"size_old":2,"size_new":20}]},"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);
}
Download runnable example ↓

Check boundaries before the next load

Existing divergence retains 2/21. An unauthorised new-side 30 request retains 2/20. Missing scaled or old representation remains unchanged with missing-representation. A proposed old NULL is held as missing-edit-value. Numeric zero updates the pair to0/0; text3 is held rather than coerced.

Editable boundary records and expected outputs
CaseInput JSONExpected output JSON
Existing pair already diverges{"old":2,"scaled":21,"edit":{"side":"old","value":3}}{"error":"divergent-existing-pair","records":[{"id":1,"size_old":2,"size_new":21}]}
Edit targets the unauthorised side{"old":2,"scaled":20,"edit":{"side":"new","value":30}}{"error":"non-authoritative-edit","records":[{"id":1,"size_old":2,"size_new":20}]}
Missing scaled counterpart{"old":2,"scaled":null,"edit":{"side":"old","value":3}}{"error":"missing-representation","records":[{"id":1,"size_old":2,"size_new":null}]}
Missing old counterpart{"old":null,"scaled":20,"edit":{"side":"old","value":3}}{"error":"missing-representation","records":[{"id":1,"size_old":null,"size_new":20}]}
Missing proposed old value{"old":2,"scaled":20,"edit":{"side":"old","value":null}}{"error":"missing-edit-value","records":[{"id":1,"size_old":2,"size_new":20}]}
Present numeric zero edit{"old":2,"scaled":20,"edit":{"side":"old","value":0}}{"error":null,"records":[{"id":1,"size_old":0,"size_new":0}]}
Text numeral held{"old":2,"scaled":20,"edit":{"side":"old","value":"3"}}{"error":"invalid-edit-value","records":[{"id":1,"size_old":2,"size_new":20}]}
Download editable CSV ↓

May old 3 commit while scaled 20 stays unchanged?

Show the worked answer

No. That violates the supplied pair invariant. The authorised edit commits 3/30 together.

Related resources