Skip to content

feat: boost dispatch candidates outside declared peak hours - #301

Merged
dnth merged 4 commits into
mainfrom
fm/fm-dispatch-peak-hours
Nov 13, 2026
Merged

dnth merged 4 commits into
mainfrom
fm/fm-dispatch-peak-hours

Conversation

@dnth

@dnth dnth commented Nov 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

Profiles declare their provider's peak-price windows once; the resolver boosts that candidate's rank everywhere outside them and leaves ranking untouched inside them.

 { "harness": "omp", "model": "opencode-go/deepseek-v4.1-flash", "provider": "opencode-go",
+  "peak_pricing": {
+    "multiplier": 2,
+    "windows": [
+      { "weekdays": ["mon","tue","wed","thu","fri"], "start": "01:00", "end": "04:00" },
+      { "weekdays": ["mon","tue","wed","thu","fri"], "start": "06:00", "end": "10:00" } ] } }
rank(candidate)
  no peak_pricing, or inside a declared window  -> exp(spendPriority)
  outside every declared window (incl. weekend) -> exp(spendPriority) * multiplier   candidate line: offpeak=xN

The ranking weight is exp(spendPriority).
quota-axi's scalar is signed, so a literal multiplication by a boost factor would deepen a negative deficit instead of favoring the candidate; exp is order-preserving, so peak ranking is identical to a run with no declaration.
Eligibility, quota floors, exhausted-runway refusals, approvals, and the genuine-tie rule read the same unadjusted evidence.
The UTC clock is read once per run; FM_DISPATCH_CLOCK_UTC pins it for tests; a malformed declaration exits 2 in the resolver and bootstrap reports the same configuration error.

Evidence

  • Before: the new resolver cases failed on the unfixed code, for example not ok - off-peak boosts a below-leader weight past the leader (missing: profile '--harness omp --model opencode-go/deepseek-v4.1-flash'); the 0.3 candidate stayed behind the 0.4 candidate.
    After: bash tests/fm-dispatch-resolve.test.sh exits 0 with every case green, including off-peak and weekend boosts, peak output identical to no declaration, eligibility and adjusted-tie handling, malformed declarations, single midnight-crossing clock sampling, and trailing-newline rejection.

  • Substitute for the cancelled macOS check (firstmate-approved; the captain decides the merge): the Stock macOS Bash snapshot compatibility job was cancelled by the provider twice with no verdict.
    Its own workflow commands were run under the exact required interpreter, GNU bash 3.2.57:

    • bash --version -> GNU bash, version 3.2.57(1)-release (x86_64-pc-linux-musl)
    • parse sweep (bin/fm-lint.sh --list-files, then bash -n per file) -> 443 files, PASS
    • bash tests/fm-fleet-snapshot-view.test.sh -> 17 ok (CI expects 17)
    • bash tests/fm-bearings-snapshot.test.sh -> 47 ok (CI expects 47)
    • Date portability: bin/fm-dispatch-resolve.sh:365-367 tries GNU date -u -d and falls back to BSD date -u -j -f '%Y-%m-%dT%H:%M:%SZ'; the live path at :369 runs date -u '+%u %H:%M' with no date flags and POSIX/BSD strftime formats.
  • bin/fm-lint.sh (pinned ShellCheck 0.11.0): exit 0; bin/fm-doc-audience-check.sh: ok, surfaces=98, local_links=530.

Merge Danger

Door: two-way.
The field is optional, absent-field behavior is byte-identical, and reverting the commits restores the previous ranking.

Blast Radius: dispatch ranking only.
No behavior changes until peak_pricing is added to the private config/crew-dispatch.json after merge.

Pipeline

Updates from git push no-mistakes

✅ **Intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 7 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Local resolver with synthetic quota inputs boosts the lower-weight candidate off-peak and displays offpeak=x2 ✅ pass live Product CLI transcripts: weekday-offpeak, negative-signed-priorities
Local resolver applies the weekend boost even inside declared window clock times ✅ pass live Product CLI transcripts: saturday-inside-clock-window, sunday-second-window
Local resolver preserves undeclared ranking during peak hours and respects half-open window boundaries ✅ pass live Product CLI transcripts: first-window-start, first-window-interior, first-window-end, second-window-start, second-window-end and undeclared comparisons
Local resolver refuses ineligible candidates and preserves captain approval despite off-peak pricing ✅ pass live Product CLI transcripts: floor-refusal, exhausted-runway, approval-required and undeclared comparisons
Local resolver escalates a genuine adjusted-weight tie without choosing a profile ✅ pass live Product CLI transcripts: adjusted-weight-tie
Resolver rejects malformed rule and default pricing declarations; detect-only bootstrap reports the same configuration errors ✅ pass live Product CLI transcripts: malformed multiplier, time, weekday, newline and corresponding bootstrap cases
Local resolver samples weekday and time together once and rejects an invalid clock override ✅ pass live Structured CLI outputs: date_calls; Product CLI transcripts: system-clock, malformed-clock-override
  • bash tests/fm-dispatch-resolve.test.sh — exit 0; supplemental fixture-based regression coverage.
  • python3 .tmp-pricing-live/drive.py — exit 0; 47 real resolver/bootstrap CLI executions with isolated synthetic inputs and localhost HTTPS.
  • Inspected resolver-header and configuration-owner documentation; did not run prohibited lint or static-analysis commands.
  • Retained CLI evidence, stopped the HTTPS emulator, removed disposable workspace fixtures, and confirmed a clean worktree.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

dnth added 4 commits November 12, 2026 22:06
Profiles in config/crew-dispatch.json may declare optional peak_pricing:
UTC weekday windows plus a cost multiplier above 1. Outside every declared
window, including all weekend, the resolver multiplies the candidate's
positive ranking weight (exp of quota-axi spendPriority) by the multiplier
before the argmax; inside a window it ranks exactly as with no declaration.
Eligibility, floors, exhausted-runway refusals, approvals, and tie handling
read the same unadjusted evidence, and an adjusted candidate line shows
offpeak=xN. The UTC clock is read once per run, with FM_DISPATCH_CLOCK_UTC
pinning it for tests, and malformed declarations exit 2. Bootstrap applies
the same validation while typed resolution is active.
@dnth
dnth merged commit 273ee47 into main Nov 13, 2026
39 of 41 checks passed
@dnth
dnth deleted the fm/fm-dispatch-peak-hours branch November 13, 2026 00:48
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.

1 participant