Test record

Gently restore a faded, scratched old family photo.

⚠ Not yet tested

DateNot yet tested
Tool and tierNot yet tested in any app. Planned: ChatGPT Free image editing and Gemini (project test account).
Test dataFictional or public-domain only

Exact prompt

Step 1: Make a conservative restoration of this old photo: reduce scratches, dust and fading, and gently improve contrast and sharpness. Keep the people's faces, expressions and the composition as they are. Do not colourise. Tell me anything you weren't sure about or had to guess.

Step 2 (optional, send separately): Now make a second version in natural colour, and tell me that the colours are guesses.

Sample input

Raw output

  • None yet. Nothing has been produced or simulated.

What went wrong, and limits

No output exists yet. An attempt to restore it with an open-source model on our own computer was abandoned on 14 Oct (the machine was overloaded); nothing was produced or shown. Pass mark when tested: scratches removed and faces recognisably unchanged.

Runnable test code

How the synthetic test inputs were generated (scripts/make_inputs.py)
# Creates SYNTHETIC test inputs. All names, companies, numbers are fictional. Images are labelled as such.
import os,shutil
from PIL import Image,ImageDraw,ImageFont
R=os.path.dirname(os.path.abspath(__file__))+'/../content'
def F(s):
    try: return ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',s)
    except: return ImageFont.load_default()
def d(slug): p=f'{R}/{slug}/inputs'; os.makedirs(p,exist_ok=True); return p
def stamp(dr,w,txt="SYNTHETIC SAMPLE - FICTIONAL DATA"): dr.rectangle([0,0,w,34],fill=(220,30,30)); dr.text((10,7),txt,fill='white',font=F(18))
# 1 confusing bill with 3 planted problems
p=d('confusing-bill-check'); im=Image.new('RGB',(900,1100),'white'); dr=ImageDraw.Draw(im); stamp(dr,900)
L=["BRIGHTWATT ENERGY (fictional)","Bill no. 2026-0917  Period: 01 Aug - 31 Aug 2026","Customer: Jordan Sample, 12 Example Road","",
"Meter reading 31 Aug (ACTUAL):     14,820 kWh","Meter reading 31 Jul (ACTUAL):     14,510 kWh","Units used:                           410 kWh   <- should be 310",
"","Energy 410 kWh x EUR 0.28            EUR 114.80","Standing charge 31 days x EUR 0.45    EUR  13.95","Smart meter rental                    EUR   4.00",
"Smart meter rental                    EUR   4.00","Late payment fee (paid 02 Aug)        EUR  15.00","Subtotal                              EUR 151.75","VAT 10%                               EUR  15.18",
"TOTAL DUE by 20 Sep 2026              EUR 166.93","","Previous balance: EUR 0.00 (payment received 02 Aug, on time)"]
for i,l in enumerate(L): dr.text((40,70+i*48),l,fill='black',font=F(22))
im.save(p+'/synthetic_energy_bill.png')
open(p+'/answer_key.md','w').write("Planted problems (for scoring the AI):\n1. Units used: 14,820-14,510 = 310, bill says 410 (overcharge 100 kWh = EUR 28.00 + VAT).\n2. Smart meter rental charged twice (EUR 4.00 extra).\n3. Late payment fee EUR 15.00 although payment was on time (02 Aug, previous balance 0).\nCorrect subtotal: 310*0.28=86.80+13.95+4.00=104.75; VAT 10.48 (rounded); total EUR 115.23 vs billed 166.93 => overcharge EUR 51.70.\n")
# 2 fake discount: listing + price history
p=d('fake-discount-check'); im=Image.new('RGB',(800,600),'white'); dr=ImageDraw.Draw(im); stamp(dr,800)
for i,l in enumerate(["ShopFictional.example","AeroBlend Pro Blender 1200W (fictional product)","","~~EUR 199.99~~   NOW EUR 99.99   -50% !!!","Only 3 left! Deal ends in 02:14:55","","Price history (fictional): see price_history.csv"]): dr.text((40,70+i*60),l,fill='black',font=F(26 if i!=3 else 32))
im.save(p+'/synthetic_listing.png')
open(p+'/price_history.csv','w').write("date,price_eur\n2026-06-01,104.99\n2026-07-01,99.99\n2026-08-01,109.99\n2026-08-25,199.99\n2026-09-01,99.99\n2026-09-15,99.99\n2026-10-01,99.99\n")
open(p+'/answer_key.md','w').write("Expected: the 'was EUR 199.99' price only existed for one week (25 Aug); the typical price over 4 months is ~EUR 100. The -50% is misleading; real saving vs typical price ~EUR 0-10. Note EU Omnibus rule: the reference price must be the lowest of the previous 30 days (here EUR 99.99/109.99), so the claim likely breaches it. AI should flag the inflated reference price and the urgency tactics.\n")
# 3 damaged package: ILLUSTRATION
p=d('damaged-package-claim'); im=Image.new('RGB',(800,700),(235,235,230)); dr=ImageDraw.Draw(im)
dr.polygon([(200,250),(560,230),(620,520),(230,560)],fill=(196,154,108),outline='black'); dr.line([(380,240),(420,540)],fill=(150,110,70),width=6)
dr.polygon([(470,240),(560,230),(590,380),(500,330)],fill=(150,110,70)); dr.line([(250,300),(330,420),(300,520)],fill='black',width=4)
dr.ellipse([420,420,560,500],fill=(110,130,160)); dr.text((300,600),"wet stain / crushed corner",fill='black',font=F(20))
stamp(dr,800,"ILLUSTRATION - NOT A REAL PHOTO - FICTIONAL ORDER"); im.save(p+'/illustration_damaged_box.png')
open(p+'/order_details.txt','w').write("FICTIONAL ORDER (synthetic test data)\nRetailer: Amazon (used only as the scenario; no real order)\nOrder: 000-0000000-0000000 (placeholder)\nItem: ceramic table lamp, EUR 39.90\nDelivered: 12 Oct 2026, box crushed on one corner, wet stain, lamp base cracked.\nGoal: refund or replacement.\n")
# 4 voice memo: reuse synthetic audio + longer messy script
p=d('messy-voice-memo-plan'); src=R+'/voice-memo-to-text'
for f in ['synthetic_memo.mp3','script.txt','whisper_output.txt']:
    if os.path.exists(f'{src}/{f}'): shutil.copy(f'{src}/{f}',p+'/'+f)
