Search that respects the user’s persistent trait preferences — allergens they must avoid, dietary stances (vegan, kosher, halal), religious constraints, and sourcing preferences (organic, fair-trade, local).Documentation Index
Fetch the complete documentation index at: https://docs.closient.com/llms.txt
Use this file to discover all available pages before exploring further.
When to use
- User has a preference profile (explicitly set or inferred) and searches without restating “and no nuts please” each time.
- Any recipe / meal / grocery workflow where preferences should be defaulted.
Preferences model
Closient tracks a user’sTraitPreference list — each entry is:
trait— lower-snake-case slug, e.g.peanuts(allergen),vegan(dietary),kosher(religious). Pass directly into search constraints.stance—AVOID/REQUIRE/PREFER/NEUTRALcategory— ALLERGEN / DIETARY / RELIGIOUS / SOURCING
Flow (end-to-end)
1. Read user preferences
200 + []. Read-only — writes still happen
through the dashboard’s HTMX form at /preferences/.
2. Translate preferences into constraints
| Category | Stance | Goes into |
|---|---|---|
| ALLERGEN | AVOID | exclude_allergens |
| DIETARY | REQUIRE | require_certifications |
| RELIGIOUS | REQUIRE | require_certifications |
| SOURCING | REQUIRE | require_certifications |
| ANY | PREFER | rank boost (client-side) |
| ANY | NEUTRAL | ignored |
3. Run a constrained search
The unified surface accepts the three constraint sets directly — either as list query params onGET /search/api/v1/search or as constraints.*
keys on POST /search/api/v1/search/session:
"avoid peanuts", "vegan certified", "no sucralose" —
so unauthenticated callers without a stored preference list still get
the filter for free.
4. Read the trait fields on each result
SearchResultOut carries the fields inline so no per-candidate
round-trip is needed:
certifications: string[]— certification slugs the product holds (unionsCertificationAssignmentcodes with non-allergenTraitlinks — DIETARY / RELIGIOUS / SOURCING).contains_allergens: string[]— allergen slugs detected on the product (unions allergen-typed substance composition with explicit ALLERGENTraitlinks).substance_flags: string[]— substances that matched the current request’savoid_substancesfilter, so the UI can show “flagged because X”.allergen_data_confidence: "high" | "medium" | "low"—high: explicit substance composition matched (we know what’s in it).medium: explicit allergenTraitlink only (asserted, not compositional).low: neither signal — treat missing data as not clean.
Guidance for agents
- AVOID always beats PREFER — never recommend something that fails an AVOID constraint.
- Trust
high/mediumconfidence; questionlow. When the user has a hard avoid constraint and the row’s confidence islow, drop the candidate or ask the user instead of recommending blindly. - Surface the rationale — “Showing Product X because it’s certified vegan and avoids peanuts per your preferences.”
- Ask about gaps, don’t silently guess. If the user hasn’t set a preference relevant to a tricky product (e.g. glycerin for strict vegans), ask before deciding for them.
Related skills
local-product-search— the base search this skill wrapsfind-alternative— when a result fails a constraint, use this to substitute