Issue files (.scratch/issues/20-29): retrospective specs for all work done in the current sprint — hardening, route-timeout, start-layer protocol, heartbeat stats, availability map, rolling RPM, smart assignment, throughput routing, routing tests, relay outbound client. ADRs (docs/adr/0011-0014): 0011 — Auto-shard from memory budget and tracker network assignment 0012 — X-Meshnet-Start-Layer overlapping shard execution protocol 0013 — Rolling RPM statistics, smart assignment scoring, throughput routing 0014 — Relay outbound client for NAT/internet pipeline hops prd.json: US-020 through US-029 added, all marked done. ralph_progress.py now shows 29/29 complete (100%). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
33 lines
1.1 KiB
Markdown
33 lines
1.1 KiB
Markdown
# US-026 — Smart model assignment via demand×coverage scoring
|
||
|
||
Status: done
|
||
Priority: Medium
|
||
Stage: Implemented
|
||
|
||
## Context
|
||
|
||
`/v1/network/assign` currently picks the model with the largest uncovered shard gap,
|
||
ignoring traffic. A model serving 1000 RPM at 60% coverage is far more valuable to fill
|
||
than a zero-traffic model at 50% coverage.
|
||
|
||
## Scoring formula
|
||
|
||
```
|
||
score = (demand_rpm + 1.0) × (coverage_deficit + 0.01)
|
||
```
|
||
|
||
- `demand_rpm`: combined RPM from `_StatsCollector.get_combined_stats()`
|
||
- `coverage_deficit`: fraction of model layers with zero node coverage, in [0.0, 1.0]
|
||
- `+1.0` floor: models with no traffic still compete by coverage
|
||
- `+0.01` floor: fully-covered models still have a non-zero score if they have traffic
|
||
|
||
`price_per_token: 0.0` reserved in the response for future billing integration.
|
||
|
||
## Acceptance criteria
|
||
|
||
- [ ] `_handle_network_assign` computes score per model and returns the highest
|
||
- [ ] Demand uses combined stats (local + peer slices)
|
||
- [ ] `price_per_token: 0.0` present in response
|
||
- [ ] Test: high-demand low-coverage model beats low-demand high-coverage model
|
||
- [ ] `python -m pytest` passes
|