I’m going to use KILO as the working name (you can swap later).

0) One-page concept

KILO is a photography operating system where “chat + moments + best picks” replaces folders + sliders.

North Star: Time-to-delivery (from ingest → client-ready) goes from hours to minutes.

Core loop

  1. Ingest
  2. AI moments + savage cull
  3. Style DNA batch edit
  4. Deliver proof gallery + selects + invoice + print store
  5. Archive becomes searchable forever

Differentiators

  • AI culling that feels like a top assistant
  • Personalized ranking from your taste
  • Style DNA: consistent look across years
  • “Ask your archive” as the default interface
  • Client delivery that’s premium + monetized

1) PRD — Product Requirements Document

1.1 Goals

  • Cut culling time by 70–90% without sacrificing keepers.
  • Make edits consistent (your signature look, not generic).
  • Instant retrieval: find any photo by meaning, not folder.
  • Client experience: proof → selects → pay → deliver in one flow.
  • Creator control: ownership, privacy, opt-in training.

1.2 Non-goals (for V1)

  • Full Photoshop replacement.
  • Full Lightroom catalog parity on day 1.
  • Generative “make new images” features (high risk, not needed to win).
  • Public social network feed (keep focus on workflow + delivery).

1.3 Target users & personas

Persona A — Working Photographer (Primary)

  • Shoots: events / portraits / weddings / editorial / street
  • Pain: culling, consistency, delivery, admin overhead
  • Win condition: “I can deliver faster with higher quality and less brain melt.”

Persona B — Studio Owner (Primary)

  • Needs: team roles, approvals, consistent style across shooters
  • Win condition: “My editors move faster; quality is standardized.”

Persona C — Creator (Secondary)

  • Needs: story packs, carousel crops, captions in voice
  • Win condition: “I publish daily without drowning.”

Persona D — Client (Secondary)

  • Needs: frictionless proofing + selecting + paying
  • Win condition: “I can pick favorites easily and get my photos fast.”

1.4 Jobs-to-be-done (JTBD)

  • “When I import a shoot, help me instantly find the best frames.”
  • “When I edit, make it look like me every time.”
  • “When a client asks for ‘that shot’, I can find it in seconds.”
  • “When I deliver, it feels premium and I get paid cleanly.”

1.5 Key user journeys

Journey 1: Ingest → Cull → Edit → Deliver (MVP journey)

  1. Import from card/folder
  2. AI creates previews + embeddings + moments
  3. Cull in stacks (winner preselected)
  4. Apply Style DNA
  5. Publish proof gallery
  6. Client selects favorites
  7. Invoice/checkout + delivery

Journey 2: “Ask your archive”

  • User: “Show my best night street portraits with neon + rain.”
  • System: returns a ranked grid + optional story sequence.

Journey 3: Studio workflow

  • Shooter uploads → Editor culls + edits → Owner approves → Client delivery.

1.6 Feature set

MVP (launchable, lethal)

Ingest

  • Import from SD/folder, watch folder, upload progress, resume
  • Auto-duplicate detection at ingest
  • Generate thumbnails + smart previews

Cull

  • Auto-cluster into “moments”
  • Burst winner suggestion
  • Keyboard-first pick/reject/rate
  • Compare view inside cluster
  • “One-breath” personalization: learn preference from first few picks

Edit

  • Global fixes (exposure/WB/contrast)
  • Style DNA (lite): learn from your edits/presets
  • Batch apply + sync across similar lighting
  • Smart masks (subject/sky/background) optional in V1 (can be V1.5)

Search

  • Semantic search (“red umbrella”, “laughing”, “neon street”)
  • Metadata filters (camera, lens, date, rating)

Client Delivery

  • Proof gallery + hearts/stars + comments
  • Download delivery (web)
  • Basic invoicing/payment integration (or link-out in MVP)

Privacy

  • Opt-in face clustering (off by default)
  • Opt-in training (off by default)

1.7 Functional requirements (detailed)

Ingest requirements

  • Support RAW + JPEG + HEIC (mobile)
  • Sidecar XMP support (read/write) for compatibility
  • Preserve EXIF/IPTC
  • Detect corrupted files and isolate
  • Generate:
    • thumbnail (small)
    • smart preview (medium)
    • histogram + exposure stats
    • embedding vector (for search)
    • perceptual hash (for duplicates)
  • Background processing queue with clear status UI

