Monorepo for Aesthetic.Computer aesthetic.computer
README.md

Jeffrey Platter #

An index of canonical photographic references for Jeffrey Alan Scudder — face, body, hands — across the repo, the assets CDN, the vault, and the social silos. A sub-platter within the papers platter, parallel to whistlegraph-platter and to jeffrey-lexicon (the textual analogue — a frequency-attributed dictionary of jeffrey's first-hand vocabulary; live dashboard at papers.aesthetic.computer/platter/jeffrey-lexicon/).

The platter exists so that any pipeline (CV layout, image generation, press kit, lecture slide, video composite) can resolve "a photograph of jeffrey" to a concrete URL or file path with known POIs, focal points, and provenance — instead of reaching for whatever's nearby.

This is index-only: pointers to where canonical images live. Masters live on the assets CDN and in the vault. No binary duplication into papers/.

Picture-making history — drawings.rey.sc #

The platter now includes a public visual history of 3,996 drawings completed from September 2006 through August 2016, recovered from Jeffrey's still-running Ruby on Rails catalog at drawings-rey-sc.jas.life. The source archive describes itself as “a living archive of images” and was established March 17, 2015. It organizes the work into 102 named groups, 24 locations, and 19 collaborator records.

The completion month/year comes from the archive's own chronological headings, not from the derivative-image upload timestamp. That distinction matters because much of the older work was batch-ingested into Rails in 2015. Refresh with:

node papers/jeffrey-platter/import-drawings.mjs

1. In this repo #

Pieces (capture surfaces) #

These are the AC pieces that produce new photographic frames of jeffrey when he uses them:

POI manifest (single source of truth) #

  • manifest.json — POI manifest for both CDN buckets (8 headshots + 38 candids). Each item carries focal: [x%, y%], pois: [{t: f|b|h, box}], and aspect. POIs originally detected via OpenCV DNN + Haar cascades.
  • sync.mjs — copies manifest.json to consumer-served paths. Run after editing the manifest. Currently writes one target: system/public/give.aesthetic.computer/jeffreys-manifest.json.

Consumers (where canonical jeffrey-images are already used) #

  • system/public/justanothersystem.org/cv.html — bio portrait slideshow with Ken Burns; pulls jeffery-av--07/06/10.jpg from the shoot/ bucket. OG/Twitter card image is jeffery-av--07.jpg. Hardcoded URLs; doesn't read the manifest yet (TBD).
  • system/public/give.aesthetic.computer/index.html — full Jeffreys Ken Burns canvas slideshow. Fetches ./jeffreys-manifest.json at runtime via loadJeffreysManifest() and merges into the slideshow's image index (buildImageIndex()). Originally inlined the same data as JS object literals; lifted to JSON 2026-04-28.
  • recap/ — recap pipeline uses the jeffrey-pvc Professional Voice Clone via /api/say. Audio analogue of canonical-jeffrey: not visual but lives in the same canonical-self category. See recap/SCORE.md.

Adjacent textual / video material #


2. External (assets CDN + sites) #

Hosted dashboard — papers.aesthetic.computer/platter/jeffrey/ #

Public sortable/filterable gallery of the 457 confirmed-jeffrey IG selfies from @whistlegraph (face-matched against the AV shoot, described per-image by GPT-4o). Lives under the new /platter/ namespace alongside future per-platter dashboards:

Page is public — the source images were already public on instagram.com/whistlegraph/, and the GPT-4o descriptive layer is treated as part of the public AC research record.

assets.aesthetic.computer/jeffreys/ #

Hosted on Digital Ocean Spaces. Sync via npm run assets:sync:down / npm run assets:sync:up (see CLAUDE.md).

jeffreys/shoot/ — Professional AV photoshoot (face-focused headshots) #

55 headshots named jeffery-av--01.jpg through jeffery-av--55.jpg, uploaded 2026-01-05. Bucket audited 2026-04-28 via aws s3 ls; all 55 are present and cataloged in manifest.json under buckets.shoot.items.

Resolution tiers (sizes vary 10x within the sequence — uploads were sized for different consumers):

Tier Range Size Use
master --01..--10 20–26 MB Training crops, print, archival
mid --11..--35 1.7–5.3 MB Slideshows, web reference
web --36..--55 220–340 KB Thumbnails / smallest backgrounds

Per-tier annotation lives in each item's tier and size fields. All headshots share uniform POI framing: aspect: 0.667, focal: [50, 35], pois: [{t:"f", box:[30,15,40,40]}] — face-centered portrait. The framing is a placeholder; a re-run of OpenCV face detection on master-tier frames would yield true bounding boxes.

Note the spelling: filenames use jeffery- (one r), not jeffrey-.

Currently consumed:

  • give.aesthetic.computer Ken Burns slideshow — re-enabled 2026-04-28; merges all 55 into allImagesData (was previously commented out — only 8 cataloged then)
  • justanothersystem.org cv.html — hardcoded URLs for --06/07/10 (OG card uses --07)

jeffreys/<NAME>.{heic,HEIC,jpeg,JPEG} — iPhone master files #

38 masters sit at the top of the jeffreys/ prefix (not in a subdirectory), 1:1 with jpg/ candids. These are the iPhone-original HEIC/JPEG files — the JPGs in candids/ are derivatives. Cataloged in manifest.json under buckets.masters.items with candid_key cross-references and per-file size.

Use this bucket for training crops — masters carry roughly 2× the byte-budget of their JPG derivatives and preserve color depth that JPEG re-encoding lossily compresses. Don't surface masters in slideshows (HEIC has spotty browser support); use the candids/ JPGs for those.

Mixed extensions in the bucket: 32 are heic/HEIC, 6 are jpeg/JPEG. Manifest keys preserve the actual extension on the CDN.

jeffreys/jpg/ — Candids (JPG derivatives of the masters) #

38 enumerated candids (IMG_NNNN.jpg + FullSizeRender) with hand-tuned focal points and POI bounding boxes. Full data lives in manifest.json under buckets.candids.items. Includes:

FullSizeRender, IMG_0260, IMG_0675, IMG_0686, IMG_0688, IMG_0798, IMG_1111, IMG_1577, IMG_1616, IMG_1737, IMG_1809, IMG_2124, IMG_2208, IMG_2280, IMG_2498, IMG_2630, IMG_2658, IMG_2668, IMG_2905, IMG_2913, IMG_3017, IMG_3234, IMG_4281, IMG_4312, IMG_4606, IMG_4894, IMG_4997, IMG_5043, IMG_5050, IMG_5272, IMG_5644, IMG_6342, IMG_6367, IMG_6435, IMG_8080, IMG_8188, IMG_8989, IMG_9795.

Bucket audited 2026-04-28 — exactly 38 entries, manifest is complete, no orphans, no uncataloged files. Each candid has a master field pointing at its HEIC/JPEG counterpart in jeffreys/; prefer the master for training, use the JPG for slideshows and embeds.

POI types: f = face, b = body, h = hand. Aspects vary (0.562 / 0.563 / 0.667 / 0.75 / 0.8 / 1.333). IMG_2124 and IMG_2658 are referenced by name in give.aesthetic.computer/index.html as the splash/background plates.

TBD: locate the script that generated the existing focal/POI values (OpenCV DNN + Haar cascades, per the give-page comment) and check it in to portraits/jeffrey/bin/. The manifest carries the output of that pipeline; the pipeline itself isn't in the repo yet.

screenshots/images/ — First-person POV "selfies" (90 environmental webp captures) #

90 webp screenshots of jeffrey's working environment — laptop screens, hands on the keyboard, desk surfaces, ambient development moments. Captured live while making AC. Treated as canonical first-person POV reference imagery for any pipeline that wants a POV-from-jeffrey look (vs the third-person headshots in shoot/). Mostly portrait orientation (aspect: 0.75), each item has a focal coordinate and pois boxes (t: "s" = scene region).

URL pattern: https://assets.aesthetic.computer/screenshots/images/<name>.webp. Cataloged in manifest.json under buckets.screenshots.items (imported from give.aesthetic.computer/index.html 2026-05-02). Currently consumed by the give Ken Burns slideshow (merged into allImagesData) and available to image-gen pipelines via --refs.

jeffreys/gens/ — Generated images (gpt-image-2 + platter-grounded identity) #

Output bucket for any pipeline that synthesizes a new jeffrey-image conditioned on the platter refs (typically SHOOT_REFS + SELFIE_REFS from portraits/jeffrey/bin/generate-neo.py). One PNG per successful gen, dated, never overwritten.

Filename convention: <context>-<segment>-<YYYY-MM-DDTHHMM>.png — e.g. recap-jeffrey-24h-02_menuband-2026-04-29T1630.png. context says where the gen came from (e.g. recap-jeffrey-24h); segment is whatever locally-meaningful subdivision the producer cares about; the timestamp keeps regens distinct so we never lose a previous take.

Producers:

Manifest entry shape (under buckets.gens.items[<filename>]):

{
  "model": "gpt-image-2",
  "size": "1024x1536",
  "quality": "high",
  "refs": ["portraits/jeffrey/corpus/shoot/jeffery-av--07.jpg", "..."],
  "context": "recap-jeffrey-24h",
  "segment": "02_menuband",
  "generated": "2026-04-29T16:30:00.000Z",
  "bytes": 2520266,
  "prompt": "<full gpt-image-2 prompt — preserved for provenance>"
}

The full prompt is kept inline so a year from now we can answer "what was the metaphor that produced this take?" without cross-referencing the source audience config (which has likely drifted by then).

Push to CDN: npm run assets:sync:up after a batch of gens. The bucket is under the standard system/public/assets/* gitignore — git tracks the manifest entry, not the PNG bytes.

Social silos (canonical public faces) #

Institutional pages carrying jeffrey portraits #


3. Local bulk archive (gitignored) #

Bulk image data lives at portraits/jeffrey/ under gitignored subdirectories — these aren't secrets (vault is for SECRET_FILES only), just bulky regenerable cache:

  • portraits/jeffrey/ig-archive/<account>/ — Instagram bulk dumps. As of 2026-04-29: whistlegraph/ ≈ 4.27 GB, 4,575 posts spanning 2014-08-23 → 2026-04-28. Pulled via portraits/jeffrey/bin/ig-archive.fish. Per-post JSON metadata is xz-compressed alongside each image. The 4,575 entries are a mix of grid posts and stories — the partition is exposed via the meta catalog (next item).
  • portraits/jeffrey/curated/ — outputs of the face-match → vision-describe → meta-extract pipeline.
    • jeffrey-match.jsonl — insightface identity scores per image (491 of 4,575 posts confirmed-jeffrey at default threshold).
    • jeffrey-described.jsonl — GPT-4o scene-graph metadata.
    • whistlegraph-meta.jsonl — flat catalog (one row per shortcode) with typename, caption, likes, comments, taken_at, is_video. Built by bin/ig-meta-extract.mjs. Type partition (2026-05-08 build): GraphImage 2,049 + GraphSidecar 367 + GraphVideo 345 = 2,761 grid posts; GraphStoryImage 1,677 + GraphStoryVideo 101 = 1,778 stories. Caption coverage: 47% of posts; stories carry no caption field.
    • thumbnails/ (384px), index.html (static browser).
  • portraits/jeffrey/social/<account>/ — the social-graph / art-world map layer (followers+following → typed graph + graph.svg data image foregrounding galleries/museums/institutions and the people who run them). Built by the bin/ig-social-* scripts; see portraits/jeffrey/README.md → "Social graph / art-world map". Authenticated personal social data — gitignored like ig-archive/.
  • TBD: portraits/jeffrey/selfies/ — selfie corpus (raw output from selfie.mjs/snap.mjs/cap.mjs runs); promote the keepers to assets/jeffreys/jpg/ after curation.
  • TBD: portraits/jeffrey/press/ — press headshots and high-res stills sent to institutions.
  • TBD: portraits/jeffrey/shoot-raw/ — uncompressed masters from the AV photoshoot (only web-sized JPGs are on the CDN today).

The only jeffrey-related thing that lives in the vault is the instaloader session cookie at aesthetic-computer-vault/silo/instaloader-sessions/whistlegraph — that one IS a credential (authenticated IG session) and stays vault-side.


4. Instagram archive ingestion (currently BLOCKED) #

The silo Instagram bridge is the path to bulk-importing jeffrey's solo + AC photo archives into the platter.

  • Bridge code: silo/server.mjs on the silo VPS, port 3003
  • Migration report: reports/instagram-api-migration-2026-03-29.md
  • Status (2026-03-29): login rejected on instagram-private-api, @i7m/instagram-cli, and subzeroid/instagrapi-rest. Errors range from IgLoginBadPasswordError to "IP added to the blacklist". Migration to instagrapi 2.3.0 (Python, actively maintained) sketched but not landed.
  • Block resolution path: bypassed 2026-04-29 — instaloader cookie-import (Chrome) succeeded; bulk archive of @whistlegraph (4.1 GB, 6,104 frames, 2014–2026) lives at portraits/jeffrey/ig-archive/whistlegraph/. Silo bridge migration is independent and still pending — only needed if the silo dashboard needs live IG profile/feed queries.

When ingestion comes online, image filenames should map IG shortcodes to date-prefixed names (YYYY-MM-DD-<shortcode>.jpg) so timeline queries are easy. POI re-detection is a separate post-ingest pass.


5. For canonical image generation (the goal) #

The motivating use case for this platter is to feed image-generation pipelines a stable, well-annotated reference set of jeffrey so generated portraits stay on-model.

Pipeline location: portraits/jeffrey/ at the monorepo root. It consumes manifest.json and the CDN buckets; it is the agreed home for training scripts, LoRA artifacts, IP-Adapter ref sets, and any sample outputs.

Currently in place

  • A two-bucket archive (shoot/ headshots + jpg/ candids) hosted on the CDN
  • Per-image POI metadata (face/body/hand bounding boxes + focal point + aspect) for 46 images in manifest.json. Lifted out of give.aesthetic.computer/index.html 2026-04-28.
  • Voice analogue (jeffrey-pvc PVC) already wired into /api/say — establishes the pattern of canonical-self assets being callable as a service

Gaps to close

  • TBD: agree on what "canonical" means for generation:
    • Face LoRA / DreamBooth training corpus — needs ≥20 high-quality face crops with diverse lighting/angles. The 8 shoot/ headshots are too uniform on their own (all focal: [50, 35]); needs candids mixed in.
    • IP-Adapter / FaceID reference set — needs a smaller curated set of 5–10 very clean references.
    • Identity-preserving prompt suffix — needs a stable text description of jeffrey's appearance, derived from photos. Adjacent to but distinct from voice clone metadata.
  • TBD: licensing & consent rails — even though jeffrey is the subject and operator, downstream pipelines that publish generated portraits should have an explicit allowlist of where they're allowed to render him.

Adjacent infrastructure to study

  • arxiv-penrose/ — Penrose pipeline for AC illustrations. Not for portraits, but the "diagrams from data" pattern (declarative spec → rendered image) is a useful analogue.
  • recap/bin/scout.mjs — content-query resolver. Could be extended with a { jeffrey: "shoot" | "candid" | "any", count: N } query that returns N canonical jeffrey URLs for use in slide compositions.

6. Curation: shows + contact sheets #

A "show" is a small JSON file describing a curated subset of the @whistlegraph IG archive — the input that drives both visual review (contact sheets on the desktop) and, eventually, the IG-side onlyMe / undoOnlyMe archive/unarchive flow that turns the public grid into a rotating exhibition wall.

  • Show definitions: portraits/jeffrey/shows/<slug>.json — selectors (AND'd) + manual_include / manual_exclude lists + optional order. Selector vocabulary: face_match, face_excludes, date_range, recent_count, recent_days, media_kind (post / story), top_n_by (likes / comments).
  • Resolver: portraits/jeffrey/bin/show-resolve.mjs — node bin/show-resolve.mjs <slug> [--with-media-ids]. Joins whistlegraph-index.json + whistlegraph-meta.jsonl + jeffrey-match.jsonl and emits the resolved post list as JSON. --with-media-ids lazily reads each .json.xz for the numeric node.id that instagram-private-api's media.onlyMe(mediaId) expects.
  • Meta catalog: portraits/jeffrey/bin/ig-meta-extract.mjs — one-time scan of the .json.xz files; produces curated/whistlegraph-meta.jsonl.
  • Contact sheet renderer: portraits/jeffrey/bin/show-contact-sheet.py — bin/show-contact-sheet.py <slug> [--max=N]. Tiles 200px square thumbs in a 22-column grid with a per-tile caption strip (date + likes + comments + caption text wrapped to 2 lines). Outputs to ~/Desktop/whistlegraph-shows/<slug>-N.jpg (gitignored — desktop scratch).
  • Built-in shows (auto-generated): posts-YYYY (2014–2024), stories-YYYY (2017–2026), most-liked-100, most-commented-100, plus jeffrey-only, no-jeffrey, era-2014, recent-30 as exemplars.

The IG-side projector (silo admin endpoints that diff a resolved show against the live grid + archived list, then issue throttled onlyMe / undoOnlyMe calls) is the natural next layer — it is not yet in silo/server.mjs, just sketched here so the curation chain has somewhere to land.


7. Timeline (rough spine) #

  • 2026-01-03 to 2026-01-05 — candids and HEIC masters uploaded to jeffreys/ and jeffreys/jpg/ (38 files each); AV shoot uploaded to jeffreys/shoot/ (55 frames) on 2026-01-05
  • 2026-01–04 — POI manifest authored by hand inside give.aesthetic.computer/index.html; consumed by cv.html (justanothersystem.org) and the Ken Burns slideshow
  • 2026-03-29 — silo IG migration attempted, blocked at login layer (report)
  • 2026-04-28 — platter index created; POI manifest lifted from give.aesthetic.computer/index.html to standalone manifest.json; give-page now fetches the synced copy at runtime; bucket audit added masters/ bucket and tier/size/master annotations; headshots merge re-enabled in give-page; portraits/jeffrey/ scaffolded; silo instagrapi.service staged
  • TBD: candid corpus origin — IMG_NNNN.jpg filenames are iPhone-default; the masters carry EXIF dates that should be parsed and added to the manifest as taken_at

How to extend this index #

  1. When new material appears (a new shoot, a new selfie session keeper, a press photo placement, an ingested IG batch) — add a line under the matching section with a link or asset path.
  2. Use TBD: prefix for known-missing items so they're greppable.
  3. Don't check binaries into papers/. Masters live on the CDN or in the vault; this file points at them.
  4. When the POI manifest gets extracted from give.aesthetic.computer/index.html into a standalone JSON, link it here and update §2 to reflect the new source of truth.
  5. If a sibling manifest.json or pois/ directory grows, note it in §1 (consumers) so other pipelines can find it.