research-scheduler
Closes the kannaka-hdl §14 loop (ADR-0002). One pass:
- Collect demand — grow every store program (each app's entry / gate / seed / variants, plus this app's
demand/*.khdl) speculatively and harvestdiscovery_requestsfrom the sealed plans. Expect-gated programs that refuse to emit while failing still contribute: their unresolved-component warnings are parsed as degraded requests. - Rank — group by
domain|class; blocked-plan count first, floor stringency as tiebreak. - Order — for the top
max_ordersnon-memory entries with no standing order, enqueue acrystal_work_orderonto the swarm queue (kannaka swarm enqueue). Memory-domain demand is recall supply — provisioner territory, never a crystal order. The scheduler only enqueues; crystal work executes in the crystal lane. - Attribute — state lives in
~/.kannaka/research-scheduler.json(KHDL_SCHEDULER_STATEoverrides). A request that disappears from the backlog on a later pass is loggedRESOLVED, attributed to its order id. Two plans demanding the same class share one order with two attributions.
node runtime/khdl-app.mjs run apps/research-scheduler --dry-run # report only
node runtime/khdl-app.mjs run apps/research-scheduler # enqueue + persist
The shipped demand program (demand/memory-seed-bank.khdl) requests the "Memory Seed" crystal class — a real registry gap, not a synthetic one — so a fresh install has one honest standing order from its first pass.