Acceptance criteria

  • Import 1,000 photos and start culling within 60 seconds (thumbnails visible fast; deeper processing can finish later).

Culling requirements

  • Clustering:
    • time-based segmentation + visual similarity
    • burst detection
  • Ranking:
    • sharpness/focus score
    • blur score
    • blink detection (opt-in face model)
    • aesthetic score (general + personalized)
    • uniqueness score (avoid redundancy)
  • UI:
    • stacks view (cluster)
    • winner preselected
    • instant key actions:
      • F pick / keep
      • D reject
      • 1-5 rating
      • C compare within stack
      • G go to next stack
      • S star
  • Explainability (lightweight):
    • “picked because: sharpest + best expression + clean background”
    • show top signals (not a novel)

Acceptance criteria

  • For bursts, the top-1 suggestion matches photographer’s final pick ≥ 60% early, improves to ≥ 75% after personalization (target numbers; validate in beta).

Editing requirements

  • Non-destructive edits stored as parameters + masks references
  • Global controls:
    • exposure, contrast, highlights/shadows, WB temp/tint
    • tone curve (basic)
    • HSL (basic)
    • grain (optional)
    • B&W mix (optional)
  • Style DNA lite:
    • Learn parameter distributions by lighting context (day/night/indoor)
    • Apply to new photos with confidence score
  • “Reference match” (V1.5):
    • provide 1–3 example outputs, match vibe

Acceptance criteria

  • Batch edit 200 photos and preview results in < 30 seconds after processing (assuming smart previews).

Search requirements

  • Search by:
    • text query → vector search
    • filters → metadata query
  • Return ranked results with:
    • best matches
    • “related” suggestions
  • Save search as Smart Collection.

Client gallery requirements

  • Share link with:
    • expiration settings
    • password
    • watermark toggle
  • Client actions:
    • favorite / star
    • comments pinned to photo
    • compare 2–4 images
  • Photographer actions:
    • export final set
    • lock selections
    • invoice + payment (or connect to Stripe)

Team/studio requirements (if included at launch, keep minimal)

  • Roles:
    • Owner, Admin, Editor, Shooter, Viewer
  • Permissions per project.

1.8 Non-functional requirements

Performance

  • Thumbnails show instantly as files arrive.
  • Culling UI must stay 60fps feel (no laggy scrolling).
  • Search results under 500ms for common queries.

Reliability

  • Ingest is resumable.
  • Edits are versioned; rollback is one click.
  • Never overwrite originals.

Security & privacy

  • Encryption at rest for stored originals and previews.
  • Access controls for client links.
  • Opt-in for biometric-like face clustering.
  • Opt-in for training on user content (default off).

Compliance (practical baseline)

  • GDPR/CCPA-ready data export + deletion.
  • Clear data retention policy.
  • CSAM detection/handling pipeline (must exist if hosting user uploads).

1.9 Metrics & analytics

North Star

  • Time-to-delivery (import → share gallery)

Core funnel

  • Import started → import completed
  • Cull started → cull completed
  • Edit started → edit completed
  • Gallery created → client opened → client selected → photographer delivered

Quality metrics

  • Cull:
    • % of AI top picks kept
    • number of “regrets” (user overrides)
  • Edit:
    • % of photos requiring manual tweak after AI
    • style consistency score (human eval)
  • Search:
    • time-to-find (from query to click)
    • search satisfaction (thumbs up/down)

Business metrics

  • Paid conversion
  • Storage usage
  • Gallery share rate
  • Payment conversion rate
  • Print store revenue (if enabled)

1.10 Rollout plan

  • Alpha: 20–50 photographers, heavy telemetry, weekly interviews
  • Beta: 500–2,000, introduce client galleries + payments
  • GA: studio roles + portfolio builder

1.11 Risks & mitigations

  • Bad culling suggestions kill trust → always show clusters + allow fast overrides; learn from picks.
  • Style feels “generic AI” → Style DNA from user edits; allow reference matching.
  • Privacy concerns → on-device face clustering; opt-in training; transparent controls.
  • Compute cost → smart previews; caching; only run heavy models when needed.

