/** * Org sections spec 6.9 and 13.2 (piece P4.1): the section budget rules as pure functions. Nothing here is * wired: no module outside documents/ imports it, it reads no clock, environment, file or daemon state, and it * returns the same answer for the same definition. P4.5 wires the checks into the checklist and the resolver * into startup, resume and reload; P4.6 builds the closure on `allocationStatus` * (section-budget-status.ts). * * - `effectiveRoleUsdCap`: the ONE resolver of a role's USD cap (A25): `budget_usd`, with `policy.maxUsd` * allowed only when equal. * - `partitionOf`: who is charged to which allocation: each section's roster (the lead once), the root and * every unsectioned role in the root reserve. * - `resolveBudgetCaps`: the cap that applies to every role and section once the org ceiling and the * partition limits are applied (never above the org ceiling). * - `budgetFindings`: the definition-level checks, each with a code, a path and a remedy. */ export type RoleCapCode = 'ROLE_CAP_INVALID' | 'ROLE_CAP_CONFLICT'; export type RoleCapResult = { ok: true; usd: number | undefined; } | { ok: false; code: RoleCapCode; message: string; remedy: string; }; /** The part of a role the budget rules read. An `OrgDef` role is assignable to it. */ export interface BudgetRole { id: string; type?: string; kind?: string; reports_to?: string | null; runtime?: string; budget_usd?: number; policy?: { maxUsd?: number; } | undefined; } /** The part of a definition the budget rules read. An `OrgDef` is assignable to it. */ export interface BudgetDef { roles: BudgetRole[]; sections?: unknown; runtime?: string; run_config?: Record; } /** True when `a` is above `b` by more than rounding noise. */ export declare const exceedsUsd: (a: number, b: number) => boolean; export declare const roundUsd: (n: number) => number; export declare const isPositiveUsd: (v: unknown) => v is number; /** The resolver for one role (A25, spec 6.9 "effective cap parity"). `budget_usd` is canonical; * `policy.maxUsd` may be absent or equal to it. A `maxUsd` with no `budget_usd`, or a different one, is a * conflict: it is never silently preferred or dropped. */ export declare function effectiveRoleUsdCap(role: BudgetRole): RoleCapResult; export interface PartitionRole { id: string; /** The role's own cap when it has one that resolves (undefined: none, invalid or conflicting). */ capUsd: number | undefined; cap: RoleCapResult; } export interface PartitionGroup { roles: PartitionRole[]; /** Sum of the resolved caps of `roles`. */ capSumUsd: number; } export interface SectionPartition extends PartitionGroup { name: string; lead: string | undefined; /** True when the section has a `budget` key, well formed or not. */ budgetDeclared: boolean; /** `budget.usd` when it is well formed. */ allocationUsd: number | undefined; /** Roster ids with no role in the definition (the definition check reports them). */ unknownRoles: string[]; } export interface Partition { /** `run_config.budget_usd` when it is a positive number. */ orgUsd: number | undefined; sections: SectionPartition[]; /** The root and every role in no section. `usd` is the org budget minus the allocations (negative when * they over-allocate; undefined without an org budget). */ reserve: PartitionGroup & { usd: number | undefined; }; /** Sum of the well-formed section allocations. */ allocatedUsd: number; } /** The root the way definition.ts picks it: the boss, else the first role that reports to no one. */ export declare function rootOf(def: BudgetDef): BudgetRole | undefined; /** True for a role that runs a model session (an endpoint role is an HTTP automation and holds no cap). */ export declare const isAgentRole: (r: BudgetRole) => boolean; /** Who is charged to which allocation (spec 6.9). A section's roster is its members plus its lead, each role * once. A role in two sections belongs to the first (the definition check reports the rest). The root is * never in a section, even as a section's lead: it stays in the reserve. */ export declare function partitionOf(def: BudgetDef): Partition; export interface ResolvedRoleCap { /** The section the role is charged to; undefined: the root reserve. */ section: string | undefined; /** The role's own cap, when it resolves. */ declaredUsd: number | undefined; /** The cap that applies: the declared cap held under its partition limit and the org ceiling. */ effectiveUsd: number | undefined; /** True when `effectiveUsd` is below `declaredUsd`. A validated definition never is: budgetFindings reports * every case as an error, so a cap is rejected, never silently reduced. */ clamped: boolean; } export interface ResolvedCaps { orgUsd: number | undefined; /** Each section's allocation held under the org ceiling. */ sections: Record; /** The root reserve, never below zero. */ reserveUsd: number | undefined; roles: Record; } /** The cap that applies to each role and section. The precedence: a role's cap is `budget_usd` (see * `effectiveRoleUsdCap`); it is held under its partition's limit (the section's allocation, or the reserve * for the root and unsectioned roles) and under `run_config.budget_usd`. No entry is ever above the org * ceiling, and with no ceiling and no allocation nothing is held. */ export declare function resolveBudgetCaps(def: BudgetDef): ResolvedCaps; //# sourceMappingURL=section-budget.d.ts.map