{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/core/scheduler/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iDAAiD,CAAC;AAC9F,OAAO,KAAK,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEzF,kFAAkF;AAClF,MAAM,WAAW,iBAAiB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,aAAa,EAAE,mBAAmB,CAAC;IACnC,iFAAiF;IACjF,sBAAsB,EAAE,MAAM,CAAC;CAC/B;AAED,6CAA6C;AAC7C,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,sBAAsB,EAAE,GAAG,sBAAsB,EAAE,CAOxG;AAED,8DAA8D;AAC9D,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAEpG;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,IAAI,EAAE,oBAAoB,GACxB,iBAAiB,GAAG,SAAS,CAW/B","sourcesContent":["/**\n * Scheduler Foundation — deterministic policy (2.12.0).\n *\n * Pure, side-effect-free executor selection. There is no scoring, ranking, or\n * random tie-breaking: candidates are total-ordered by `executorId`, and intents\n * are total-ordered by `priority` (descending), then `enqueuedAtMs` (FIFO), then\n * `intentId`. Identical scheduler state always yields an identical decision.\n */\n\nimport type { AssignabilityResult } from \"../assignment/assignment-types.js\";\nimport type { ExecutorLivenessStatus } from \"../executor-registry/executor-registry-types.js\";\nimport type { SchedulingIntentRecord, SchedulingPolicyMode } from \"./scheduler-types.js\";\n\n/** One executor considered for a single intent, with its liveness observation. */\nexport interface ExecutorCandidate {\n\texecutorId: string;\n\tstatus: ExecutorLivenessStatus;\n\tassignability: AssignabilityResult;\n\t/** Number of current (designation) assignments already held by this executor. */\n\tcurrentAssignmentCount: number;\n}\n\n/** Deterministic intent processing order. */\nexport function orderPendingIntents(records: readonly SchedulingIntentRecord[]): SchedulingIntentRecord[] {\n\treturn [...records].sort((a, b) => {\n\t\tif (b.priority !== a.priority) return b.priority - a.priority;\n\t\tif (a.enqueuedAtMs !== b.enqueuedAtMs) return a.enqueuedAtMs - b.enqueuedAtMs;\n\t\tif (a.intentId !== b.intentId) return a.intentId < b.intentId ? -1 : 1;\n\t\treturn 0;\n\t});\n}\n\n/** Deterministic candidate ordering: ascending executorId. */\nexport function sortExecutorCandidates(candidates: readonly ExecutorCandidate[]): ExecutorCandidate[] {\n\treturn [...candidates].sort((a, b) => (a.executorId < b.executorId ? -1 : a.executorId > b.executorId ? 1 : 0));\n}\n\n/**\n * Choose one executor deterministically.\n *\n * - `first-fit`: the first assignable executor by ascending executorId.\n * - `least-assigned`: the assignable executor with the fewest current\n *   assignments, tie-broken by ascending executorId.\n */\nexport function chooseExecutor(\n\tcandidates: readonly ExecutorCandidate[],\n\tmode: SchedulingPolicyMode,\n): ExecutorCandidate | undefined {\n\tconst sorted = sortExecutorCandidates(candidates);\n\tif (sorted.length === 0) return undefined;\n\tif (mode === \"least-assigned\") {\n\t\tlet best = sorted[0];\n\t\tfor (const candidate of sorted) {\n\t\t\tif (candidate.currentAssignmentCount < best.currentAssignmentCount) best = candidate;\n\t\t}\n\t\treturn best;\n\t}\n\treturn sorted[0];\n}\n"]}