2) Data model + database schema (Postgres + pgvector)

2.1 Storage architecture

  • Originals (RAW/JPEG): Object storage (S3-compatible)
  • Thumbnails / previews: Object storage + CDN
  • DB: Postgres for metadata + permissions + billing
  • Vectors: pgvector (in Postgres) or dedicated vector DB (later)

2.2 Core entities (ERD-style)

  • users
  • studios (optional)
  • studio_members
  • projects
  • project_members
  • assets (photos)
  • asset_files (original + preview variants)
  • embeddings
  • perceptual_hashes
  • clusters (moments)
  • cluster_assets
  • ratings (pick/reject/stars)
  • edit_versions
  • edit_params (JSONB)
  • masks (optional V1.5)
  • exports
  • client_galleries
  • gallery_assets
  • gallery_activity (favorites/comments)
  • invoices / payments (Stripe integration)
  • audit_log
  • jobs (processing pipeline)

2.3 Suggested Postgres DDL (simplified, buildable)

— USERS

create table users (

  id uuid primary key,

  email text unique not null,

  display_name text not null,

  created_at timestamptz not null default now(),

  updated_at timestamptz not null default now()

);

— STUDIOS (OPTIONAL)

create table studios (

  id uuid primary key,

  name text not null,

  owner_user_id uuid not null references users(id),

  created_at timestamptz not null default now()

);

create table studio_members (

  studio_id uuid not null references studios(id),

  user_id uuid not null references users(id),

  role text not null check (role in (‘owner’,’admin’,’editor’,’shooter’,’viewer’)),

  created_at timestamptz not null default now(),

  primary key (studio_id, user_id)

);

— PROJECTS

create table projects (

  id uuid primary key,

  studio_id uuid references studios(id),

  owner_user_id uuid not null references users(id),

  title text not null,

  description text,

  shoot_date date,

  timezone text,

  status text not null default ‘active’ check (status in (‘active’,’archived’,’deleted’)),

  created_at timestamptz not null default now(),

  updated_at timestamptz not null default now()

);

create table project_members (

  project_id uuid not null references projects(id),

  user_id uuid not null references users(id),

  role text not null check (role in (‘owner’,’admin’,’editor’,’shooter’,’viewer’)),

  created_at timestamptz not null default now(),

  primary key (project_id, user_id)

);

— ASSETS (PHOTOS)

create table assets (

  id uuid primary key,

  project_id uuid not null references projects(id),

  captured_at timestamptz,

  ingested_at timestamptz not null default now(),

  camera_make text,

  camera_model text,

  lens_model text,

  focal_length_mm numeric,

  shutter_speed text,

  aperture numeric,

  iso integer,

  width_px integer,

  height_px integer,

  orientation integer,

  exif jsonb,        — raw exif dump

  iptc jsonb,        — keywords, copyright

  flags jsonb,       — { “has_face”: true, “is_duplicate”: false, … }

  created_at timestamptz not null default now()

);

— FILE VARIANTS

create table asset_files (

  id uuid primary key,

  asset_id uuid not null references assets(id) on delete cascade,

  kind text not null check (kind in (‘original’,’thumbnail’,’preview’,’export’)),

  storage_url text not null,

  content_type text,

  byte_size bigint,

  checksum_sha256 text,

  created_at timestamptz not null default now(),

  unique(asset_id, kind)

);

— DUPLICATE DETECTION

create table perceptual_hashes (

  asset_id uuid primary key references assets(id) on delete cascade,

  phash text not null,

  dhash text,

  created_at timestamptz not null default now()

);

— VECTORS (pgvector)

— Requires: create extension if not exists vector;

create table embeddings (

  asset_id uuid not null references assets(id) on delete cascade,

  model text not null,                 — “clip-vit-l-14” etc.

  dims integer not null,

  embedding vector(768) not null,       — adjust dims per model

  created_at timestamptz not null default now(),

  primary key (asset_id, model)

);

— For speed:

create index embeddings_ivfflat_idx on embeddings using ivfflat (embedding vector_cosine_ops);

— CLUSTERS (“MOMENTS”)

