/** * Ratchet Mechanism (FR-26). * * Prevents quality regression during performance optimization and refactoring tasks. * Scores can only go up, never down. If an optimization attempt produces worse metrics * than the baseline, changes are automatically rolled back via `git reset --hard`. * * AC-26.1: Project config enables ratchet per work-package with time budget, baseline metric, baseline value. * AC-26.2: Baseline snapshot (git SHA + metric value) recorded before Implement stage. * AC-26.3: Improvement → keep & commit; regression → git reset --hard to baseline SHA. * AC-26.4: Time budget exhausted without improvement → rollback, not pipeline failure. * AC-26.5: Ratchet result written to Stage Record and Ledger evidence chain. * AC-26.6: When disabled, Implement stage behaves identically to FR-05. * AC-26.7: Metric comparison uses executable evaluator (FR-23) scores, not LLM judgment. * AC-26.8: Audit event recorded before git reset, including reason, baseline SHA, discarded changes summary. */ import type { ArtifactRef } from '../types/index.js'; import type { EvaluatorResult } from './evaluator-types.js'; /** * Ratchet configuration for a single work-package or FR. * Declared in sevo.config.json: `{ ratchet: { "": RatchetConfig } }`. * * AC-26.1: Config includes time budget, baseline metric name, and baseline value. */ export interface RatchetConfig { /** Whether ratchet mode is active for this work-package. */ enabled: boolean; /** Maximum seconds allowed for the optimization attempt. */ timeBudgetSeconds: number; /** Name of the metric to track (e.g. "test-execution-time", "bundle-size"). */ baselineMetric: string; /** Baseline metric value. Lower-is-better by default; set `higherIsBetter` to invert. */ baselineValue: number; /** If true, higher scores mean improvement (e.g. throughput). Default: false (lower is better). */ higherIsBetter?: boolean; } /** * Ratchet configuration registry: work-package ID → config. */ export type RatchetRegistry = Record; /** * Baseline snapshot captured before optimization begins. * AC-26.2: Records git commit SHA + baseline metric value. */ export interface BaselineSnapshot { /** Git commit SHA at baseline. */ commitSha: string; /** Metric name being tracked. */ metricName: string; /** Metric value at baseline. */ metricValue: number; /** Timestamp when snapshot was taken. */ capturedAt: string; } /** Outcome of the ratchet comparison. */ export type RatchetOutcome = 'improved' | 'regressed' | 'budget-expired' | 'unchanged'; /** * Full ratchet execution result. * AC-26.5: Written to Stage Record and Ledger evidence chain. */ export interface RatchetResult { /** Work-package ID this ratchet applies to. */ workPackageId: string; /** Baseline snapshot. */ baseline: BaselineSnapshot; /** Post-optimization metric value (null if evaluator failed). */ optimizedValue: number | null; /** Whether changes were kept or rolled back. */ outcome: RatchetOutcome; /** Whether a git reset was performed. */ rolledBack: boolean; /** Reason for rollback (when applicable). */ rollbackReason?: string; /** SHA that was rolled back to (when applicable). */ rollbackTargetSha?: string; /** Summary of discarded changes (when rolled back). */ discardedChangesSummary?: string; /** Execution duration in milliseconds. */ durationMs: number; /** Timestamp of ratchet evaluation. */ evaluatedAt: string; } /** * Audit event emitted before a git reset. * AC-26.8: Must be recorded before the destructive operation. */ export interface RatchetAuditEvent { type: 'ratchet-rollback'; workPackageId: string; baselineSha: string; currentSha: string; baselineValue: number; optimizedValue: number | null; reason: string; discardedChangesSummary: string; timestamp: string; } /** * Persisted ratchet state for a project. * Stored in `/.sevo/ratchet-state.json`. */ export interface RatchetState { /** Historical best scores per work-package per metric. */ highScores: Record>; /** Baseline snapshots for active ratchet sessions. */ activeBaselines: Record; /** Completed ratchet results (append-only log). */ history: RatchetResult[]; /** Last updated timestamp. */ updatedAt: string; } /** * Load ratchet registry from project config. * Returns empty registry if not configured (AC-26.6: no side effects when disabled). */ export declare function loadRatchetRegistry(projectRoot: string): RatchetRegistry; /** * Check if ratchet is enabled for a given work-package. * AC-26.6: Returns false when not configured → no impact on normal flow. */ export declare function isRatchetEnabled(registry: RatchetRegistry, workPackageId: string): boolean; /** * Load persisted ratchet state from disk. */ export declare function loadRatchetState(projectRoot: string): RatchetState; /** * Persist ratchet state to disk. */ export declare function saveRatchetState(projectRoot: string, state: RatchetState): void; /** * Get the current git HEAD SHA for a project. */ export declare function getCurrentGitSha(projectRoot: string): string; /** * Capture a baseline snapshot before optimization begins. * AC-26.2: Records git commit SHA + metric value. */ export declare function captureBaseline(projectRoot: string, workPackageId: string, config: RatchetConfig): BaselineSnapshot; /** * Determine if the optimized value is an improvement over baseline. * AC-26.7: Uses numeric comparison, not LLM judgment. */ export declare function isImprovement(baselineValue: number, optimizedValue: number, higherIsBetter: boolean): boolean; /** * Determine if the optimized value is a regression from baseline. */ export declare function isRegression(baselineValue: number, optimizedValue: number, higherIsBetter: boolean): boolean; /** * Execute git reset --hard to baseline SHA. * AC-26.8: Audit event must be recorded BEFORE calling this function. */ export declare function executeRollback(projectRoot: string, targetSha: string): void; /** * Create an audit event for a rollback operation. * AC-26.8: Recorded before the destructive git reset. */ export declare function createRollbackAuditEvent(workPackageId: string, baseline: BaselineSnapshot, currentSha: string, optimizedValue: number | null, reason: string, discardedChangesSummary: string): RatchetAuditEvent; /** * Append an audit event to the project's ratchet audit log. */ export declare function appendAuditEvent(projectRoot: string, event: RatchetAuditEvent): void; /** * Convert a RatchetResult into an ArtifactRef for Ledger evidence chain. * AC-26.5: Ratchet results are part of the evidence chain. */ export declare function ratchetResultToArtifact(projectRoot: string, result: RatchetResult): ArtifactRef; export interface RatchetEvaluateOptions { /** Project root directory. */ projectRoot: string; /** Work-package ID to evaluate. */ workPackageId: string; /** Evaluator result from FR-23 executable evaluator. AC-26.7: score source. */ evaluatorResult: EvaluatorResult; /** Whether the time budget was exhausted. */ timeBudgetExhausted?: boolean; } /** * Evaluate ratchet for a work-package after optimization attempt. * * Flow: * 1. Load baseline snapshot and ratchet config. * 2. Compare evaluator score against baseline (AC-26.7). * 3. If improved → keep changes, update high score. * 4. If regressed or budget expired → record audit event (AC-26.8), then git reset (AC-26.3). * 5. Persist result to state and return for Stage Record inclusion (AC-26.5). */ export declare function evaluateRatchet(options: RatchetEvaluateOptions): RatchetResult; /** * Get the historical high score for a work-package metric. * Used by gate checks to enforce the ratchet: new scores must meet or exceed this. */ export declare function getHighScore(projectRoot: string, workPackageId: string, metricName: string): number | undefined; /** * Check if a new score meets the ratchet threshold (does not regress from historical high). * Returns true if the score is acceptable (equal or better than high score). */ export declare function meetsRatchetThreshold(projectRoot: string, workPackageId: string, metricName: string, newScore: number, higherIsBetter: boolean): boolean; //# sourceMappingURL=ratchet.d.ts.map