mirror of
https://github.com/garrytan/gstack.git
synced 2026-07-30 19:21:41 +02:00
feat: design taste engine with persistent schema
Adds a cross-session taste profile that learns from design-shotgun
approval/rejection decisions. Biases future design-consultation and
design-shotgun proposals toward the user's demonstrated preferences.
Codex review caught that the plan had "taste engine" as a vague goal
without schema, decay, migration, or placeholder insertion points. This
commit ships the full spec.
Schema v1 at ~/.gstack/projects/$SLUG/taste-profile.json:
- version, updated_at
- dimensions: fonts, colors, layouts, aesthetics — each with approved[]
and rejected[] preference lists
- sessions: last 50 (FIFO truncation), each with ts/action/variant/reason
- Preference: { value, confidence, approved_count, rejected_count, last_seen }
- Confidence: Laplace-smoothed approved/(total+1)
- Decay: 5% per week of inactivity, computed at read time (not write)
Changes:
- bin/gstack-taste-update: new CLI. Subcommands approved/rejected/show/
migrate. Parses reason string for dimension signals (e.g.,
"fonts: Geist; colors: slate; aesthetics: minimal"). Emits taste-drift
NOTE when a new signal contradicts a strong opposing signal. Legacy
approved.json aggregates migrate to v1 on next write.
- scripts/resolvers/design.ts: new generateTasteProfile() resolver.
Produces the prose that skills see: how to read the profile, how to
factor into proposals, conflict handling, schema migration.
- scripts/resolvers/index.ts: register TASTE_PROFILE and a BIN_DIR
resolver (returns ctx.paths.binDir, used by templates that shell out
to gstack-* binaries).
- design-consultation/SKILL.md.tmpl: insert {{TASTE_PROFILE}} placeholder
in Phase 1 right after the memorable-thing forcing question so the
Phase 3 proposal can factor in learned preferences.
- design-shotgun/SKILL.md.tmpl: taste memory section now reads
taste-profile.json via {{TASTE_PROFILE}}, falls back to per-session
approved.json (legacy). Approval flow documented to call
gstack-taste-update after user picks/rejects a variant.
Known gap: v1 extracts dimension signals from a reason string passed
by the caller ("fonts: X; colors: Y"). Future v2 can read EXIF or an
accompanying manifest written by design-shotgun alongside each variant
for automatic dimension extraction without needing the reason argument.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
c1d6fd8706
commit
9e95a9dc50
@@ -116,7 +116,14 @@ Two rounds max of context gathering, then proceed with what you have and note as
|
||||
|
||||
## Step 2: Taste Memory
|
||||
|
||||
Read prior approved designs to bias generation toward the user's demonstrated taste:
|
||||
Read both the persistent taste profile (cross-session) AND the per-session approved
|
||||
designs to bias generation toward the user's demonstrated taste.
|
||||
|
||||
**Persistent taste profile (v1 schema at `~/.gstack/projects/$SLUG/taste-profile.json`):**
|
||||
|
||||
{{TASTE_PROFILE}}
|
||||
|
||||
**Per-session approved.json files (legacy, still supported):**
|
||||
|
||||
```bash
|
||||
setopt +o nomatch 2>/dev/null || true
|
||||
@@ -124,14 +131,17 @@ _TASTE=$(find ~/.gstack/projects/$SLUG/designs/ -name "approved.json" -maxdepth
|
||||
```
|
||||
|
||||
If prior sessions exist, read each `approved.json` and extract patterns from the
|
||||
approved variants. Include a taste summary in the design brief:
|
||||
|
||||
"The user previously approved designs with these characteristics: [high contrast,
|
||||
generous whitespace, modern sans-serif typography, etc.]. Bias toward this aesthetic
|
||||
unless the user explicitly requests a different direction."
|
||||
approved variants. Merge these into the taste-profile.json-derived signal — if the
|
||||
profile already says "user prefers Geist font" (from aggregated history), the
|
||||
approved.json files add the specific recent approval context.
|
||||
|
||||
Limit to last 10 sessions. Try/catch JSON parse on each (skip corrupted files).
|
||||
|
||||
**Updating taste profile after a design-shotgun session:** When the user picks a
|
||||
variant, call `{{BIN_DIR}}/gstack-taste-update approved <variant-path>`. When they
|
||||
explicitly reject a variant, call `{{BIN_DIR}}/gstack-taste-update rejected <variant-path>`.
|
||||
The CLI handles schema migration from approved.json, decay, and conflict flagging.
|
||||
|
||||
## Step 3: Generate Variants
|
||||
|
||||
Set up the output directory:
|
||||
|
||||
Reference in New Issue
Block a user