create table clusters (

  id uuid primary key,

  project_id uuid not null references projects(id) on delete cascade,

  kind text not null check (kind in (‘moment’,’burst’,’duplicate_group’)),

  start_time timestamptz,

  end_time timestamptz,

  title text,

  score numeric,                — overall cluster quality

  created_at timestamptz not null default now()

);

create table cluster_assets (

  cluster_id uuid not null references clusters(id) on delete cascade,

  asset_id uuid not null references assets(id) on delete cascade,

  rank integer,                 — within cluster order

  role text check (role in (‘candidate’,’winner’,’alt’)),

  primary key (cluster_id, asset_id)

);

— RATINGS / PICKS

create table ratings (

  id uuid primary key,

  asset_id uuid not null references assets(id) on delete cascade,

  user_id uuid not null references users(id),

  rating integer check (rating between 1 and 5),

  picked boolean,

  rejected boolean,

  starred boolean,

  notes text,

  created_at timestamptz not null default now(),

  unique(asset_id, user_id)

);

— EDIT VERSIONS

create table edit_versions (

  id uuid primary key,

  asset_id uuid not null references assets(id) on delete cascade,

  user_id uuid not null references users(id),

  parent_id uuid references edit_versions(id),

  name text,

  params jsonb not null,       — non-destructive params

  created_at timestamptz not null default now()

);

— EXPORTS

create table exports (

  id uuid primary key,

  project_id uuid not null references projects(id) on delete cascade,

  user_id uuid not null references users(id),

  preset text,                  — “instagram_carousel”, “full_res”

  settings jsonb,

  status text not null check (status in (‘queued’,’running’,’done’,’failed’)),

  created_at timestamptz not null default now()

);

— CLIENT GALLERIES

create table client_galleries (

  id uuid primary key,

  project_id uuid not null references projects(id) on delete cascade,

  created_by uuid not null references users(id),

  title text not null,

  share_slug text unique not null,

  password_hash text,

  expires_at timestamptz,

  watermark boolean not null default false,

  allow_downloads boolean not null default false,

  created_at timestamptz not null default now()

);

create table gallery_assets (

  gallery_id uuid not null references client_galleries(id) on delete cascade,

  asset_id uuid not null references assets(id) on delete cascade,

  sort_order integer,

  primary key (gallery_id, asset_id)

);

create table gallery_activity (

  id uuid primary key,

  gallery_id uuid not null references client_galleries(id) on delete cascade,

  asset_id uuid references assets(id) on delete cascade,

  actor_type text not null check (actor_type in (‘client’,’photographer’)),

  action text not null check (action in (‘favorite’,’unfavorite’,’comment’)),

  payload jsonb,

  created_at timestamptz not null default now()

);

— JOBS (PROCESSING PIPELINE)

create table jobs (

  id uuid primary key,

  project_id uuid references projects(id) on delete cascade,

  asset_id uuid references assets(id) on delete cascade,

  type text not null, — “generate_preview”, “embedding”, “cluster”, “denoise”, “export”

  status text not null check (status in (‘queued’,’running’,’done’,’failed’,’canceled’)),

  progress numeric,

  error text,

  created_at timestamptz not null default now(),

  updated_at timestamptz not null default now()

);

— AUDIT LOG

create table audit_log (

  id uuid primary key,

  user_id uuid references users(id),

  studio_id uuid references studios(id),

  project_id uuid references projects(id),

  action text not null,

  target jsonb,

  created_at timestamptz not null default now()

);

2.4 Index strategy (high impact)

  • assets(project_id, captured_at)
  • ratings(asset_id, user_id)
  • clusters(project_id, kind, start_time)
  • gallery_assets(gallery_id, sort_order)
  • jobs(status, type, created_at)
  • embeddings ivfflat index (cosine) + partition by model if needed

3) API map (REST-first, GraphQL optional later)

3.1 Principles

  • REST endpoints for core resources
  • Signed URLs for uploads/downloads
  • Webhooks/events for processing progress
  • Idempotency keys for ingest + billing

3.2 Auth

  • POST /auth/login (passwordless magic link or OAuth)
  • POST /auth/refresh
  • POST /auth/logout

3.3 Projects

  • GET /projects
  • POST /projects
  • GET /projects/{projectId}
  • PATCH /projects/{projectId}
  • POST /projects/{projectId}/archive

