Kicon RFC 002 design generation pipeline

RFC-002 — Design Generation Pipeline

*uthor:*Koder Engineering *ate:*20260429 *tatus:*Accepted *odule:*productsdevkicon *elated:*kiconRFC001 (variant generation), hubRFC006 (Hub icon trigger), policies/sdk-first.kmd


Table of Contents

  1. Summary
  2. Problem Statement
  3. Goals
  4. Non-Goals
  5. Background
  6. Design
  7. Scope of Change
  8. Execution Plan
  9. Dependencies
  10. Alternatives Considered
  11. References

1. Summary

Promote kicon from a buildtime *ariant generator*(one master SVG → N platformcorrect outputs, scope of RFC001) to a full *esign pipeline* master generation, candidate batch production across multiple backends, raster→vector conversion, interactive selection. The first real driver is the Koder Hub icon (hubRFC-006 §6.4); every Koder product downstream benefits from the same workflow when it needs a fresh icon.

2. Problem Statement

Today every Koder product that needs an icon goes through an ad-hoc external workflow: someone opens an image generation tool (Midjourney, DALL·E), iterates 20+ prompts, downloads PNGs, manually traces or hands them to a designer, drops the master into the module's directory, runs kicon generate. Three issues:

  1. *endor lock per icon.*Each round of generation is bespoke: different prompts, different services, different post-processing. Selection rationale is not reproducible.
  2. *o procedural option.*When a product just needs "a circular badge with the letter K and brand colors" there is no fast path — you still have to open a design tool. Procedural icons (badges, monograms, simple geometric forms) make up a meaningful slice of asks.
  3. *o 3D path inside the toolchain.*Photorealistic 3D icons (the Koder Jet path — memory project_jet_icon_candidates) require Blender or a comparable tool, and there is no integration anywhere — every Koder product reinvents the rendering pipeline.

The Koder Hub rename (hubRFC006) needs 20 icon candidates following direction A (3D hub & spoke). It is the trigger to fix the pipeline once and for all instead of running the ad-hoc loop a sixteenth time.

3. Goals

  • One CLI surface (kicon design) covers every realistic generation path: procedural, imagemodel, 3Drendered.
  • Backend pluggability — a new generation source (e.g. Replicate, Flux, Midjourney) is added by implementing one Go interface.
  • All imagemodel traffic flows through services/ai/gateway/ (existing OpenAIcompatible facade), via the koder_imagegen_kit SDK. No direct provider API calls in kicon or in any other consumer. Enforce SDK-first policy from one canonical place.
  • Reproducibility — every generated batch ships with a manifest.json that records prompt, parameters, backend, model, seed, timestamp. A future re-run with the same manifest must produce equivalent output.
  • Vectorization first-class — raster outputs from image models or 3D renders can be converted to SVG masters in the same tool, without leaving kicon.
  • Selection workflow — pick from a candidate batch interactively (browser grid or terminal preview) and commit the chosen master into the module dir, ready for kicon generate.

4. Non-Goals

  • Replacing professional design tooling (Figma, Inkscape, Illustrator). kicon design covers the "I need a competent icon fast" case, not the "I need a brand identity system" case.
  • Training a custom Koderstyle image model. The pipeline consumes offtheshelf models through the gateway; model finetuning is out of scope.
  • Hosting the gateway, the runtime, or any backend infrastructure. kicon is a client; backends live where they always have (services/ai/gateway, services/ai/runtime).
  • Blender as a hard dependency. The Blender backend is opt-in; users without Blender installed see a clear "blender not found" message and can fall back to procedural or imagegen.

5. Background

kicon v0.2.x covers RFC-001: take one master SVG, validate it against specs/icons/products.kmd, emit platform variants (Android adaptive, iOS, macOS .icns, Windows .ico, Linux PNGs, web favicon, Hub catalog tile). It assumes the master already exists.

The gateway (services/ai/gateway/) already exposes POST /v1/images/generations (OpenAI-compatible) with two providers wired: OpenAI (DALL·E) and Stability (Stable Diffusion). Routing in cmd/gateway/main.go:routeImageRequest matches on model prefix. ImageProvider interface in internal/provider/provider.go is the extension point.

