/** * Feedback-loop metrics: DORA-style roll-ups computed from existing state. * * Reads transitions.log, instance.yaml, phase-*.yaml, and the cost ledger — * no new ledger (AC-15). Read-only by construction: pure functions over * projectRoot (AC-19). Missing data degrades to null, never zero-fill; * empty denominators are null, not 0% (AC-17). * * Design: feedback-loop design.md §Metrics module (rev 2, F5/F11) */ import { type InstanceCost } from '../cost/report.js'; import type { InstanceState, PhaseState, WorkflowTemplate } from '../core/types.js'; import type { CostConfig } from '../cost/types.js'; /** Attribution rule for multi-cause bugfixes (design DD-1, AC-18). */ export declare const ATTRIBUTION_RULE: "full-count-per-cause"; export interface TemplateMetrics { template: string; /** Completed instances of this template (AC-22 completion moment). */ completed: number; /** Distinct completed instances named as a cause ÷ completed; null when completed = 0. */ change_failure_rate: number | null; /** Mean created_at → completion across completed instances; null when no data. */ avg_lead_time_seconds: number | null; /** Mean per-phase lead time across instances that ran the phase. */ phase_lead_times: Record; } export interface InstanceMetrics { name: string; template: string; completed: boolean; /** created_at → completion moment; null while incomplete or on bad data. */ lead_time_seconds: number | null; /** Bugfix instances whose caused_by names this instance. */ caused_bugfixes: string[]; /** null ⇔ no ledger data for the instance (F5: 0 means a priced $0, not absence). */ own_cost: InstanceCost | null; /** own + one-level caused bugfix costs; null when own_cost is null. */ true_cost_micro_usd: number | null; /** * own + one-level caused bugfix tokens; null when own_cost or any caused bugfix's * cost has no ledger data — the null rule above, in tokens (cost-in-tokens/AC-6). */ true_cost_tokens: number | null; } export interface MetricsReport { generated_at: string; attribution_rule: typeof ATTRIBUTION_RULE; coverage: { instances: number; with_caused_by: number; with_cost: number; }; templates: TemplateMetrics[]; instances: InstanceMetrics[]; /** caused_by values resolving to no known instance (AC-17). */ unresolved_causes: { bugfix: string; name: string; }[]; } /** * One instance's state as `completionInfo` and the metrics roll-ups need it. * * Exported alongside `loadInstance` so callers outside this module can build the * argument `completionInfo` takes (roadmap-revamp/AC-27). The roadmap layout * migration has to answer "did this instance finish?", and the naive form of * that question — is the last phase complete? — is wrong for maintenance-terminal * templates, which complete on maintenance *entry*. Reusing the existing answer * is cheaper and safer than a second definition of done that has to remember the * special case. */ export interface LoadedInstance { state: InstanceState & { caused_by?: string[]; }; phases: Map; dir: string; } /** * Load one instance's `instance.yaml` and every `phase-*.yaml` beside it. * * Returns null when the instance directory has no readable `instance.yaml`; an * unreadable individual phase file is skipped rather than failing the load, so a * partially-written state directory still yields what it has. */ export declare function loadInstance(projectRoot: string, name: string): LoadedInstance | null; /** * Built-in templates merged with the project's own overrides from * `.aidlc/templates/`, keyed by name. * * Exported with `loadInstance` because `completionInfo` needs both, and a caller * that could load an instance but not its templates would have to duplicate this * merge — including the precedence rule that a project override wins * (roadmap-revamp/AC-27). */ export declare function loadAllTemplates(projectRoot: string): Map; /** * The instance's final applicable phase (template × scope), or null when the * template cannot be resolved. Maintenance-terminal instances complete on * maintenance ENTRY; others when the final phase reaches status complete. */ export declare function completionInfo(inst: LoadedInstance, templates: Map): { completed: boolean; completedAt: string | null; }; /** * Per-phase lead seconds for one instance. Pairs transitions.log `to: X` * with the next `from: X`; null-from/to records (scope upgrades) are * skipped; unmatched intervals fall back to the phase YAML timestamps; * the current open phase is excluded. Inconsistency → phase omitted (null * downstream per AC-17). */ export declare function phaseLeadSeconds(inst: LoadedInstance): Map; /** Compute the full metrics report. Read-only (AC-19). */ export declare function computeMetrics(projectRoot: string, config: CostConfig | null, now?: () => string): MetricsReport; //# sourceMappingURL=report.d.ts.map