{
  "sourceKind": "separate production-editor working copy; not a public GitHub commit",
  "reviewedAt": "2026-10-22",
  "excerpts": [
    {
      "file": "app/studio/retouch.ts",
      "start": 14,
      "end": 19,
      "code": " if(layerLocked(doc,layer,'pixels'))throw Error('Unlock the layer before retouching.');\n if(layer.kind==='text'||layer.kind==='adjustment'||layer.shape||layer.smartObject||layer.gridWarp||layer.puppet)throw Error('Rasterize this layer before retouching.');\n if(!['clone','heal','dodge','burn','sponge','blur','sharpen','spot','smudge','remove','mixer'].includes(settings.mode)||!Number.isFinite(settings.size)||settings.size<1||settings.size>300||!Number.isFinite(settings.hardness)||settings.hardness<0||settings.hardness>100||!Number.isFinite(settings.strength)||settings.strength<0||settings.strength>100)throw Error('Invalid retouch brush.');\n if(settings.sourceTransform)validateCloneTransform(settings.sourceTransform);\n if(settings.sample!==undefined&&!['current','below','all'].includes(settings.sample))throw Error('Invalid sample layers.');\n if(!['shadows','midtones','highlights'].includes(settings.range)||typeof settings.saturate!=='boolean'||typeof settings.pressure!=='boolean'||settings.source&&(!Number.isFinite(settings.source.x)||!Number.isFinite(settings.source.y)))throw Error('Invalid retouch settings.');if(!points.length)return doc;if(points.length>100000||points.some(p=>!Number.isFinite(p.x)||!Number.isFinite(p.y)||p.pressure!==undefined&&(!Number.isFinite(p.pressure)||p.pressure<0||p.pressure>1)))throw Error('Invalid retouch path.');",
      "ref": "working-copy-2026-10-22",
      "sha256": "1128552b9bd49ecfaa66638802228c013df9a1590ddcb6b1089c3bc31f6db401"
    },
    {
      "file": "app/studio/clone-source.ts",
      "start": 5,
      "end": 8,
      "code": "export function validateCloneTransform(t:CloneTransform){if(!t||![t.scaleX,t.scaleY].every(n=>Number.isFinite(n)&&n>=1&&n<=1000)||!Number.isFinite(t.angle)||Math.abs(t.angle)>360||typeof t.flipX!=='boolean'||typeof t.flipY!=='boolean')throw Error('Invalid clone source transform.');}\n// Inverse of the displayed source scale/rotation: destination pixels map back to donors.\nexport function cloneDelta(p:Point,t:CloneTransform=defaultCloneTransform):Point{const a=t.angle*Math.PI/180,c=Math.cos(a),s=Math.sin(a);return {x:(p.x*c+p.y*s)*100/t.scaleX*(t.flipX?-1:1),y:(-p.x*s+p.y*c)*100/t.scaleY*(t.flipY?-1:1)};}\nexport function cloneDonor(point:Point,start:Point,source:Point,t?:CloneTransform):Point{const d=cloneDelta({x:point.x-start.x,y:point.y-start.y},t);return {x:source.x+d.x,y:source.y+d.y};}",
      "ref": "working-copy-2026-10-22",
      "sha256": "5b95e75b0b48bdfc2e9b26329910fca148a0358680246128bb4956169307903c"
    },
    {
      "file": "app/studio/retouch.ts",
      "start": 21,
      "end": 27,
      "code": " const clone=settings.mode==='clone'||settings.mode==='heal';if(clone&&!settings.source)throw Error('Alt-click to choose a source point.');\n const edit=await openPixelEdit(doc,layer),image=edit.image,base=image.data.slice(),data=image.data,w=image.width,h=image.height,clip=doc.selection?selectionForLayer(doc.selection,layer):undefined,path=points.map(p=>({...localPoint(p,layer),pressure:p.pressure??1})),coverage=new Float32Array(w*h),hard=settings.hardness/100;\n const merged=clone&&settings.sample&&settings.sample!=='current'?(await openPixelEdit({...doc,layers:settings.sample==='below'?doc.layers.slice(0,doc.layers.findIndex(l=>l.id===layer.id)+1):doc.layers})).image:undefined;\n const donor=merged,matrix=homography(quadPoints(layer));\n const read=(x:number,y:number,shift:boolean):number[]|undefined=>{const world=mapMatrix(matrix,layer.flipX?1-(x+.5)/layer.width:(x+.5)/layer.width,layer.flipY?1-(y+.5)/layer.height:(y+.5)/layer.height),point=shift?cloneDonor(world,points[0],settings.source!,settings.sourceTransform):world;if(donor){const dx=Math.floor(point.x),dy=Math.floor(point.y);if(dx<0||dy<0||dx>=donor.width||dy>=donor.height)return;const i=(dy*donor.width+dx)*4;return Array.from(donor.data.subarray(i,i+4));}const local=shift?localPoint(point,layer):{x:x+.5,y:y+.5},dx=Math.floor(local.x+1e-7),dy=Math.floor(local.y+1e-7);if(dx<0||dy<0||dx>=w||dy>=h)return;const i=(dy*w+dx)*4;return Array.from(base.subarray(i,i+4));};\n const lum=(i:number)=>(base[i]*.2126+base[i+1]*.7152+base[i+2]*.0722)/255;\n const stamp=(p:RetouchPoint)=>{const pressure=settings.pressure?Math.max(.05,Math.min(1,p.pressure??1)):1,r=settings.size*pressure/2;for(let y=Math.max(0,Math.floor(p.y-r));y<Math.min(h,Math.ceil(p.y+r));y++)for(let x=Math.max(0,Math.floor(p.x-r));x<Math.min(w,Math.ceil(p.x+r));x++){const d=Math.hypot(x+.5-p.x,y+.5-p.y)/r;if(d>1)continue;const n=y*w+x,a=(d<=hard?1:(1-d)/Math.max(.001,1-hard))*settings.strength/100*(clip?clip.alpha[n]/255:1);coverage[n]=Math.max(coverage[n],a);}};",
      "ref": "working-copy-2026-10-22",
      "sha256": "1128552b9bd49ecfaa66638802228c013df9a1590ddcb6b1089c3bc31f6db401"
    },
    {
      "file": "app/studio/retouch.ts",
      "start": 31,
      "end": 35,
      "code": " else for(let y=0;y<h;y++)for(let x=0;x<w;x++){const n=y*w+x,i=n*4,a=coverage[n];if(!a)continue;const brightness=lum(i),tone=Math.max(0,Math.min(1,brightness)),range=settings.range==='shadows'?(1-tone)**2:settings.range==='highlights'?tone**2:4*tone*(1-tone);let sampled:number[]=[];\n  if(clone){const pixel=read(x,y,true);if(!pixel)continue;sampled=pixel;if(settings.mode==='heal'){let target=[0,0,0],from=[0,0,0],tw=0,fw=0;for(let yy=-2;yy<=2;yy++)for(let xx=-2;xx<=2;xx++){const t=read(x+xx,y+yy,false),f=read(x+xx,y+yy,true);if(t){tw+=t[3];for(let k=0;k<3;k++)target[k]+=t[k]*t[3];}if(f){fw+=f[3];for(let k=0;k<3;k++)from[k]+=f[k]*f[3];}}if(tw&&fw)for(let k=0;k<3;k++)sampled[k]+=target[k]/tw-from[k]/fw;}}\n\n  for(let k=0;k<3;k++){const v=base[i+k];let value=v;if(clone)value=sampled[k];else if(settings.mode==='dodge')value=edit.native?v*(1+range):v+(255-v)*range;else if(settings.mode==='burn')value=v*(1-range);else if(settings.mode==='sponge')value=brightness*255+(v-brightness*255)*(settings.saturate?2:0);else {let sum=0,count=0;for(let yy=-1;yy<=1;yy++)for(let xx=-1;xx<=1;xx++){const qx=Math.max(0,Math.min(w-1,x+xx)),qy=Math.max(0,Math.min(h-1,y+yy));const alpha=base[(qy*w+qx)*4+3]/255;sum+=base[(qy*w+qx)*4+k]*alpha;count+=alpha;}const mean=count?sum/count:v;value=settings.mode==='blur'?mean:v+(v-mean)*2;}const outAlpha=clone&&!layer.lockTransparency?base[i+3]*(1-a)+sampled[3]*a:0;data[i+k]=clone&&!layer.lockTransparency?(outAlpha?(v*base[i+3]*(1-a)+(edit.native?value:Math.max(0,Math.min(255,value)))*sampled[3]*a)/outAlpha:0):v*(1-a)+(edit.native?value:Math.max(0,Math.min(255,value)))*a;}\n  if(clone&&!layer.lockTransparency)data[i+3]=base[i+3]*(1-a)+sampled[3]*a;",
      "ref": "working-copy-2026-10-22",
      "sha256": "1128552b9bd49ecfaa66638802228c013df9a1590ddcb6b1089c3bc31f6db401"
    }
  ],
  "productionUI": {
    "date": "2026-10-22",
    "passed": true,
    "route": "Clone Stamp on duplicate layer; Undo and Redo observed",
    "settings": {
      "size": 110,
      "hardness": 20,
      "strength": 100,
      "pressure": false,
      "sample": "current",
      "aligned": true
    },
    "layers": [
      "original",
      "Clone wall repair"
    ],
    "fullRetouchSuiteRerun": false
  },
  "historicalReports": [
    {
      "file": "patch-render-results.json",
      "sha256": "e9d5dddcfc303e57f1114f455d8a4d984eeb0dd38393dbaff2f2ab4cd4709649",
      "results": {
        "passed": true,
        "checks": [
          "Source repair and destination copy preserve source pixels and relocate selection",
          "Gradient-domain color adaptation and transparent new-layer output",
          "Feathered selection, all-layer sampling, empty target and pixel/transparency locks",
          "Cancellation, invalid donor guard and PSD/PSB patch pixels"
        ]
      },
      "freshRun": false
    },
    {
      "file": "precision-retouch-results.json",
      "sha256": "2c3afb05465538fd360771684b1f9c6bfca4d30e2cafe5af027ea911ed6ad23a",
      "results": {
        "passed": true,
        "checks": [
          "clone",
          "heal",
          "dodge",
          "burn",
          "sponge",
          "blur",
          "sharpen",
          "smudge",
          "mixer",
          "spot",
          "remove",
          "fill and patch current",
          "fill and patch new",
          "content-aware scale",
          "RGB16 clone and tiny-alpha preservation",
          "RGB16 dodge and tiny-alpha preservation",
          "RGB16 blur and tiny-alpha preservation",
          "Gray16 clone and tiny-alpha preservation",
          "Gray16 dodge and tiny-alpha preservation",
          "Gray16 blur and tiny-alpha preservation",
          "Lab16 clone and tiny-alpha preservation",
          "Lab16 dodge and tiny-alpha preservation",
          "Lab16 blur and tiny-alpha preservation",
          "CMYK16 clone and tiny-alpha preservation",
          "CMYK16 dodge and tiny-alpha preservation",
          "CMYK16 blur and tiny-alpha preservation"
        ],
        "selectionOutside": "exact",
        "sourceUnchanged": true
      },
      "freshRun": false
    }
  ]
}