import type { EvidenceLedger, Recommendation, RetroRollup } from '@manehorizons/cadence-types'; /** * Phase 212 (rec-20260712-004 lineage). The three `RetroRollup` frequency * dimensions a friction entry can come from — deliberately the exact key * names of `RetroRollup` itself so a match can be traced straight back to * `rollup[frictionBucket].recurring`. */ export type FrictionBucket = 'bypasses' | 'roughTaskStatuses' | 'findingCategories'; /** * One recurring friction entry matched to one candidate recommendation. * `phaseIds` is carried through from the `RetroFrequencyEntry` unchanged — * it is the evidence of *recurrence* the note text (below) reports. */ export interface FrictionMatch { frictionKey: string; frictionBucket: FrictionBucket; phaseIds: string[]; recommendationId: string; } /** * AC-1: pure, no I/O. For every *recurring* entry in each of the rollup's * three frequency buckets (never `oneOff` — Boundaries §"recurring only"), * find every recommendation whose `affectedAreas`/`affectedFiles` overlap * the friction key under {@link frictionMatchesCandidate}'s heuristic, and * emit one {@link FrictionMatch} per (friction entry, recommendation) pair. * A friction entry with no matching recommendation contributes nothing — * callers (T3's CLI command) distinguish "no match" from "matched" by * comparing the rollup's recurring entries against this function's output. */ export declare function matchFrictionToRecommendations(rollup: RetroRollup, recommendations: Recommendation[]): FrictionMatch[]; /** * Phase 212 T2 (AC-3): count how many `Evidence` entries linked to * `recommendation` (via `recommendation.evidenceIds`, cross-checked against * `e.recommendationId` same as {@link isAlreadyRecorded}) are * friction-derived — i.e. their `summary` starts with the shared * {@link FRICTION_MARKER_PREFIX}, regardless of bucket/key. Pure, no I/O; * `scoreRecommendation` (`packages/core/src/intelligence/recommend.ts`) * feeds this count into its capped `frictionPts` term. */ export declare function countFrictionEvidence(recommendation: Recommendation, evidenceLedger: EvidenceLedger): number; export type FrictionEvidenceOutcome = 'wrote' | 'skipped-already-recorded' | 'error'; export interface FrictionEvidenceResult { frictionKey: string; frictionBucket: FrictionBucket; recommendationId: string; outcome: FrictionEvidenceOutcome; evidenceId?: string; error?: string; } /** * AC-2: the impure write step. `recommendations` and `evidenceLedger` are * loaded once by the caller (T3's CLI command) and passed in — this function * does the idempotency check for every match purely in-memory against that * single snapshot. `matches` legitimately CAN carry several entries with the * same friction key+bucket within one run — `matchFrictionToRecommendations` * emits one `FrictionMatch` per (friction entry, recommendation) pair, so a * friction key that overlaps N recommendations produces N matches sharing * that key+bucket. What actually makes the in-memory snapshot safe is * uniqueness of the (frictionKey, frictionBucket, recommendationId) triple: * `recommendations` (the input array) never contains duplicate ids, and the * matching loop visits each recommendation at most once per friction entry, * so no two matches in one run ever target the same recommendation with the * same key+bucket — each `isAlreadyRecorded` check and each write below is * therefore against a distinct (recommendation, marker) pair, with no risk of * the in-memory snapshot going stale against itself mid-loop. Only reaches * for I/O (`addEvidenceToRecommendation`, phase 199's tied-record writer — * reused verbatim rather than re-implementing the ledger-write mechanics) on * an actual new match. `addEvidenceToRecommendation` redacts internally too; * the explicit `redactSecrets` call here matches how every other evidence * writer in `recommendations.ts` treats freeform text as untrusted at its * origin, not just at the final choke point. */ export declare function recordFrictionEvidence(root: string, matches: FrictionMatch[], recommendations: Recommendation[], evidenceLedger: EvidenceLedger): Promise; //# sourceMappingURL=retro-feedback.d.ts.map