Skip to content

feat: overlay targets are scheduling hints, not a serving class - #2087

Merged
hachall merged 6 commits into
mainfrom
feat/targets-are-hints
Oct 22, 2026
Merged

hachall merged 6 commits into
mainfrom
feat/targets-are-hints

Conversation

@hachall

@hachall hachall commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

What

A serving class is where a request is routed. Until now, an organisation overlay's targets made the request resolve as a custom class. This PR removes custom: overlay targets become scheduling hints, exactly like account-file priority and targets, and the request keeps its routed class (standard today).

Before After
Overlay targets → resolved class custom (analytics resolved_serving_class, tariff and cache lookup) Resolved class is always the routed class (standard)
Targets sent through a separate path, even to members that refuse scheduling fields Targets, priority and account priority all go through one hints path, only to dynamo members that accept scheduling fields
Overlay class_pricing could price custom class_pricing prices one of the model's classes (standard). custom is refused by validation, and rows the catalog owns under it are retired on the next apply

Why

  • Classes are destinations. model is standard and, later, model:fast is fast. Customer deals (priority, limits, price, tolerations) sit on top of whichever class a request hits. Latency targets are customer labels for alerting and diagnostics; nothing routes on them. custom was left over from the earlier target-routing design.
  • Fixes a pricing gap. With targets on an overlay, the price lookup used class custom and skipped an account's standard-class price, falling back to the model default. The new e2e test overlay_targets_change_neither_the_class_nor_the_price covers it.

Changes

  • onwards:
    • ServingClass has only Standard. ServingTargets, the overlay targets field and the separate stamping path are removed. A stored config that still carries overlay targets loads, and the field is ignored.
    • Hints are not sent to a named-pool member that refuses scheduling fields, matching how its nvext is already stripped.
    • The request span records onwards.serving.priority and onwards.serving.targets (whether latency targets were sent), separately from onwards.serving.resolved.
  • dwctl:
    • The sync maps model_overlays.targets (ttft_ms, itl_ms, priority) onto the overlay's hints.
    • PricingClass is standard only; custom joins the retired class names.
    • The batch-in-class check that standard made redundant is removed.
  • dashboard:
    • Pricing lists the model's classes only. A class price is shown winning over the organisation's all-class price, as billing does.
    • Overlay details label targets as scheduling hints.
  • docs: the overlay how-to, the configuration reference and the class-identity note.

Compatibility

  • Existing overlay files keep working: targets: {ttft_ms, itl_ms, priority} is unchanged on the wire and now applies as hints.
  • An overlay file that uses class_pricing: custom fails validation (startup and the offline validator). Move such a price to standard.
  • No migration.
  • onwards drops public items (ServingTargets, ServingClass::Custom). Its next release is already a major.

Tests

  • just lint rust, just lint ts: green.
  • just test ts: 805 passed.
  • just test rust: 4244 of 4245 passed. The failure was test_e2e_ai_proxy_streaming_chat_completions_with_fusillade_header, a known load-timing flake; it passed 3/3 on its own and in the previous full run.
  • After merging main (deps/CA bundle): onwards 676 passed, and the affected dwctl suites passed.

🤖 Generated with Claude Code

View guided diff Turn on auto-fix

A serving class is where a request is routed. Overlay `targets` used to make
a request resolve as a `custom` class, which changed its analytics class and
its price lookup: an account's standard-class price was skipped whenever its
overlay carried targets. Targets now travel exactly like account-file hints:
the priority and latency targets are sent to dynamo members, and the request
keeps its routed class (standard) and its price.

- onwards: `ServingClass` has only `standard`; the separate targets path and
  `ServingTargets` are gone. Hints are not sent to a named-pool member that
  refuses scheduling fields, matching how its `nvext` is already stripped.
  The request span records the hinted priority and whether targets were sent.
- dwctl: the sync turns stored overlay targets into hints. Overlay
  `class_pricing` prices one of the model's classes (`standard`); `custom` is
  refused, and rows the catalog owns under it are retired on the next apply.
- dashboard: pricing shows the model's classes only; overlay details label
  targets as scheduling hints.
Copilot AI balanced review requested due to automatic review settings October 22, 2026 10:45
@cubic-dev-ai

cubic-dev-ai Bot commented Oct 22, 2026

Copy link
Copy Markdown

Running ultrareview automatically — this PR appears to change payment, billing, or quota logic, where a missed bug can charge customers the wrong amount, so a deeper multi-pass review is worth running. I'll post findings when complete.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Deploying control-layer with  Cloudflare Pages  Cloudflare Pages

Latest commit: 20ee974
Status: ✅  Deploy successful!
Preview URL: https://02d29d3e.control-layer.pages.dev
Branch Preview URL: https://feat-targets-are-hints.control-layer.pages.dev

View logs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultrareview ran automatically — this PR appears to change payment, billing, or quota logic, where a missed bug can charge customers the wrong amount, so a deeper multi-pass review is worth running.

All reported issues were addressed across 15 files

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread docs/src/how-to/organization-model-overlays.md Outdated
Comment thread onwards/src/handlers.rs
Comment thread dwctl/src/sync/onwards_config/mod.rs
Comment thread dwctl/src/org_overlays.rs
… policies

Name the request span's targets field for what it is (configured) and record
onwards.hints_sent on the attempt that actually carried hints. A
priority-only account policy no longer clears an overlay's latency targets in
the sync. The overlay docs name dynamo members that accept scheduling fields,
and a test covers retiring catalog-owned custom prices on a still-declared
model.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 5 files (changes from recent commits).

Requires human review: Cross-cutting serving behaviour change: overlay targets become scheduling hints, the custom serving class and its pricing are removed, altering production class resolution, tariff selection and dashboards. Affects the production request path, so it requires human approval.

View guided diff | Turn on auto-fix | Re-trigger cubic

@hachall
hachall added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit 4723cfa Oct 22, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants