On 27 July we quietly opened Parjanya 2.0 to a small group of photographers and asked them to do one thing: upload real shoots, not portfolios, and tell us and looked for their feedback and how they would wanted the application to be. Twenty-plus people took us up on it: wildlife, nature, landscape and architecture photographers, from working professionals to few who bought their first camera this year and mobile photographer. They brought 1,400-frame safari mornings, bracketed dawns, archival film scans and RAW from bodies our decoder had never met. By this weekend the pipeline had enriched 18,884 images across more than 18 file formats for that group.
Today it is open to everyone. This post is the release notes: what Parjanya does, who tested it and what they found, everything that changed between the July baseline and now, and what is coming next. The engineering detail is here too, because this blog has always been the place for it.
What Parjanya does, in two passes
You drop a folder or files from your card or hard drive straight into the browser, and the files go from the browser directly into private storage over signed, resumable transfers. The moment the upload says complete you can close your browser or session: the analysis picks the work up on its own, and every upload and every verdict is recorded as a replayable intent, so nothing is lost to a dropped connection or a busy GPU. (The upload path and the reconciliation model behind it, TBIE, in-house research paper successfully verified for our usecase and evolved and tested for 18+ usecases.) Parjanya makes fast previews from every file (majority is RAW files across DSLR, mirrorless, mobile phones and Analog converted to Digital) and then checks each frame twice, in a fixed order.
Pass one is a technical gate. Cheap, strict, and deliberately narrow: unreadable or damaged files, images whose pixel size disagrees with what the file claims, blank frames, near-solid exposures (a frame is set aside only when almost every pixel is pure white or pure black, so brackets and silhouettes pass), duplicates by perceptual fingerprint (frames within ten seconds on the same body are a burst, never duplicates), and screenshots or exports in formats no camera writes will be filtered out. Anything set aside lands in Skip with the reason attached. Nothing is deleted.
Pass two is VLM enrichment. A vision-language model running on our own GPUs reads the frame and writes what you see on the detail page: what the photo is doing, how it is composed, what is holding it back and how strongly, plus the tags search runs on. A deterministic rule engine turns those findings into Keeper, Review or Skip with the reason attached. There is no score out of ten, on purpose: the same findings give the same verdict every time. (our v2.0 major change proved score engine doesn’t hold true and a deterministic rule engine does the best for our usecase)
You curate in a three-tab gallery where any verdict can be overruled, search the shoot in your own words (”leopard in dappled light”, “long exposure, silky water”, “symmetry, blue hour”), and after 500 uploads you get Parjanya Vision: a report card written like a coach rather than a mark sheet.
The people who tested it
The pilot group was small enough that every one of them changed something. A wildlife shooter pressed Stop on a 479-image batch expecting a pause; that single click is why Pause and Resume exist. A documentary photographer was first to point out that a Review/Skip line drawn only on technique penalises intentional motion and grain, which is now an open design question on the tracker (#58). Someone on their first camera uploaded iPhone photos that were accepted and never analysed. An archivist uploaded 16-bit grayscale scans that came back as blank white frames(#87). A landscape photographer with a body released this year sent RAW files our decoder had never seen, and they came back in false colour until it learned to fall back to the camera’s own embedded preview. And a mix of legacy camera bodies, manual lens and more.
Several of the pilot group are credited on the public tracker against the issues they raised; where someone preferred to stay unnamed, the issue says “pilot feedback” and nothing more. The onboarding guide itself, the ten-minute walkthrough new users get today, was recommended by one of the pilot experts.
Thank you, all of you. The list of fixes below is mostly your list.
https://github.com/JagadeeshRampam/parjanya-issues/issues
What changed since the July baseline
The v2.0.0 baseline was cut on 11 July after a 12,000-image validation run. Between then and today, 34 items on the public tracker were closed. Grouped by what you will notice:
Uploads and formats
iPhone photos process now. HEIC and HEIF were on the supported list and were accepted at upload, then stranded silently with no preview and no analysis. The decoder library was installed the whole time; the one line that registers it with the imaging library had been lost in a refactor. Fixed and verified on real iPhone uploads (#40).
16-bit grayscale scans no longer come back white. Single-channel 16-bit TIFFs were clipped to solid white during preview generation and then, correctly, set aside as blank. The fix rescales by bit depth and validates every preview it writes. All 28 affected images were reprocessed (#87).
Canon CR3 previews lost their magenta cast and dark border (#16).
Filenames with spaces render previews again (#69), and camera and lens names no longer carry trailing padding from fixed-width metadata fields, which had been splitting one lens into two entries in filters (#48).
Upload progress no longer flashes “Uploading: 0” mid-transfer (#3), and switching accounts in the same tab no longer shows the previous account’s upload bar (#33).
When an upload is blocked, by a trial cap or an account hold, the app now says why and what to do, instead of a generic error (#24).
Processing you can control
Pause and Resume. Stop was permanent, and a photographer found that out on a 479-image batch. Pause parks queued work and Resume picks it up exactly where it left off; a frame already being analysed when you pause finishes and keeps its result (#36). Stop still exists and now sticks end to end, including for work already in flight (#32).
“Warming up the AI analysis.” The GPU fleet starts on demand. When it is starting, the gallery now says so, so a cold start reads as a cold start and not as a broken product (#62).
Screenshots are turned away before they reach the GPU. Nine screenshots uploaded in August all passed the technical checks and three were accepted as good photographs. A metadata gate now rejects non-photographic content first (#64).
Reading the analysis
Critique and improvements are two cards now. The critique is served exactly as written. The one or two actions worth taking were previously the last sentence of an italic paragraph most readers had stopped reading; they are now their own card, and they never repeat what the critique already said (#93).
Burst groups show a per-frame breakdown when the frames in a burst got different verdicts (#1).
The gallery badge showed “Pending” for every auto-curated image because two parts of the system spelled the verdict differently. Fixed (#90).
Gallery and search
Newest first. The gallery was not listing your newest uploads first, which meant your own upload could be invisible to you. It reads from a recency index now (#66), and the three tabs agree on what “newest” means (#68).
Semantic re-ranking using SigLIP 2 image embeddings is integrated behind a flag, and search now says visibly when it has fallen back to keyword ranking (#28, #30). Content filters for scene, lighting and mood are still hidden until every image carries those tags (#72, #25).
Parjanya Vision
The report card shipped on 9 September. It started life as a per-shoot summary idea (#85) and became a tenant-wide card: what you shoot, which camera bodies and formats, how far you zoom, where your Review pile clusters, how you curate (rescued versus demoted), and what to try. Every rate travels with its count. Copy is coach voice by rule; there is a test that fails the build if words like mistake or grade appear (#98).
Two same-day fixes after the first photographers opened it: bars that overflowed their card, and a horizontal fill bar that read like a progress meter for what is really two counts being compared. It is a vertical bar chart now (#99).
Account, trial and email
Sign-up provisions correctly (#22) and confirmation codes deliver (#23), which sounds like table stakes and was the last launch dependency to close.
Every account email exists now: three days before a trial ends, the day it ends, a follow-up a week later, when you are at 90% of a cap, when a cap is reached, and one for every action we take on an account, including a past-tense notice after a deletion completes (#88, #89, #104).
Where your photos live
Confidently, because it was audited before launch: your originals go from your browser straight into private, encrypted storage in Mumbai, in a space that belongs only to your account, with public access blocked at the bucket level and every connection over HTTPS. Every request is checked against your signed-in identity before it touches a record; there is no path from one photographer’s library to another’s. Every access to stored photos is written to an audit trail with alarms on any human or unexpected access. The vision model runs on GPUs we operate, so your photos are never sent to a third-party AI service and are never used to train models. And nothing is deleted by us: when a trial ends, uploads pause and everything already there stays readable and downloadable.
Search, in your own words
Search reads the critique, the composition notes and the closed-vocabulary tags the model writes for every frame (subject, scene, lighting, mood, dominant colours), so queries like elephant herd at a waterhole, backlit, dew on a spider web, ridgeline at dawn, layered haze or stairwell, geometric shadows work today. Two more pieces are built and switching on as the whole catalogue gets its tags and embeddings: filter chips for scene, lighting and mood, and a look-alike mode that ranks by visual similarity using SigLIP 2 image embeddings (#11, #25, #72).
Three things the pilot taught us
1. Stop is not Pause, and a UI should know the difference. The 479-image incident was not a bug; Stop did what it said. The bug was offering only an irreversible action for a reversible intent. Resume had one subtle requirement worth writing down: flip the records back to pending before re-queueing them. Queue first and a worker can pick the message up, still read “paused”, and drop the job on the floor.
2. Small uploads should not summon the whole fleet. GPU scaling used to step up on a timer whenever the queue was non-empty. A 13-image batch could scale to the maximum fleet, most of which arrived after the work was done, and the fleet then took 69 minutes to scale back down. Scaling now targets an exact capacity from visible-plus-in-flight queue depth; the same drain takes about four minutes. The accepted side effect is that scale-in occasionally interrupts a job mid-inference, which the queue’s visibility timeout retries (about 1% of images, zero lost) (#41).
3. “Supported” is a promise about acceptance, not decoding. The HEIC and 16-bit TIFF cases were the same class of problem: a format we would accept at upload and then fail on quietly. The legacy and edge-case list from the pilot is now long and mostly handled: RAW from bodies newer than the decoder’s database (falls back to the camera’s embedded preview instead of false colour), 16-bit and grayscale scans (rescaled by bit depth), iPhone HEIC, 25 RAW formats including Canon CRW, Sony SRF/SR2, Hasselblad 3FR/FFF, Phase One IIQ and Sigma X3F, filenames with spaces, manufacturer-padded camera names, bracketed exposures (pass the gate), bursts (stack, best frame ranked). Still open: older bodies and phone JPEGs that record no capture time can have burst frames flagged as duplicates (#70). Of the 34 formats, 18 are proven end to end in production; the next one we want a real file for is Fujifilm RAF (#42, #47). If you shoot Fuji, your first upload is a favour to us.
Numbers from the closed beta
20+ photographer accounts, from first-camera to full-time professional
18,884 images enriched, across 18+ file formats
104 issues filed on the public tracker since July; 34 closed, every one with what actually shipped
Launch-day verification: 100 human-checked images, 51 Keeper / 47 Skip / 2 Review, zero stranded
GPU drain after a small upload: 69 minutes → about 4 minutes
Cold start after an idle period: 5 min 32 s today; 90 s is the target
28 archival scans and 261 verdict records repaired in place, nothing deleted
The trial
30 days, 1,500 photos, 30 GB of storage including previews. Whichever runs out first ends the trial. Uploads pause at that point and nothing is removed; your gallery, critiques and downloads keep working. Ask and we can raise a cap on your existing account. No card is needed to start.
What is next
In roughly the order we expect to ship:
A “your shoot is ready” notification, email and in-app, so you can close the laptop after the upload completes and be told when the analysis is done. Today the first verdicts after an idle period wait about five and a half minutes for the AI to warm up; the target is 90 seconds (#105). Broader in-app notifications follow (#8).
Near-duplicate detection, burst-aware, on top of the exact-duplicate check that is live (#4)
Curation that learns from you. Every Keeper and Skip on a Review frame is already recorded; the model of your taste that reads them is next (#5)
Content filters in search once every image carries scene, lighting and mood tags (#72), and a relevance floor so weak semantic matches stop looking strong (#74)
Parjanya Vision phase 4: gear-specific advice that unlocks only when your own photos provide the evidence (#100), and phase 5, genre for your older photos from stored embeddings without reprocessing (#101)
Self-serve payment (#9), and burst covers that show the best frame rather than the middle one (#92)
The onboarding guide in more formats: a video walkthrough with voice-over is next (#53)
Everything, including the items we have not fixed yet, is public at github.com/JagadeeshRampam/parjanya-issues. Open and closed alike. The people who tested this deserved to see the list, and so do you.
Start
Onboarding guide, ten minutes start to finish: parjanya.phagyul.ai/guide.html
Create your account: parjanya.phagyul.ai/signup
For the pilot group of Experts across the world and my buddies: thank you again! 🙏
Jagadeesh
Engineering appendix (for readers who came for the systems)
Short entries; each has a longer post either published or drafted.
Why there is no score. The rule engine reads distortion type and severity (motion blur: heavy) rather than a numeric quality score. Scores compressed incompatible defects onto one axis and gave photographers nothing to act on. The model still emits one; the gate ignores it.
From Score Engine to Rule Engine: Why I Rebuilt the Decision Layer
·I did not set out to replace a scoring engine with a rule engine. I set out to make the system cheaper, easier to explain, and less fragile as I was not keen on moving to g5.xlarge or g6.xlarge due to prompt sizes increased and would be lot of churn in terms of architectural and infra changes, comes with re testing every functionality and the increase i…
Caching that never existed. The dashboards were designed against a response cache that was never provisioned in production, so every dashboard call recomputed. They now serve from a snapshot store warmed by an in-process loop; the admin pane, which took up to 29 seconds per range, answers in under a second (#34).
The month that weighed nothing. A field rename mid-July left usage attribution reading the old name and projecting only the old name from the database, so every image uploaded for a month contributed zero bytes to per-tenant attribution. The headline figure stayed right because it preferred a storage-measured value, which is exactly why nobody noticed. Lesson written down: a rename has to land in the projection too, and a test fixture that only builds one spelling cannot catch a rename (#81).
Idempotent email. Trial emails failed silently for three weeks after the flag went live because the execution role never received send permission, and a failed send was marked as delivered before it was attempted, so it could never retry. The rewrite is claim → send → confirm, with release on failure, and it is the helper every new notification now uses (#88, #89, #104).
Dedup that could eat a whole cluster. Symmetric concurrent rejection let every member of a duplicate cluster defer to another member that was also being discarded. Twelve images got no analysis. Survivors are now chosen by a total order, earliest wins (#97).
TBIE. The reconciliation model behind all of this, Truth, Belief, Intent, Execution, has its own post: From Pipeline to Platform. The white paper is in draft.
From localhost friction to production-shaped architecture
From localhost friction to production-shaped architecture
·Lessons from Parjanya v2.0 and the v5.4 architecture revision








