# The MyBazaar companion — canonical prompt template

**Status:** approved character, 8 Sep 2026. Any work that generates, extends or edits the
companion MUST start from this file. Do not re-derive the character from an older sheet or
from memory — reference the image below and paste the blocks below verbatim.

## Reference images (in priority order)

| Path | What it is | Use |
|---|---|---|
| `~/generated-images/character-moodboard/ai/sheet1.png` | Greeting sheet — the cleanest four poses | **Canonical.** Reference this for all new work. |
| `~/generated-images/character-moodboard/03-companion.png` | The original approved three-pose sketch | Historical origin only. |
| `~/generated-images/character-moodboard/ai/sheet{2..5}.png` | Working, feelings, product states, brand | Pose inventory; each carries some drift. |

> Referencing every sheet back to the *original* sketch is what caused the proportion and
> belly-patch drift across the set. New sheets should reference **sheet1**, not `03-companion`.

## Character block — paste verbatim

```
The character (match the reference image exactly): a small friendly non-human companion
creature. A rounded teal pebble-shaped body in deep teal #01796F, with a soft pale mint belly
patch low on the front, two small black dot eyes, a small simple curved smile, and two short
stubby rounded arms. It has NO legs and NO feet — it floats slightly above a soft pale
elliptical shadow on the ground.
```

## Style block — paste verbatim

```
Style: flat vector illustration. Clean uniform dark outline #113833 around the body and arms,
consistent weight. Flat solid fills only — absolutely no gradients, no shading, no texture,
no highlights, no 3D. Even ambient light.

Palette, exactly these colours and no others:
  deep teal #01796F (the body)
  pale mint #EAF6F3 (belly patch, flat background)
  pale teal #D7ECE8 (soft shadow)
  near-black green #113833 (all outlines, eyes, mouth)
  magenta #C42B60 (one tiny accent only, if any)
  warm yellow #F0C64B (one tiny accent only, if any)

Every character in the image must be IDENTICAL in size, proportion, body shape, outline weight
and colour. Only the pose, the arms, the facial expression and the prop may differ.

NO brown, tan, kraft, beige or any colour outside the six above — this includes paper bags,
flags, wood and cardboard, which must be teal or pale mint, never kraft brown.
The character has NO legs and NO feet in any pose, including sitting, jumping and walking.
No tongue. No nose. No ears.

No legible text, no numbers, no letters, no logos, no signage anywhere in the image. Any card,
box, screen or sign in the image must be completely blank.
```

The last two paragraphs exist because each one is a defect that actually shipped — see
**Known drift** below. Do not trim them.

## Sheet prompt shape

Four poses per image. The model holds the character consistent *within* one image far better
than across separate calls, so never generate poses one at a time.

```
A character model sheet: the SAME companion creature shown four times in one horizontal row,
on one flat pale mint background. Leave a clear empty vertical gap between each character —
no character, arm, shadow or prop may touch or overlap its neighbour.
Left to right: (1) …; (2) …; (3) …; (4) …
```

The spacing sentence matters for a practical reason: sheets get split into individual pose
files afterwards, and two poses that touch cannot be separated by any cut. On `sheet2` the
trolley and the stack overlap by ~35px, so those two tiles can only be cut at a compromise
point. Ask for the gap up front and the split is lossless.

## Hard rules (brand, not style)

1. **Never on a money surface** — checkout, payouts, settlement, invoices, GST. Learning and
   idle surfaces only: onboarding, empty states, errors, 404, loading, marketing, packaging.
2. **Never captioned as a merchant**, and never speaks in first person. It is a companion, not
   a person.
3. **Never a wedge hero.** Those belong to the illustrated human cast, one per segment.
4. **Invents no text, prices, names or counts** — every prop stays blank.
5. Label and log every generated asset as AI-generated (doc 07 production checklist, item 7).

## Known drift — check every new sheet against this list

| Defect | Where it happened | Guard |
|---|---|---|
| Kraft brown props | sheet5 — flag and paper bag | Explicit no-brown line in the style block |
| Legs and feet appeared | sheet4 — poses 2, 3 and 4 | Explicit no-legs line, repeated |
| Magenta tongue | sheet5 pose 4 | "No tongue" in the style block |
| Belly patch teardrop ↔ egg | across sheets | Reference sheet1, not the original sketch |
| Proportion wobble | sheet2 vs sheet1 | Same — one canonical frame |
| Stray dot near the face | sheet2 pose 2 | Visual QA before accepting |

