/** * Plan-cache recurrence probe — INSTRUMENT-FIRST (search AI → service, 团队/给service-AI.md [1]; * core [ref]). Zero-LLM, zero-dependency, pure in-memory. * * Measures the **per-scope recurrence rate of task objectives**: the unproven "省钱" premise behind a * proposed core *plan-caching* feature (store a successful run's generalized plan → a similar new task * retrieves it as a hint). The 2-juror review wanted real data before core builds the producer hook: * does an agent's traffic actually re-pose near-duplicate objectives per tenant? (arXiv 2602.18922: * heterogeneous queries can hit 0–12%.) We hold the real multi-tenant traffic, so this is ours to count. * * **The token criterion is copied verbatim from core `strategy-store` (`compileStrategyQuery`)** — * otherwise we'd measure something other than what plan-cache retrieval would actually use. Note the * **asymmetry**: a stored problem is matched on its full `tokens()` set, the query on its * `significant()` set. A hit = `significant(new) ⊆ tokens(historical)` OR (5.49 legacy acceptance * arm) the non-CJK subset `qAlnum` is non-empty and fully contained (`qAlnum ⊆ tokens(historical)`). * * Fidelity choices (stated to search AI for confirmation): the history ring holds only **completed** * tasks (plan-cache only stores plans from successful runs), while the hit test runs for **every** * finished task; `qSig` length is bucketed so a hit can be told apart from a short-objective fluke * (the juror's `qSig>=3` gate). */ import type { Metrics } from "./observability/metrics.js"; import type { Logger } from "./observability/logger.js"; export declare function tokens(s: string): string[]; export declare function significant(s: string): string[]; /** Per-scope view for the 2-week handoff back to search AI. */ export interface ScopeRecurrence { tasks: number; hits: number; hitRate: number; /** qSig-length histogram (index 0..QSIG_CAP; last bucket = QSIG_CAP+). */ qsig: number[]; } export declare const QSIG_CAP = 12; /** * In-memory recurrence tracker. One per process (single replica per worker in prod; cross-replica * aggregation is unnecessary for a 2-week instrument — each instance reports its own slice). */ export declare class PlanCacheProbe { private readonly metrics?; private readonly logger?; private readonly byScope; constructor(metrics?: Metrics | undefined, logger?: Logger | undefined); /** * Record one finished task. `completed` = it succeeded (only those enter the history ring). Pure * in-memory + a counter/histogram + a debug log line; never throws into the caller. */ record(scopeRaw: string | undefined, objective: string, completed: boolean): void; /** Per-scope recurrence snapshot for the handoff (token-gated dump endpoint). */ dump(): Record; /** LRU get-or-create: re-insert on access so the oldest-touched scope is evicted past the cap. */ private touch; } //# sourceMappingURL=plan-cache-probe.d.ts.map