Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions skills/lemonade-router-builder/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,13 @@ The `x-lemonade-route` response header carries the matched rule id (or
`x_lemonade_route`: `{ route_to, matched_rule, default_used, outputs,
trace[] }` - useful for verifying each rule fires as expected.

**Read `default_used`, not the rationale.** A fallback returns HTTP 200 with no
error, so the silent failure Step 4 warns about is invisible unless you check
the trace. `"default_used": true` with `"matched_rule": ""` is the signature.
In Mode A an empty `rationale` on its own is *not* a fallback signal - a
successful route to a non-first candidate commonly returns one. See
[reference.md](reference.md#reading-a-mode-a-trace).

## Defaults summary

| Field | Default when the user doesn't say |
Expand Down
13 changes: 13 additions & 0 deletions skills/lemonade-router-builder/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ should produce. Note what was defaulted: names, ids, thresholds, `on_error`,
is derived from the default candidate rather than a fixed literal, so the
examples below each get a distinct name.

**These are shape references, not runnable policies.** Each names models a
given host may not have. They all pass `scripts/validate.py`, which
deliberately cannot check model existence - that needs a live server. Register
one against a host missing a referenced model and the server rejects it:

```
400 Collection component not registered: '<model>'.
Pull or register it before referencing it in a collection.
```

That is correct, documented behaviour. Substitute models the target host
actually has (`GET /api/v1/models`) before registering.


## 1. Pure intent, no concrete signals → LLM-as-router

Expand Down
23 changes: 23 additions & 0 deletions skills/lemonade-router-builder/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,29 @@ for keyword/metadata conditions. Registration errors come back as descriptive
parser messages (e.g. `routing.default_model 'X' must be listed in
routing.candidates`); fix the field it names and re-POST.

### Reading a Mode A trace

Mode A has no author-supplied rule ids, so `matched_rule` reports synthetic
ones - `__route_0`, `__route_1`, ... - one per entry in `routing.candidates`,
in declaration order.

Two things about these traces are easy to misread. Observed at 11.5.2:

- **An empty `rationale` is not a failure signal.** Routing to a candidate
other than the first commonly returns `"rationale": ""` and `"score": 0.0`
on a perfectly successful decision.
- **Fallback has one unambiguous signature** - all three together:

```json
{ "default_used": true, "matched_rule": "", "rationale": "", "score": 0.0 }
```

with `x-lemonade-route: default`. Check `default_used`, not the rationale.

A fallback returns HTTP 200 with no error field, so a policy that falls back on
every single request is indistinguishable from a working one unless you ask for
the trace.

## Desktop-editor compatibility

Users may open the generated policy in the Lemonade desktop app's Hybrid
Expand Down