## Generation mechanics

- Run via `agy -p … --dangerously-skip-permissions --print-timeout 12m` from a scratch dir.
- The image model is `gemini-3.1-flash-image`. **Quota is small** — roughly 1–4 images per
  window, windows reset on a ~5 hour cycle. Batch scripts must parse the reset timestamp out of
  the error (`at YYYY-MM-DDTHH:MM:SSZ`) and sleep until then rather than retrying blindly.
- **The model will claim to have saved a file it never generated.** Always verify the PNG
  exists and is non-empty before reporting success, and re-run if not.
- Never let a batch script `pkill -f` a pattern that also matches its own command line — it
  kills the launcher. Kill by PID, or use a distinct script filename.

## Splitting sheets into individual poses

`scripts/split-poses.cjs` cuts a 4-pose sheet into four files. Two things it has to do that
are not obvious:

- **Measure ink against each column's own background**, not a corner pixel — the sheets carry a
  subtle vignette, and a single reference reads that gradient as content, hiding the real gaps.
- **Find cuts in the character band only** (top 80%). The drop shadows merge between poses, so a
  full-height profile shows no gap even where one plainly exists.

Cleanup after cutting must be conservative: erase only edge-touching components under ~7% of
tile width *and* under ~1400px. An earlier, looser rule deleted the trolley's wheel as if it
were a neighbour's sliver.

## The pose pipeline, end to end

Sheets are the source of truth; everything below them is regenerable and should not be kept.

```
ai/sheetN.png                 generated 4-pose sheets  (KEEP — the source)
  |  scripts/split-poses.cjs   cut into 4, common baseline, overlapping windows
  v
poses/                        intermediate — delete after use
  |  remove-background.mjs (this skill) --tolerance 22 --feather   (NO --holes)
  v
poses-cut/                    intermediate — delete after use
  |  scripts/refine-edges.cjs  halo strip + alpha ramp + neighbour recolour
  |  scripts/convert-shadow.cjs  shadow -> translucent ink + fringe sweep
  v
poses-crisp/                  FINAL — this is what ships
```

Three settings that are load-bearing, each learned the hard way:

- **`--tolerance 22`, never the default 40.** The shadow sits only ~73 from the background
  while the halo sits ~62 — they are nearly the same tone, so the cut cannot separate them by
  colour. Halo removal is structural instead (see below).
- **Never `--holes`.** The belly patch is the *same* pale mint as the background and survives
  only because the body's outline encloses it. The hole pass punches straight through it.
- **Fringe threshold is 120 luminance**, derived from the artwork — the outline measures < 110
  and the teal body ~85, so anything brighter on the boundary is a blend with the ground. Do
  not raise it to "just above what you can see"; that is how it was wrong at 190, then 150.

Two more traps: no median/blur/sharpen filter anywhere (a `median(3)` visibly thickens the
outline at this size), and export lossless — a quality-96 WebP reintroduces ~40 fringe pixels.

## Output locations

- Sheets: `~/generated-images/character-moodboard/ai/`
- Individual poses: `~/generated-images/character-moodboard/poses/`
- Boards: `character-board.html`, `prop-library.html` in the same tree; the gallery serves them
  at `https://images.oracle.makemybazar.com/character-moodboard/`.
- **The gallery is public and unauthenticated.** Nothing sensitive goes in these folders.

`split-poses.cjs`, `refine-edges.cjs`, `convert-shadow.cjs` and `undraw-recolor.mjs` live with
the output, in `~/generated-images/character-moodboard/scripts/` — they are moodboard tooling,
not product code, and deliberately stay out of the repo. Only `remove-background.mjs` (in this
skill) is general enough to be versioned.

They take their directories from argv, with the paths above as defaults, and must be run from a
workspace package that declares `sharp` — `projects/mybazaar-web` — as
`yarn node < <path>/<name>.cjs`. Yarn PnP cannot resolve `sharp` for a file outside the
workspace, which is why they are piped in on stdin rather than passed as a path.

Because they sit outside version control, treat this document as the durable record: the
settings below are the part worth keeping, and the scripts can be rebuilt from them.

## Related

- Props: 42 Tabler icons (MIT), six per wedge — see `prop-library.html`. They ship in
  `currentColor`, so no recolouring step is needed.
- Wedges come from `projects/mybazaar-web/src/configs/segments.ts` — **seven**, not the eight
  still listed in `strategies/brand-strategy/07-imagery-direction.md`.
