/** * context-ledger/gates.ts — L2: the ledger's rows feed what gets included. * * Three gates, one policy, each hooking an EXISTING seam (no new framework * surface): `gatedTools(inner, predicate)` for tools, `skillGraph().entryBy` * for skills, and a rule-trigger wrapper for injections. * * THE POLICY PRINCIPLE — demote, never starve: a piece the ledger judges * poorly is demoted, but every `refreshEvery`-th decision lets it through * anyway ("parole"), so it keeps generating fresh ledger data. Without * parole a piece demoted once could never earn again — a self-fulfilling * verdict. And the ledger never judges a piece it barely knows: below * `minOffers` everything passes. */ import type { EntryScorer } from '../injection-engine/entryScorer.js'; import type { Injection } from '../injection-engine/types.js'; import type { ToolGatePredicate } from '../../tool-providers/types.js'; import type { ContextLedger } from './types.js'; /** * When the ledger is allowed to judge, and how harshly. * Plain-named knobs — a bookkeeper's rules, not ML hyperparameters. */ export interface LedgerPolicy { /** Don't judge a piece until it has been offered this many times. Default 5. */ readonly minOffers?: number; /** Demote below this used÷offered rate. Default 0.05 (essentially "never used"). */ readonly earnRateFloor?: number; /** * Parole: let a demoted piece through anyway every Nth demotion decision, * so it keeps earning fresh data. Default 10. `Infinity` disables parole * (NOT recommended — a starved piece can never redeem itself). */ readonly refreshEvery?: number; } /** * TOOL GATE — plug into the existing provider combinator: * * ```ts * import { gatedTools, staticTools } from 'agentfootprint/tool-providers'; * builder.toolProvider(gatedTools(staticTools(tools), ledgerToolGate(ledger))); * ``` * * Unused tool schemas are usually the biggest silent token cost — this is * the gate to start with. */ export declare function ledgerToolGate(ledger: ContextLedger, policy?: LedgerPolicy): ToolGatePredicate; /** * SKILL GATE — an `EntryScorer` for `skillGraph().entryBy(...)` that wraps * another scorer (keyword, embedding, …) and demotes candidates the ledger * says never earn. Demotion multiplies the inner score toward the floor — * ranking pressure, not exclusion — and parole restores full weight * periodically, so a demoted skill can still win when nothing else fits. */ export declare function ledgerEntryScorer(ledger: ContextLedger, inner: EntryScorer, policy?: LedgerPolicy): EntryScorer; /** * INJECTION GATE — wrap ONE injection so the ledger's verdict joins its * trigger. `always` becomes a ledger-backed rule; an existing `rule` is * AND-ed with the verdict. `on-tool-return` / `llm-activated` are returned * UNCHANGED (they are already demand-driven — the ledger has nothing to * add). `always` pieces are exempt unless you explicitly wrap them — the * safety-first default from the design. */ export declare function ledgerGated(injection: Injection, ledger: ContextLedger, policy?: LedgerPolicy): Injection; //# sourceMappingURL=gates.d.ts.map