3.4 Ingest

Two-step upload (fast + scalable)

  1. Request upload URL
  • POST /projects/{projectId}/assets:prepareUpload

Request:

{

  “files”: [

    { “filename”: “DSC01234.ARW”, “byteSize”: 48293823, “contentType”: “image/x-sony-arw” }

  ]

}

Response:

{

  “uploads”: [

    {

      “clientFileId”: “local-1”,

      “assetId”: “uuid-asset”,

      “uploadUrl”: “https://signed-url…”,

      “headers”: { “Content-Type”: “image/x-sony-arw” }

    }

  ]

}

  1. Confirm upload complete
  • POST /projects/{projectId}/assets:finalizeUpload

Request:

{

  “assets”: [

    { “assetId”: “uuid-asset”, “checksumSha256”: “…” }

  ]

}

Response:

{ “queuedJobs”: [“uuid-job-preview”, “uuid-job-embed”, “uuid-job-cluster”] }

3.5 Assets

  • GET /projects/{projectId}/assets?cursor=…&limit=…
  • GET /assets/{assetId}
  • PATCH /assets/{assetId} (keywords, notes, flags)
  • GET /assets/{assetId}/files (thumbnail/preview/original links)
  • POST /assets/{assetId}/ratings (pick/reject/rate/star)
  • GET /assets/{assetId}/history (edits + actions)

3.6 Clusters (moments)

  • GET /projects/{projectId}/clusters?kind=moment
  • GET /clusters/{clusterId}
  • PATCH /clusters/{clusterId} (rename, reorder, override winner)
  • POST /clusters/{clusterId}/winner (set winner asset)

3.7 Culling actions

  • POST /projects/{projectId}/cull:applyAction

Request:

{

  “actions”: [

    { “assetId”: “uuid”, “picked”: true },

    { “assetId”: “uuid2”, “rejected”: true }

  ]

}

Response:

{ “ok”: true }

3.8 Edit versions

  • POST /assets/{assetId}/edits (create version)
  • GET /assets/{assetId}/edits
  • GET /edits/{editId}
  • POST /edits/{editId}/applyTo (batch apply to list)

Edit payload example:

{

  “name”: “Style DNA v1”,

  “params”: {

    “exposure”: 0.2,

    “contrast”: 12,

    “wbTemp”: 5400,

    “wbTint”: 6,

    “toneCurve”: [[0,0],[64,60],[128,132],[192,210],[255,255]],

    “hsl”: { “reds”: {“sat”: 4}, “blues”: {“lum”: -6} },

    “grain”: 8

  }

}

3.9 Search

  • GET /projects/{projectId}/search?q=neon%20rain&limit=50
  • POST /projects/{projectId}/search (advanced filters)

Advanced request:

{

  “q”: “street portrait night”,

  “filters”: {

    “ratingMin”: 4,

    “picked”: true,

    “cameraModel”: [“Leica M11”, “Sony A7IV”],

    “dateRange”: { “start”: “2025-01-01”, “end”: “2025-12-31” }

  }

}

3.10 Client galleries

  • POST /projects/{projectId}/galleries
  • GET /galleries/{galleryId}
  • POST /galleries/{galleryId}/assets (add selected assets)
  • GET /share/{shareSlug} (public view, password optional)
  • POST /share/{shareSlug}/favorite
  • POST /share/{shareSlug}/comment

3.11 Exports

  • POST /projects/{projectId}/exports
  • GET /exports/{exportId}
  • GET /exports/{exportId}/download

3.12 Jobs + realtime progress

  • GET /projects/{projectId}/jobs?status=running
  • SSE/WebSocket: /realtime channel project:{projectId}

Job event:

{

  “type”: “job.progress”,

  “jobId”: “uuid”,

  “assetId”: “uuid”,

  “jobType”: “embedding”,

  “progress”: 0.72,

  “status”: “running”

}

4) Wireframe-level screen specs (what to build, screen by screen)

Below are “wireframes in words”: layout, components, states, and keyboard flow.