There is no existing Koder pattern for procedural icon templates and no existing Blender pipeline anywhere in the monorepo.

6. Design

6.1 Subcommand Surface

kicon design generate \
    --backend procedural|imagegen|blender \
    --template <name> | --prompt <text> | --scene <name> \
    --params key=value,... \
    --n 20 \
    --out workdir/

kicon design pick workdir/                # opens browser grid; --no-browser for TTY
kicon design refine workdir/ --keep N,N,N --n 10
kicon design promote workdir/<id> --dest <module>/icon.svg

kicon vectorize <png> --backend vtracer|potrace --out <svg>

kicon design generate produces a workdir of N candidates plus manifest.json. pick opens an interactive selector. refine regenerates a fresh batch biased toward the kept candidates (re-runs the same backend with parameter perturbations). promote installs the chosen candidate into a module's icon slot and runs kicon validate.

kicon vectorize is independent — it converts any PNG to SVG and is reused by both the imagegen and blender flows.

6.2 Backend Abstraction

package design

type Backend interface {
    Name() string
    Capabilities() Capabilities
    Generate(ctx context.Context, spec Spec) (*Batch, error)
}

type Spec struct {
    Template string            // procedural template name OR blender scene name (mutually exclusive with Prompt)
    Prompt   string            // imagegen
    Params   map[string]string // backend-specific parameters
    N        int
    Seed     *int
    Size     string            // "1024x1024" etc.
    Workdir  string
}

type Capabilities struct {
    AcceptsTemplate bool
    AcceptsPrompt   bool
    AcceptsScene    bool
    OutputsSVG      bool
    OutputsPNG      bool
    Reproducible    bool // same Spec → same Batch (with seed)
}

type Batch struct {
    Candidates []Candidate
    Manifest   Manifest
}

type Candidate struct {
    ID    string  // "01", "02", ...
    Path  string  // relative to Workdir
    Type  string  // "svg" | "png"
}

Each backend is a Go package under internal/design/backend_<name>/ that registers itself via init() into a process-wide registry keyed by name.

6.3 Procedural Backend

internal/design/backend_procedural/. Templates are Go-templated SVG files in internal/design/templates/, one directory per template:

templates/
  hub-and-spoke/
    template.svg    (Go text/template with parameter placeholders)
    schema.json     (parameter names, types, ranges, defaults)
    samples.yaml    (curated parameter combinations, used as the seed batch)

A run with --n 20 either picks 20 entries from samples.yaml (if present and ≥N) or generates 20 random parameter combinations within schema.json ranges. --params overrides specific keys.

First template ships: *hubandspoke`* Parameters:

  • spoke_count (4..6)
  • spoke_endpoint_shape (cube | sphere | prism, varied per spoke)
  • core_color, spoke_color, endpoint_palette
  • gradient_intensity (0.0..1.0, simulates 3D depth via radial gradients)
  • rotation_offset_deg

Output is SVG. OutputsSVG=true, Reproducible=true (deterministic given seed).

Future templates that fit procedural well: badge (circular emblem with letter), monogram (letter pair in geometric layout), token (gem/coin shape), grid (logo as cell layout).

6.4 Imagegen Backend

internal/design/backend_imagegen/. Calls services/ai/gateway/v1/images/generations via the *koderimagegenkit`*SDK (created as part of this RFC, see §7) — never the provider APIs directly.

Per-call parameters mapped from Spec:

  • Promptprompt
  • --params model=dall-e-3model
  • --params size=1024x1024size
  • Nn (requests N images in one call when supported, else loops)
  • Seedseed (when the underlying provider supports it; SDXL does, DALL·E does not)
  • --params response_format=b64_json → returns inline base64 (preferred over signed URLs to avoid the URL-expiry race)

Output is PNG. OutputsPNG=true, Reproducible= whatever the underlying provider claims via the SDK.