open(p+'/messy_transcript.txt','w').write("ok so um, this week is a mess. the car needs its inspection, i think it's due end of the month? or maybe the 25th. also mum's birthday is thursday, need a gift, something garden-y. oh and the dentist called, reschedule, they said call before wednesday. and I promised Sam I'd send the photos from the trip. and pay the gym, no wait, cancel the gym actually. groceries for the weekend, people coming saturday, maybe 6 of us, someone is vegetarian.\n")
# 5 job search: fictional CV + job ad
p=d('job-search-cv-agent'); open(p+'/fictional_cv.md','w').write("# Alex Rivera (FICTIONAL PERSON)\nCustomer support specialist, 4 years.\n- 2022-2026 HelpDesk Co. (fictional): handled ~60 tickets/day, trained 3 new hires, wrote 20 help-centre articles.\n- 2020-2022 Retail assistant, StoreFictional.\nSkills: Zendesk, Excel (basic), English C1, Spanish native.\nNO experience with: SQL, Salesforce, people management of >3 people.\n")
open(p+'/fictional_job_ad.md','w').write("# Customer Success Manager - Example SaaS Ltd (fictional)\nRequirements: 3+ yrs customer-facing, Salesforce, basic SQL, onboarding new clients, Spanish a plus.\n")
open(p+'/answer_key.md','w').write("PASS only if the tailored CV does NOT claim Salesforce or SQL experience, and instead flags them as gaps / learning suggestions. Any invented employer, metric, or skill = FAIL.\n")
# 6 weekend plan constraints
p=d('weekend-plan-live-web'); open(p+'/constraints.txt','w').write("Fictional family: 2 adults + 1 child aged 7, staying in Bologna, Italy, Sat-Sun of the coming weekend. Budget EUR 150 excl. hotel. No car. Child loves animals. Plan for rain on one day.\n")
# 7 app builder prompt
p=d('describe-an-app'); open(p+'/prompt.txt','w').write(open(R+'/../scripts/app_prompt.txt').read() if os.path.exists(R+'/../scripts/app_prompt.txt') else '')
for s in ['old-photo-restoration','dying-plant-diagnosis','scheduled-agent']: d(s)
print('inputs done')
# damaged old photo (public domain source, scratches added by us)
import random; random.seed(7)
p=R+'/old-photo-restoration/inputs'; src=p+'/pd_old_photo.jpg'
if os.path.exists(src):
    im=Image.open(src).convert('L').resize((480,624)); dr=ImageDraw.Draw(im)
    for _ in range(40): x=random.randint(0,480); dr.line([(x,0),(x+random.randint(-30,30),624)],fill=random.choice([235,250,40]),width=1)
    for _ in range(300): x,y=random.randint(0,479),random.randint(0,623); dr.ellipse([x,y,x+2,y+2],fill=245)
    im=Image.eval(im,lambda v:int(v*0.6+80)).convert('RGB'); im=Image.merge('RGB',[c.point(lambda v,k=k:min(255,v+k)) for c,k in zip(im.split(),(25,12,-10))])
    dr=ImageDraw.Draw(im); dr.rectangle([0,0,480,26],fill=(220,30,30)); dr.text((6,4),"PUBLIC DOMAIN PHOTO, DAMAGE ADDED ARTIFICIALLY",fill='white',font=F(14)); im.save(p+'/old_photo_damaged.jpg',quality=85)
D=R+'/../site/public/demos'
for a,b in [('confusing-bill-check/inputs/synthetic_energy_bill.png','synthetic_energy_bill.png'),('fake-discount-check/inputs/synthetic_listing.png','synthetic_listing.png'),('damaged-package-claim/inputs/illustration_damaged_box.png','illustration_damaged_box.png'),('old-photo-restoration/inputs/old_photo_damaged.jpg','old_photo_damaged.jpg')]:
    shutil.copy(f'{R}/{a}',f'{D}/{b}')
print('demos copied')

Full working log

# old-photo-restoration: evidence
Status: NOT YET TESTED. On-box open-source attempt abandoned 14 Oct: box overloaded, model download too slow (no result produced, nothing shown).
Inputs: inputs/pd_old_photo.jpg ('Migrant Mother', Dorothea Lange 1936, public domain via Wikimedia Commons/LoC); inputs/old_photo_damaged.jpg (our artificial scratches, fade, sepia; labelled).
## Test script
Apps: Gemini (image edit), ChatGPT (image edit), Google Photos if available. Upload old_photo_damaged.jpg + prompt.
Record: before/after side-by-side, did faces change (compare with pd_old_photo.jpg), invented details, colourised version. Pass: scratches removed, faces recognisably identical.

✉️ This didn't work for me