4.1 Global layout

  • Top bar
    • Project switcher
    • Search bar (command palette style)
    • Processing indicator (jobs running)
    • User menu
  • Left rail
    • Projects
    • Library
    • Cull
    • Edit
    • Story (later)
    • Client
    • Exports
  • Main canvas
  • Right inspector panel
    • Metadata, ratings, edit versions, flags, cluster info
  • Bottom filmstrip (optional toggle)

Command palette (always available)

  • Shortcut: ⌘K / Ctrl+K
  • Commands:
    • “Find: …”
    • “Export: Instagram pack”
    • “Create gallery from picks”
    • “Apply Style DNA to selected”
    • “Show duplicates”

4.2 Screen: Projects

Purpose: start a workflow fast.

Components

  • Project cards with:
    • title, shoot date

    • assets
    • progress ring: ingest/cull/edit/deliver
  • CTA: “New Project”
  • Quick actions:
    • “Import”
    • “Open Cull”
    • “Create Gallery”

Empty state

  • “Import your first shoot. KILO will auto-build moments and best picks.”

4.3 Screen: Ingest

Purpose: frictionless import + immediate culling.

Components

  • Source picker:
    • SD card
    • folder
    • Lightroom catalog import (later)
  • File list with status:
    • queued / uploading / checksum / done
  • Processing pipeline status:
    • thumbnails
    • previews
    • embeddings
    • clustering

UX rules

  • Start showing thumbnails as soon as first 50 are ready.
  • “Go to Cull” button becomes active immediately.

Error states

  • corrupted file → “quarantine” list
  • upload interrupted → resume

4.4 Screen: Cull (the money screen)

Purpose: compress 3 hours into 20 minutes.

Layout

  • Left: Cluster Stack List
    • each item shows:
      • 1 representative thumbnail
      • size (# photos)
      • AI confidence badge
      • status: unreviewed / reviewed
  • Center: Stack Viewer
    • shows top candidate large
    • below: strip of candidates in cluster
  • Right: Inspector
    • focus score, blur, exposure warnings
    • “why this pick” bullets
    • actions: set winner, split cluster, merge with next

Keyboard

  • F: pick winner (marks cluster reviewed + advances)
  • D: reject current photo or entire cluster (toggle with Shift)
  • 1–5: rating
  • X: toggle reject
  • S: star
  • C: compare mode (winner + next best)
  • ←/→: previous/next photo in cluster
  • ↑/↓: previous/next cluster
  • Z: undo
  • Space: zoom (hold for 100%)

Compare mode

  • 2-up or 4-up grid
  • highlight differences: sharpness heatmap overlay (optional)

Edge actions

  • “Split moment” (if AI grouped too much)
  • “Merge with next”
  • “Mark as duplicate group”

States

  • “AI still processing” (clusters can re-rank; lock reviewed clusters)

4.5 Screen: Edit

Purpose: make your look consistent with minimal effort.

Layout

  • Left: selected set (picks, ratings, smart collections)
  • Center: image canvas
  • Right: edit panel (global first)
  • Top: “Style DNA” selector + “Apply to Selected”

Controls

  • Global:
    • exposure, contrast, highlights, shadows
    • white balance temp/tint
    • curve, HSL, grain
  • Batch:
    • “Sync from hero”
    • “Match lighting group”
  • Versions:
    • “Original”
    • “Style DNA v1”
    • “Manual tweak”
    • “Client delivery”

Smart suggestions

  • “Fix WB” (one click)
  • “Recover highlights” (one click)
  • “Straighten horizon” (one click)

Guardrails

  • Always show “Before / After” toggle (\ key)
  • Always non-destructive; revert safe

4.6 Screen: Search / Library

Purpose: retrieve anything instantly.

Layout

  • Search bar with chips:
    • “picked”
    • “rating ≥ 4”
    • “camera”
    • “date”
  • Results grid
  • Right inspector shows metadata + quick actions

Smart Collections

  • Save query → appears in left list
  • Example: “Best street portraits” auto-updates

4.7 Screen: Client Gallery Builder

Purpose: deliver like a luxury studio.

Steps

  1. Choose set:
    • Picks / rating ≥ N / selected manually
  2. Gallery options:
    • watermark (on/off)
    • downloads (on/off)
    • expiration
    • password
  3. Publish:
    • generates share link
  4. Monitor:
    • favorites count
    • comments
    • top selected

Client view

  • Clean grid
  • Favorite button
  • Compare mode
  • Download if allowed
  • Comments pinned to image

4.8 Screen: Exports

Purpose: create platform-ready files without thinking.

Presets

  • Full-res delivery
  • Web resized
  • Instagram carousel (4:5)
  • IG story (9:16)
  • Contact sheet PDF (later)

Export status

  • queued/running/done
  • download link + checksum

5) Model evaluation plan (how we prove the AI is actually good)