Models the gateway will route correctly (already in K9 inventory):

  • dall-e-3, dall-e-2 → OpenAI provider
  • stable-diffusion-xl-1024-v1-0, stable-diffusion-3-medium, flux.1-* → Stability or runtime provider
  • imagen-3 → Google provider (added by K9)
  • koder/sdxl-local, koder/flux-local → koder_runtime provider (added by K9)

6.5 Blender Backend

internal/design/backend_blender/. Shells out to blender --background --python <script> -- <args>. Scenes live in internal/design/scenes/<name>.blend paired with internal/design/scenes/<name>.py that exposes parameters via argparse and writes one render per invocation.

First scene ships: *hubandspoke.blend** with parameters mirroring the procedural template (spoke_count, materials, lighting profile). For N candidates, kicon` invokes Blender N times with parameter variations and collects the rendered PNGs.

Detection: blender --version at backend init; if absent, the backend registers itself but Generate returns a clear "blender not installed" error pointing at install instructions.

Output is PNG. OutputsPNG=true, Reproducible=true (Cycles with fixed seed is deterministic given the same .blend + script + args).

6.6 Vectorize Subcommand

cmd/kicon/vectorize.go + internal/vectorize/. Two backends:

  • *tracer*(preferred) — modern, color-aware, produces clean paths for illustrations. Install: cargo install vtracer or use the prebuilt binary. Tunables: color count, filter speckle, path simplify.
  • *otrace*— fallback, monochrome only, ubiquitous on Linux distros.
kicon vectorize foo.png --backend vtracer --colors 8 --simplify 4 --out foo.svg

Always runs the resulting SVG through kicon validate and reports any spec violations.

6.7 Selection Workflow

kicon design pick <workdir> opens a local HTTP server on 127.0.0.1:7654 and a browser window with a grid of candidates. Each candidate has Approve / Reject / Star buttons; the user can also edit the prompt or template parameters and request a refine round inline. State persists in <workdir>/picks.json.

TTY fallback (--no-browser): list candidates numerically, render previews via chafa (256-color terminal images) when available, otherwise show paths and let the user open them externally.

kicon design promote <workdir>/<id> --dest <module>/icon.svg:

  • If candidate is SVG → copy directly, then kicon validate.
  • If candidate is PNG → run kicon vectorize with sensible defaults, then kicon validate. User can rerun vectorize manually with custom params if the autovectorization is unsatisfactory.

6.8 Workdir Layout

workdir/
  manifest.json              # backend, model, prompt/template, params, seed, timestamp, kicon version
  candidate-01.svg|png
  candidate-02.svg|png
  ...
  picks.json                 # per-candidate: status (pending|approved|rejected|starred), notes
  refines/
    01/                      # nested workdir, same layout, parent_picks pointer in manifest

Manifest schema versioned (schema_version: 1). Future kicon design replay <manifest> reproduces a batch from a manifest alone.

7. Scope of Change

Codified into 12 tasks (K1..K12) in the project task list, mapped here:

# Item Module
K1 Mapping (done)
K2 This RFC products/dev/kicon/docs/rfcs/
K3 Tickets in koder-stack + kicon backlogs projects/koder-stack/backlog/, products/dev/kicon/backlog/
K4 design subcommand skeleton + procedural backend + hub-and-spoke template products/dev/kicon/{cmd,internal/design}/
K5 imagegen backend (direct gateway HTTP first) products/dev/kicon/internal/design/backend_imagegen/
K6 vectorize subcommand products/dev/kicon/{cmd,internal/vectorize}/
K7 Blender backend + first scene products/dev/kicon/internal/design/backend_blender/ + scenes/
K8 pick / refine / promote subcommands products/dev/kicon/cmd/ + internal/design/picker/
K9 Gateway image-gen backends (Imagen, koder_runtime) services/ai/gateway/internal/provider/
K10 koder_imagegen_kit SDK (Go + Dart) engines/sdk/imagegen/ (Dart) + engines/sdk/go-imagegen/ (Go)
K11 Migrate kicon's imagegen backend to use the SDK products/dev/kicon/internal/design/backend_imagegen/
K12 E2E validation: generate Hub icon (resolves backlog #036)

8. Execution Plan

Sequenced for shippability — every checkpoint produces something usable on its own.

Stage Tickets Deliverable Status
1 K1, K2, K3 Plan + RFC + tickets in backlog F1 of Hub work proceeds in parallel
2 K4 kicon design generate --backend procedural --template hub-and-spoke --n 20 produces 20 SVG candidates in workdir First usable slice
3 K5 Same command works with --backend imagegen --prompt "..." (direct gateway HTTP) Image-model path live
4 K6 kicon vectorize available; PNG candidates from K5 can be promoted to SVG masters Full PNG → SVG → variants chain
5 K7 Blender backend works for any user with Blender installed; first scene shipped 3D path live
6 K8 kicon design pick opens browser grid, promote writes the chosen master UX complete
7 K9 Gateway routes Imagen + koder_runtime alongside OpenAI/Stability More models reachable
8 K10 SDK published; first consumer is kicon SDK-first compliance
9 K11 kicon's imagegen backend refactored to consume the SDK Direct HTTP removed
10 K12 Hub icon batch generated, picked, promoted Backlog #036 resolved; HubRFC006 F2 unblocked

Stages 2–6 deliver kicon v2 standalone. Stages 7–9 deliver the meta layer per policies/sdk-first.kmd. Stage 10 closes the loop with the original trigger.

9. Dependencies

  • services/ai/gateway/ already exposes the image generation endpoint (K1 confirmed).
  • vtracer (Rust) and/or potrace (C) for K6. Both are offtheshelf binaries with permissive licenses.
  • Blender 3.x+ for K7 (optional — backend gracefully degrades when absent).
  • chafa for K8 TTY fallback (optional).
  • HubRFC006 (the trigger) does not block kicon work; the Hub rename can proceed with placeholder icon and have the real icon slotted in via K12 before F5 of the Hub plan.

10. Alternatives Considered

  • *dd image generation logic directly to each consumer (kicon, hub landing page generator, etc.)*— rejected: violates policies/sdk-first.kmd, fragments backend choice, makes A/B-ing models impossible.
  • *ake services/ai/image-gen/ a separate service*— considered. Rejected because the gateway already owns the OpenAIcompatible facade and adding a parallel surface duplicates auth, audit, ratelimit, billing, cache. Easier to extend the gateway than fork it.
  • *se Midjourney as the canonical backend*— rejected: no first-party API, requires Discord proxy (against ToS for many use cases), poor reproducibility.
  • *kip procedural backend and rely solely on image models*— rejected: procedural is faster, deterministic, free, and covers a real slice of asks (badges, monograms). Loss of vendor independence too high otherwise.
  • *kip Blender backend and rely on raster→vector for 3D*— rejected: vectorization of photorealistic 3D loses too much detail; for 3Dassource workflows, Blender is the right tool. Optional dependency keeps the cost low.
  • *uild a custom GUI app for selection instead of HTTP+browser*— rejected: browser is universal, zeroinstall on the user side, easy to embed images, fits the Koder Stack's webfirst ergonomics.

11. References

  • kicon-RFC-001-icon-generation.md — variant generation (the "after master exists" half)
  • hub-RFC-006-unification-and-rename.md §6.4 — the Hub icon trigger
  • specs/icons/products.kmd — icon contract (3D, forma=conceito, sem fundo)
  • specs/icons/generation-targets.kmd — per-platform variant rules consumed by kicon generate
  • services/ai/gateway/api/openapi.yaml — image-gen endpoint contract
  • services/ai/gateway/internal/provider/provider.goImageProvider interface
  • policies/sdk-first.kmd — enforcement rationale for §6.4 SDK choice
  • Memory project_jet_icon_candidates — Jet went PNG-photorealistic; informs the K7 Blender path
  • Memory project_flow_icon_selection — Flow batch selection workflow that K8 generalizes

Source: ../home/koder/dev/koder/meta/docs/stack/rfcs/kicon-RFC-002-design-generation-pipeline.md