{"id":9745,"date":"2026-05-27T17:49:13","date_gmt":"2026-05-27T14:49:13","guid":{"rendered":"https:\/\/handoli.com\/index.php\/2026\/05\/27\/fossils-in-the-ground\/"},"modified":"2026-05-27T17:49:13","modified_gmt":"2026-05-27T14:49:13","slug":"fossils-in-the-ground","status":"publish","type":"post","link":"https:\/\/handoli.com\/index.php\/2026\/05\/27\/fossils-in-the-ground\/","title":{"rendered":"Fossils in the Ground"},"content":{"rendered":"<p class=\"wp-block-paragraph\"><a href=\"https:\/\/irisphotos.app\/\">Iris<\/a> ships today.<\/p>\n<p class=\"wp-block-paragraph\">2,023 days since the first line of code. Before I say anything about what it <em>is<\/em>, I want to show you what the app started as \u2014 because the two things barely resemble each other, and the gap between them is basically the whole story.<\/p>\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"721\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/hero-light-1024x721.jpg\" alt=\"\" class=\"wp-image-3056\"\/><\/figure>\n<p class=\"wp-block-paragraph\">That\u2019s the finished thing. Now let me rewind almost six years.<\/p>\n<h2 class=\"wp-block-heading\">It started as \u201cAntiPhoto,\u201d and it wasn\u2019t really a photo app<\/h2>\n<p class=\"wp-block-paragraph\">The first version, from November 2020, was called AntiPhoto. The name was a <em>mood<\/em>. I had tens of thousands of photos and videos scattered across drives and old phone backups, and Apple Photos wanted me to live inside <em>its<\/em> library, on <em>its<\/em> terms. I didn\u2019t want a walled garden. I wanted something that could point at a messy folder and just make sense of it.<\/p>\n<p class=\"wp-block-paragraph\">So the very first build wasn\u2019t about browsing pretty pictures at all. It was a triage tool. It scanned a folder and tried to <em>understand<\/em> each image \u2014 running it through machine learning models to pull out scene categories, objects, and any text it could find.<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"713\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/02_antiphoto_grid-1024x713.jpg\" alt=\"\" class=\"wp-image-3057\"\/><\/figure>\n<p class=\"wp-block-paragraph\"><em>AntiPhoto, week one. Every photo auto-tagged with whatever the models thought was in it. Half of these tags are wrong, which was sort of the point \u2014 I was trying to see how far this could go.<\/em><\/p>\n<p class=\"wp-block-paragraph\">Behind the grid was a little command-line program I called <code>TriageDemo<\/code>. You pointed it at a directory and it printed out everything it could infer per image: categories with confidence scores, detected objects, OCR\u2019d text, the works.<\/p>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"641\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/03_triage_terminal-1024x641.jpg\" alt=\"\" class=\"wp-image-3058\"\/><\/figure>\n<p class=\"wp-block-paragraph\"><em>The actual seed of the whole project: <code>TriageDemo<\/code> chewing through a folder, scoring every guess. \u201cCategory: structure 0.996. Term: people 0.98. Term: sign 0.85.\u201d<\/em><\/p>\n<p class=\"wp-block-paragraph\">If you\u2019d asked me then, I\u2019d have told you I was building a search engine for your own hard drive. Faces, things, text-in-images \u2014 index all of it, make it findable. The fact that it happened to contain your family photos was almost incidental.<\/p>\n<p class=\"wp-block-paragraph\">That framing didn\u2019t last.<\/p>\n<h2 class=\"wp-block-heading\">Renaming to Iris<\/h2>\n<p class=\"wp-block-paragraph\">By the end of December 2020, \u201cAntiPhoto\u201d had become Iris. (The internal library format kept the name <code>AntiPhotoLibrary<\/code> for an embarrassingly long time afterward \u2014 you can still find it lurking in old screenshots.) Within about six weeks the skeleton of the real app was already there: sources, dates, places, people, things, and a status bar quietly counting how much it had scanned.<\/p>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"698\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/04_iris_2020-1024x698.jpg\" alt=\"\" class=\"wp-image-3059\"\/><\/figure>\n<p class=\"wp-block-paragraph\"><em>December 2020. Newly renamed, already counting EXIF, GPS, ML, and hash passes in the status bar. Everything after this was variations on a theme.<\/em><\/p>\n<p class=\"wp-block-paragraph\">I liked \u201cIris\u201d because it refused to mean one thing. It\u2019s the iris of your <strong>eye<\/strong>. It\u2019s the <strong>aperture<\/strong> of a camera. And it\u2019s the <strong>flower<\/strong>. I spent a genuinely unreasonable amount of the next several years unable to decide which of those three the app actually was. You can watch me fail to decide, right in the icon.<\/p>\n<h2 class=\"wp-block-heading\">The icon saga<\/h2>\n<p class=\"wp-block-paragraph\">This is the part I\u2019m most sheepish about. Here is the design \u201cprocess,\u201d and I use that word generously. A lot of bad clip-art testing out ideas and even worse <s>Photoshop<\/s> Acorn choices.<\/p>\n<p class=\"wp-block-paragraph\">It began on-the-nose: an eyeball, inside a camera lens. Both meanings of \u201ciris,\u201d literally stacked on top of each other.<\/p>\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"760\" height=\"760\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/05_icon_eye.jpg\" alt=\"\" class=\"wp-image-3060\"\/><\/figure>\n<p class=\"wp-block-paragraph\"><em>Exhibit A: the \u201cwhat if we just did both\u201d icon. An eye. In a lens. Subtle.<\/em><\/p>\n<p class=\"wp-block-paragraph\">Then I swung hard toward the flower. In January 2022 the icon became a sketched iris bloom \u2014 blue fading to magenta, on a purple tile. Meh. It also looked nothing like a utility for searching 100,000 files, which is what the app actually was by then.<\/p>\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"900\" height=\"860\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/06_icon_painted_iris.jpg\" alt=\"\" class=\"wp-image-3061\"\/><\/figure>\n<p class=\"wp-block-paragraph\">Then, in late 2022, image-generation tools showed up and I completely lost the plot. I generated <em>dozens<\/em> of camera-lens-inside-a-flower icons and saved them all in a folder I named, with no irony, \u201cIcon Apps.\u201d Antique. Black. Blurred Rainbow Waves. Drippy Flower. Funky Shape. Purple Stars. Starfield. White. I could not stop.<\/p>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"755\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/07_icon_apps_grid-1024x755.jpg\" alt=\"\" class=\"wp-image-3062\"\/><\/figure>\n<p class=\"wp-block-paragraph\"><em>A small sample of the icon binge. There were more. There are always more.<\/em><\/p>\n<p class=\"wp-block-paragraph\">I even went to space.<\/p>\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"760\" height=\"760\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/08_icon_space.jpg\" alt=\"\" class=\"wp-image-3063\"\/><\/figure>\n<p class=\"wp-block-paragraph\"><em>\u201cSpace Iris.\u201d This version hung around for a surprisingly long time through early beta versions that friends and family were testing.<\/em><\/p>\n<p class=\"wp-block-paragraph\">For even longer, it came back around to, fittingly, a flower After four years and a few dozen detours, the eye and the lens quietly stepped aside and let the flower win.<\/p>\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"1024\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/icon_512x512@2x.png\" alt=\"\" class=\"wp-image-3064\"\/><\/figure>\n<p class=\"wp-block-paragraph\">But then Apple came around and decided to put everyone\u2019s Mac apps in <em><a href=\"https:\/\/9to5mac.com\/2025\/08\/08\/macos-tahoe-fix-gray-box-icons\/\">squircle jail<\/a><\/em>. I needed to align with Tahoe\u2019s demoralizing icon design guidelines and keep everything within the squircle bounds. Which led to this compromise:<\/p>\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"1024\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/tahoe-flower.png\" alt=\"\" class=\"wp-image-3065\"\/><\/figure>\n<p class=\"wp-block-paragraph\">As much as I had learned to love the rainbow flower over the two years it was the app\u2019s icon, it had way too much detail \u2014 especially in the modern Apple design era.<\/p>\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"1024\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/Iris-App-Icon-1024.png\" alt=\"\" class=\"wp-image-3066\"\/><\/figure>\n<p class=\"wp-block-paragraph\">Which brings us to the final icon design that Iris ships with today.<\/p>\n<h2 class=\"wp-block-heading\">The modes that came and went<\/h2>\n<p class=\"wp-block-paragraph\">Under the hood, Iris was organized around <strong>modes<\/strong> \u2014 a Browse \/ Organize \/ Find toggle at the top of the window. By 2022 you could see it sitting (smugly) right next to Apple Photos, which is exactly where I kept it while I worked.<\/p>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"584\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/09_side_by_side_photos-1024x584.jpg\" alt=\"\" class=\"wp-image-3067\"\/><\/figure>\n<p class=\"wp-block-paragraph\"><em>Iris (right) next to the thing it was a reaction to (left), August 2022. Note the \u201cimage analysis remaining\u201d counter \u2014 there was always more to scan.<\/em><\/p>\n<p class=\"wp-block-paragraph\">Some of those modes were wildly ambitious, and not all of them survived contact with reality. My favorite casualty is <strong>Explore Mode<\/strong> \u2014 a drag-and-drop visual query builder I described in my own notes as \u201cAdvanced Search for Normals.\u201d The idea was that you\u2019d drag People, Places, Things, and Text onto a canvas and wire them together with AND\/OR connectors to build a search visually, no query syntax required.<\/p>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"705\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/10_explore_mode-1024x705.jpg\" alt=\"\" class=\"wp-image-3068\"\/><\/figure>\n<p class=\"wp-block-paragraph\"><em>Explore Mode, as sketched on my iPad. I still think this is a good idea. I also fully understand why it didn\u2019t ship in this form \u2014 note my own margin note worrying about whether places have to be OR\u2019d \u201cb\/c a photo can\u2019t be in more than one at a time.\u201d<\/em><\/p>\n<div><\/div>\n<p class=\"wp-block-paragraph\">This is the only screen recording of the old Explore Mode I could find.<\/p>\n<p class=\"wp-block-paragraph\">Then there was also <strong>Organize Mode<\/strong>, which was its own little universe. You\u2019d collect items onto a \u201cshelf,\u201d then run batch operations on the whole shelf at once: set dates, fix locations, sort into date folders, correct OCR. There was a whole scored <strong>duplicate finder<\/strong> in there \u2014 same filename worth +2, same size +1, same hash +5, with a hopeful \u201cML?\u201d scribbled at the bottom \u2014 that computed a \u201cdupe %\u201d for every candidate.<\/p>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"705\" height=\"1024\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/11_organize_mode-705x1024.jpg\" alt=\"\" class=\"wp-image-3069\"\/><\/figure>\n<p class=\"wp-block-paragraph\"><em>Organize Mode. Half of this shipped, half of it is still a someday-maybe, and the duplicate scorer was way more fun to design than it had any right to be.<\/em><\/p>\n<p class=\"wp-block-paragraph\">The same notebooks have pages and pages on <strong>People<\/strong>: per-person \u201clifestreams,\u201d matching faces by vector distance (the more faces you confirm, the better the guesses get), a biography view that charts how often someone appears in your photos by age, and a wistful note asking whether I should let you group people into families. Some of that is in the app today. Some of it is still just ink.<\/p>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"768\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/Biography-1024x768.jpg\" alt=\"\" class=\"wp-image-3071\"\/><\/figure>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"607\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/People-Editor-1024x607.jpg\" alt=\"\" class=\"wp-image-3072\"\/><\/figure>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"821\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/People-Window-1024x821.jpg\" alt=\"\" class=\"wp-image-3073\"\/><\/figure>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"741\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/Timeline-1024x741.jpg\" alt=\"\" class=\"wp-image-3074\"\/><\/figure>\n<div><\/div>\n<p class=\"wp-block-paragraph\"><em>One last, random, video. Iris had a prototype interactive graph view (like <a href=\"https:\/\/obsidian.md\/\">Obsidian<\/a>) that shows a visually weighted representation of how your photos connect with each other by way of people, places, dates, and things.<\/em><\/p>\n<h2 class=\"wp-block-heading\">The boring work nobody sees<\/h2>\n<p class=\"wp-block-paragraph\">For every dreamy sketch there were months of deeply unglamorous hitting my head against the wall, none of which makes a good screenshot. The single hardest problem was often just <em>scrolling<\/em>. A photo library isn\u2019t 200 items, it\u2019s 200,000+, and they all have different aspect ratios, and you want a buttery justified grid that never stutters. I have a screen recording I named \u201c100k Spinning Scroll\u201d from April 2022 \u2014 the day a library of <strong>101,706 items<\/strong> finally scrolled without choking \u2014 and I remember it feeling like a bigger win than any feature. But even today, Iris has performance hiccups \u2014 especially around complex searches and truly massive libraries. But if I waited to solve every bug, I\u2019d never ship.<\/p>\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"617\" src=\"https:\/\/cdn.tyler.io\/wp-content\/uploads\/2026\/05\/12_100k_inspector-1024x617.jpg\" alt=\"\" class=\"wp-image-3075\"\/><\/figure>\n<p class=\"wp-block-paragraph\"><em>101,706 items, scrolling smoothly at last. That meant a custom collection-view layout, a background scanning daemon, and a lot of staring at memory graphs.<\/em><\/p>\n<p class=\"wp-block-paragraph\">That daemon \u2014 <code>IrisScanner<\/code> \u2014 was its own saga. It does all the heavy lifting (EXIF, hashing, location lookups, face and object ML) in the background without making the app feel slow or eating your RAM. I spent a good chunk of 2023 in Instruments getting it to do all of that while holding steady around 266 MB. Nobody will ever notice this work, which is exactly the goal.<\/p>\n<h2 class=\"wp-block-heading\">What Iris actually became<\/h2>\n<p class=\"wp-block-paragraph\">Here\u2019s the part I didn\u2019t see coming. That original triage idea \u2014 the thing that made me call it <em>AntiPhoto<\/em> \u2014 never died. It just grew up. <\/p>\n<p class=\"wp-block-paragraph\">And somewhere along the way the whole emotional center of the thing shifted. I set out to build an anti-Photos <em>utility<\/em> \u2014 a search engine for a hard drive. What I actually ended up with is a memory keeper. Open a photo today and Iris tells you the date, surfaces \u201c16 items on this day,\u201d drops a pin on the map, and lists the people in the frame with their ages quietly calculated from their birthdays. That is not a utility. That is the opposite of anti-anything.<\/p>\n<p class=\"wp-block-paragraph\">I think that\u2019s the real lesson from digging through six years of old screenshots. You start with a thesis \u2014 <em>mine was basically \u201cApple Photos is not for me\u201d<\/em> \u2014 and you build toward it. But the app keeps making little counter-arguments. The scroll work pulls you toward big libraries. The face work pulls you toward people. The \u201con this day\u201d experiment pulls you toward nostalgia. And one day you look up and the spiteful little triage tool has become a thing you\u2019re genuinely fond of, named after a flower you spent three years refusing to commit to.<\/p>\n<p class=\"wp-block-paragraph\">Stephen King is my favorite author. And if you don\u2019t count <em><a href=\"https:\/\/en.wikipedia.org\/wiki\/The_Elements_of_Style\">The Elements of Style<\/a><\/em>, he wrote the best book <em>ever<\/em> about writing, <em><a href=\"https:\/\/en.wikipedia.org\/wiki\/On_Writing:_A_Memoir_of_the_Craft\">On Writing<\/a><\/em>. He says:<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u201cStories are found things, like fossils in the ground.\u201d<\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\">The same can be said about software. Apps go where they want to go. The best you can do is keep showing up and let them.<\/p>\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/irisphotos.app\/\">Iris is out today<\/a>. Thanks for being here for the wrong turns.<\/p>","protected":false},"excerpt":{"rendered":"<p>Iris ships today. 2,023 days since the first line of code. Before I say anything about what it is, I want to show you what the app started as \u2014 because the two things barely resemble each other, and the gap between them is basically the whole story. That\u2019s the finished thing. Now let me [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":9746,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rop_custom_images_group":[],"rop_custom_messages_group":[],"rop_publish_now":"initial","rop_publish_now_accounts":[],"rop_publish_now_history":[],"rop_publish_now_status":"pending","footnotes":""},"categories":[1,15],"tags":[],"class_list":["post-9745","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-explore","category-world"],"_links":{"self":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/posts\/9745","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/comments?post=9745"}],"version-history":[{"count":0,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/posts\/9745\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/media\/9746"}],"wp:attachment":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/media?parent=9745"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/categories?post=9745"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/tags?post=9745"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}