This is how you avoid “AI demo cool, real workflow trash.”

5.1 Tasks to evaluate

  1. Duplicate detection
  2. Clustering into moments
  3. Best-of-burst selection
  4. Personalized ranking (taste learning)
  5. Edit parameter prediction (Style DNA)
  6. Semantic search relevance
  7. Safety & privacy behaviors

5.2 Datasets

Internal beta dataset

  • 200–1,000 shoots (with consent)
  • Diverse:
    • events, portraits, street, travel
    • day/night/indoor
    • different cameras/lenses
  • For each shoot:
    • final delivered set
    • cull decisions (picks/rejects)
    • final edits (params)

Public/benchmark (optional support)

  • Use for generic tasks (blur detection, aesthetic scoring) but your real win is personalization on real workflows.

5.3 Labeling guidelines (human truth)

You need consistent labels.

Culling labels

For each burst/cluster:

  • “Best frame” (1)
  • “Acceptable alternates” (0–3)
  • “Rejects” (rest)

Reasons (multi-label):

  • blur
  • blink
  • bad expression
  • awkward gesture
  • background clutter
  • exposure fail
  • redundancy

Edit labels

  • Before + after parameter sets
  • Context tags: indoor tungsten / outdoor shade / neon night etc.

Search labels

  • Query → relevant results (top 20)
  • graded relevance (0–3)

5.4 Offline metrics (per task)

Duplicate detection

  • Precision/Recall/F1 on duplicate pairs
  • “False duplicate penalty” (high severity, kills trust)

Clustering

  • Cluster purity (how often a cluster contains one “moment”)
  • Over-segmentation rate (too many clusters)
  • Under-segmentation rate (mixed moments)

Burst winner selection

  • Top-1 accuracy vs human “best frame”
  • Top-3 hit rate (winner is in top 3)

Personalized ranking

  • NDCG@K (ranking quality)
  • Improvement after feedback:
    • NDCG@20 before vs after 20 picks
  • Regret rate:
    • user picks outside top N suggestions

Edit prediction (Style DNA)

  • Parameter error (MAE) per control (exposure, WB, etc.)
  • Perceptual similarity:
    • ΔE (color difference)
    • LPIPS (perceptual distance) on previews (optional)
  • Human eval:
    • “Looks like photographer” (1–5)
    • “Would deliver as-is” (yes/no)

Search

  • Precision@10
  • MRR (first relevant result rank)
  • Query latency (p50/p95)

5.5 Online metrics (A/B tests)

  • Time-to-cull completion
  • % clusters needing manual split/merge
  • Override rate of AI winner
  • Export time-to-first-delivery
  • User satisfaction micro-prompt:
    • “Did KILO pick the right winner?” thumbs up/down

5.6 Safety & privacy evaluation

  • Face clustering is off by default → test that it never runs unintentionally
  • “No training by default” → test data governance gates
  • Client links:
    • brute force resistance (long slugs, rate limits)
    • password gating

If you ever add generative tools later:

  • Strict policy checks (consent, identity misuse, etc.)
  • Audit logging for any synthetic edits

5.7 Model governance & MLOps

  • Model registry with versioning:
    • embedding model version
    • cull ranker version
    • style DNA version
  • Backtesting:
    • run new model on past shoots and compare metrics
  • Rollout:
    • 5% → 25% → 100%
  • Kill switch:
    • revert model quickly if regression

6) “Style DNA” system design (how it actually works)

6.1 Style DNA Lite (V1, high ROI)

Inputs

  • User’s edits (params) across many photos
  • Context features:
    • lighting type (estimated)
    • ISO/noise level
    • indoor/outdoor
    • time of day
    • camera profile

Model

  • Predict edit params from image features + context
  • Or learn parameter distributions per context bucket

Output

  • A recommended edit preset + confidence score
  • If confidence low → apply only objective fixes + ask user to pick a reference edit

How it learns

  • Each time user tweaks after AI, log delta → update style profile

6.2 Reference Match (V1.5, “this is magic”)

  • User selects 1 hero image with final grade
  • Apply “match” across selected set
  • Under the hood:
    • match tone curve + WB bias + saturation curve
    • avoid crushing highlights/skin tone overfitting

7) Event-driven processing pipeline (jobs that make it feel instant)

7.1 Job types

  • generate_thumbnail
  • generate_preview
  • extract_exif
  • compute_phash
  • compute_embedding
  • cluster_project
  • rank_cluster_candidates
  • detect_faces (opt-in)
  • export_project

7.2 Pipeline strategy

  • Ingest triggers minimal jobs first:
    1. thumbnail
    2. preview
    3. exif
  • Then:
    4) embedding
    5) clustering + ranking
  • UI never blocks; it just upgrades from “basic” to “smart” progressively.

8) Naming + branding system (goes hard, stays premium)

You can keep KILO, but here are options with a consistent vibe:

8.1 Product name candidates

Brutal + minimal

  • KILO
  • ANVIL
  • FORGE
  • GRAIN
  • TANK
  • DRIVE
  • CUT

Premium + editorial

  • LUMEN
  • ARCHIVE
  • NEGATIVE
  • CONTACT
  • FRAME
  • STUDIO

AI-native feel (without cringe)

  • MOMENT
  • PICK
  • SEQUENCE
  • SIGNATURE

My top 3 for this product:

  • KILO (strength + workflow power)
  • FORGE (craft + style)
  • CONTACT (photography-native, timeless)

8.2 Taglines

  • “From shoot to story — fast.”
  • “Cull harder. Deliver sooner.”
  • “Your style, automatic.”
  • “Find anything. Ship everything.”
  • “The photographer’s operating system.”

8.3 Brand voice

  • Short sentences.
  • Confident, not corporate.
  • Always creator-first.
  • Never says “AI” unless needed — it just works.

Examples of UI copy:

  • Import screen: “Drop files. We’ll build the moments.”
  • Cull screen: “Winner suggested. Your call.”
  • Edit screen: “Make it yours.”
  • Gallery: “Favorites collected. Ready to deliver.”

8.4 Feature naming (consistent system)

  • Moments = clusters
  • Stacks = burst groups inside moments
  • Savage Cull = culling mode
  • Style DNA = personalization
  • Reference Match = match hero grade
  • Story Pack = social/blog outputs
  • Vault = archive

8.5 Visual identity direction (high-level)

  • Typography: modern grotesk + mono accent
  • UI: black/charcoal base (photo-first), minimal chrome
  • Motion: snappy transitions in Cull (feels like cutting film)

9) Build plan (90-day reality check)

Sprint 1–2 (foundation)

  • Auth, projects, ingest pipeline, thumbnails/previews
  • Assets DB + object storage
  • Basic grid viewer

Sprint 3–4 (Cull MVP)

  • Clustering (time + similarity)
  • Ranker v0 (sharpness + blur + redundancy)
  • Keyboard-first culling UI
  • Ratings store

Sprint 5–6 (Search + Style DNA lite)

  • Embeddings + vector search
  • Style profile from edits/presets
  • Batch apply + versions

Sprint 7–8 (Client gallery MVP)

  • Gallery creation + share links
  • Favorites + comments
  • Delivery exports

Sprint 9–10 (polish + performance)

  • caching + progressive processing
  • explainability + trust UI
  • analytics + A/B hooks

10) What I’d ship first (if we want maximum domination)

If you only perfect three things, it’s these:

  1. Cull (stacks + winner + instant keys)
  2. Style DNA (your look in one click)
  3. Client delivery (proof → selects → pay)

Everything else is bonus.

If you want, I can also turn this into actual implementation artifacts next:

  • a complete OpenAPI spec (YAML) for all endpoints
  • Figma-ready wireframe checklist (components + states)
  • a concrete model card template for each model (inputs/outputs/risks)
  • a sample “Style DNA” training loop pseudocode (privacy-safe)