# Class PersistentOutcomeStore

OutcomeStore that persists entries to a JSONL file on disk.

- Construction: hydrates from existing JSONL file (Zod-validates each line)
- Append: calls super.append() then appendFileSync one JSON line
- Corruption: bad lines are skipped with a warning log

#### Hierarchy (View Summary)

- OutcomeStore
  - PersistentOutcomeStore

- Defined in packages/nexus-agents/src/orchestration/outcomes/outcome-store-persistence.ts:44

##### Index

### Constructors

constructor

### Accessors

size

### Methods

append
query
queryByModelWithFamilyFallback
summarize
clear
reclassifyAll
purgeSkippedWorkers

## Constructors

### constructor

- new PersistentOutcomeStore(
  config?: PersistentOutcomeStoreConfig,
  logger?: ILogger,
  ): PersistentOutcomeStore

  #### Parameters

  - `Optional` config: PersistentOutcomeStoreConfig
  - `Optional` logger: ILogger

  #### Returns PersistentOutcomeStore

  Overrides OutcomeStore.constructor

  - Defined in packages/nexus-agents/src/orchestration/outcomes/outcome-store-persistence.ts:48

## Accessors

### size

- get size(): number

  Number of stored outcomes.

  #### Returns number

  Inherited from OutcomeStore.size

  - Defined in packages/nexus-agents/src/orchestration/outcomes/outcome-store.ts:182

## Methods

### append

- append(
  outcome: {
  id: string;
  cli: "claude" | "gemini" | "codex" | "opencode";
  category:
  | "planning"
  | "code_generation"
  | "code_review"
  | "research"
  | "architecture"
  | "security_review"
  | "documentation"
  | "testing"
  | "devops"
  | "exploration";
  model: string;
  success: boolean;
  durationMs: number;
  timestamp: string;
  qualitySignals?: string[];
  failureCategory?: | "unknown"
  | "timeout"
  | "parse"
  | "connection"
  | "execution"
  | "rate_limit"
  | "validation"
  | "authentication"
  | "generic"
  | "crash"
  | "adapter_unavailable";
  errorMessage?: string;
  source: "delegate"
  | "consensus"
  | "manual";
  wasRetried?: boolean;
  triageAction?: string;
  routingStage?: string;
  retryCount?: number;
  vendor?: string;
  family?: string;
  voterRole?: string;
  baselineId?: string;
  },
  ): void

  Override append to persist each entry to disk.

  #### Parameters

  - outcome: {
    id: string;
    cli: "claude" | "gemini" | "codex" | "opencode";
    category:
    | "planning"
    | "code_generation"
    | "code_review"
    | "research"
    | "architecture"
    | "security_review"
    | "documentation"
    | "testing"
    | "devops"
    | "exploration";
    model: string;
    success: boolean;
    durationMs: number;
    timestamp: string;
    qualitySignals?: string[];
    failureCategory?: | "unknown"
    | "timeout"
    | "parse"
    | "connection"
    | "execution"
    | "rate_limit"
    | "validation"
    | "authentication"
    | "generic"
    | "crash"
    | "adapter_unavailable";
    errorMessage?: string;
    source: "delegate"
    | "consensus"
    | "manual";
    wasRetried?: boolean;
    triageAction?: string;
    routingStage?: string;
    retryCount?: number;
    vendor?: string;
    family?: string;
    voterRole?: string;
    baselineId?: string;
    }

    - ##### id: string

    - ##### cli: "claude" | "gemini" | "codex" | "opencode"

    - ##### category:
      | "planning"
      | "code_generation"
      | "code_review"
      | "research"
      | "architecture"
      | "security_review"
      | "documentation"
      | "testing"
      | "devops"
      | "exploration"

    - ##### model: string

    - ##### success: boolean

    - ##### durationMs: number

    - ##### timestamp: string

    - ##### `Optional` qualitySignals?: string[]

    - ##### `Optional` failureCategory?:
      | "unknown"
      | "timeout"
      | "parse"
      | "connection"
      | "execution"
      | "rate_limit"
      | "validation"
      | "authentication"
      | "generic"
      | "crash"
      | "adapter_unavailable"

    - ##### `Optional` errorMessage?: string

    - ##### source: "delegate" | "consensus" | "manual"

    - ##### `Optional` wasRetried?: boolean

      Whether this outcome came from a triage-initiated retry (#1506).

    - ##### `Optional` triageAction?: string

      Triage action taken on the failure (#1506).

    - ##### `Optional` routingStage?: string

      Routing stage that selected this CLI (#1785).

    - ##### `Optional` retryCount?: number

      Number of retry attempts before this outcome (#1785).

    - ##### `Optional` vendor?: string

      Vendor resolved from `model` via ModelRegistry at write time (#2548).

    - ##### `Optional` family?: string

      Family resolved from `model` via ModelRegistry at write time (#2548).

    - ##### `Optional` voterRole?: string

      Voter role for `source: 'consensus'` outcomes (#2662) — `architect`, `security`, etc. Absent on non-consensus outcomes. Lets the stratified outcome report break results down by voter role.

    - ##### `Optional` baselineId?: string

      Baseline this outcome forked from (#2697 / Epic F follow-up to #2665). Set on outcomes recorded inside a fork-then-merge graph branch so `query({ baselineId: 'B' })` returns every branch outcome forked from baseline B — letting later analysis compare branches as a cohort. Free-form string (caller-assigned); typically the parent node's `executionId` or `taskId`.

  #### Returns void

  Overrides OutcomeStore.append

  - Defined in packages/nexus-agents/src/orchestration/outcomes/outcome-store-persistence.ts:61

### query

- query(
  filter?: {
  cli?: "claude" | "gemini" | "codex" | "opencode";
  category?:
  | "planning"
  | "code_generation"
  | "code_review"
  | "research"
  | "architecture"
  | "security_review"
  | "documentation"
  | "testing"
  | "devops"
  | "exploration";
  source?: "delegate"
  | "consensus"
  | "manual";
  success?: boolean;
  failureCategory?:
  | "unknown"
  | "timeout"
  | "parse"
  | "connection"
  | "execution"
  | "rate_limit"
  | "validation"
  | "authentication"
  | "generic"
  | "crash"
  | "adapter_unavailable";
  since?: string;
  limit?: number;
  excludeQualitySignals?: string[];
  baselineId?: string;
  },
  ): readonly {
  id: string;
  cli: "claude"
  | "gemini"
  | "codex"
  | "opencode";
  category:
  | "planning"
  | "code_generation"
  | "code_review"
  | "research"
  | "architecture"
  | "security_review"
  | "documentation"
  | "testing"
  | "devops"
  | "exploration";
  model: string;
  success: boolean;
  durationMs: number;
  timestamp: string;
  qualitySignals?: string[];
  failureCategory?: | "unknown"
  | "timeout"
  | "parse"
  | "connection"
  | "execution"
  | "rate_limit"
  | "validation"
  | "authentication"
  | "generic"
  | "crash"
  | "adapter_unavailable";
  errorMessage?: string;
  source: "delegate"
  | "consensus"
  | "manual";
  wasRetried?: boolean;
  triageAction?: string;
  routingStage?: string;
  retryCount?: number;
  vendor?: string;
  family?: string;
  voterRole?: string;
  baselineId?: string;
  }[]

  Query outcomes with optional filters.

  #### Parameters

  - `Optional` filter: {
    cli?: "claude" | "gemini" | "codex" | "opencode";
    category?:
    | "planning"
    | "code_generation"
    | "code_review"
    | "research"
    | "architecture"
    | "security_review"
    | "documentation"
    | "testing"
    | "devops"
    | "exploration";
    source?: "delegate"
    | "consensus"
    | "manual";
    success?: boolean;
    failureCategory?:
    | "unknown"
    | "timeout"
    | "parse"
    | "connection"
    | "execution"
    | "rate_limit"
    | "validation"
    | "authentication"
    | "generic"
    | "crash"
    | "adapter_unavailable";
    since?: string;
    limit?: number;
    excludeQualitySignals?: string[];
    baselineId?: string;
    }

    - ##### `Optional` cli?: "claude" | "gemini" | "codex" | "opencode"

    - ##### `Optional` category?:
      | "planning"
      | "code_generation"
      | "code_review"
      | "research"
      | "architecture"
      | "security_review"
      | "documentation"
      | "testing"
      | "devops"
      | "exploration"

    - ##### `Optional` source?: "delegate" | "consensus" | "manual"

    - ##### `Optional` success?: boolean

    - ##### `Optional` failureCategory?:
      | "unknown"
      | "timeout"
      | "parse"
      | "connection"
      | "execution"
      | "rate_limit"
      | "validation"
      | "authentication"
      | "generic"
      | "crash"
      | "adapter_unavailable"

    - ##### `Optional` since?: string

    - ##### `Optional` limit?: number

    - ##### `Optional` excludeQualitySignals?: string[]

      Exclude outcomes with any of these quality signals (#1680).

    - ##### `Optional` baselineId?: string

      Restrict to outcomes recorded against a specific baseline (#2697).

  #### Returns readonly {
  id: string;
  cli: "claude" | "gemini" | "codex" | "opencode";
  category:
  | "planning"
  | "code_generation"
  | "code_review"
  | "research"
  | "architecture"
  | "security_review"
  | "documentation"
  | "testing"
  | "devops"
  | "exploration";
  model: string;
  success: boolean;
  durationMs: number;
  timestamp: string;
  qualitySignals?: string[];
  failureCategory?: | "unknown"
  | "timeout"
  | "parse"
  | "connection"
  | "execution"
  | "rate_limit"
  | "validation"
  | "authentication"
  | "generic"
  | "crash"
  | "adapter_unavailable";
  errorMessage?: string;
  source: "delegate"
  | "consensus"
  | "manual";
  wasRetried?: boolean;
  triageAction?: string;
  routingStage?: string;
  retryCount?: number;
  vendor?: string;
  family?: string;
  voterRole?: string;
  baselineId?: string;
  }[]

  Inherited from OutcomeStore.query

  - Defined in packages/nexus-agents/src/orchestration/outcomes/outcome-store.ts:105

### queryByModelWithFamilyFallback

- queryByModelWithFamilyFallback(
  modelId: string,
  options?: {
  threshold?: number;
  extraFilter?: Omit<
  {
  cli?: "claude"
  | "gemini"
  | "codex"
  | "opencode";
  category?:
  | "planning"
  | "code_generation"
  | "code_review"
  | "research"
  | "architecture"
  | "security_review"
  | "documentation"
  | "testing"
  | "devops"
  | "exploration";
  source?: "delegate"
  | "consensus"
  | "manual";
  success?: boolean;
  failureCategory?:
  | "unknown"
  | "timeout"
  | "parse"
  | "connection"
  | "execution"
  | "rate_limit"
  | "validation"
  | "authentication"
  | "generic"
  | "crash"
  | "adapter_unavailable";
  since?: string;
  limit?: number;
  excludeQualitySignals?: string[];
  baselineId?: string;
  },
  "limit",
  >;
  },
  ): {
  outcomes: readonly {
  id: string;
  cli: "claude"
  | "gemini"
  | "codex"
  | "opencode";
  category:
  | "planning"
  | "code_generation"
  | "code_review"
  | "research"
  | "architecture"
  | "security_review"
  | "documentation"
  | "testing"
  | "devops"
  | "exploration";
  model: string;
  success: boolean;
  durationMs: number;
  timestamp: string;
  qualitySignals?: string[];
  failureCategory?: | "unknown"
  | "timeout"
  | "parse"
  | "connection"
  | "execution"
  | "rate_limit"
  | "validation"
  | "authentication"
  | "generic"
  | "crash"
  | "adapter_unavailable";
  errorMessage?: string;
  source: "delegate"
  | "consensus"
  | "manual";
  wasRetried?: boolean;
  triageAction?: string;
  routingStage?: string;
  retryCount?: number;
  vendor?: string;
  family?: string;
  voterRole?: string;
  baselineId?: string;
  }[];
  scope: "literal"
  | "empty"
  | "family";
  vendor?: string;
  family?: string;
  }

  Query outcomes for a specific model with a family-level warm-start fallback (#2548). When the literal `modelId` has fewer than `threshold` samples in the store, broaden the result to the model's `{vendor, family}` siblings — siblings within a family share enough behavior profile that their outcomes are useful priors for cold starts after a retirement.

  Returns the outcomes and a `scope` flag so callers know whether they're consuming literal-id data or family-broadened data.

  #### Parameters

  - modelId: string
  - `Optional` options: {
    threshold?: number;
    extraFilter?: Omit<
    {
    cli?: "claude"
    | "gemini"
    | "codex"
    | "opencode";
    category?:
    | "planning"
    | "code_generation"
    | "code_review"
    | "research"
    | "architecture"
    | "security_review"
    | "documentation"
    | "testing"
    | "devops"
    | "exploration";
    source?: "delegate"
    | "consensus"
    | "manual";
    success?: boolean;
    failureCategory?:
    | "unknown"
    | "timeout"
    | "parse"
    | "connection"
    | "execution"
    | "rate_limit"
    | "validation"
    | "authentication"
    | "generic"
    | "crash"
    | "adapter_unavailable";
    since?: string;
    limit?: number;
    excludeQualitySignals?: string[];
    baselineId?: string;
    },
    "limit",
    >;
    }

  #### Returns {
  outcomes: readonly {
  id: string;
  cli: "claude" | "gemini" | "codex" | "opencode";
  category:
  | "planning"
  | "code_generation"
  | "code_review"
  | "research"
  | "architecture"
  | "security_review"
  | "documentation"
  | "testing"
  | "devops"
  | "exploration";
  model: string;
  success: boolean;
  durationMs: number;
  timestamp: string;
  qualitySignals?: string[];
  failureCategory?: | "unknown"
  | "timeout"
  | "parse"
  | "connection"
  | "execution"
  | "rate_limit"
  | "validation"
  | "authentication"
  | "generic"
  | "crash"
  | "adapter_unavailable";
  errorMessage?: string;
  source: "delegate"
  | "consensus"
  | "manual";
  wasRetried?: boolean;
  triageAction?: string;
  routingStage?: string;
  retryCount?: number;
  vendor?: string;
  family?: string;
  voterRole?: string;
  baselineId?: string;
  }[];
  scope: "literal"
  | "empty"
  | "family";
  vendor?: string;
  family?: string;
  }

  Inherited from OutcomeStore.queryByModelWithFamilyFallback

  - Defined in packages/nexus-agents/src/orchestration/outcomes/outcome-store.ts:122

### summarize

- summarize(
  filter?: {
  cli?: "claude" | "gemini" | "codex" | "opencode";
  category?:
  | "planning"
  | "code_generation"
  | "code_review"
  | "research"
  | "architecture"
  | "security_review"
  | "documentation"
  | "testing"
  | "devops"
  | "exploration";
  source?: "delegate"
  | "consensus"
  | "manual";
  success?: boolean;
  failureCategory?:
  | "unknown"
  | "timeout"
  | "parse"
  | "connection"
  | "execution"
  | "rate_limit"
  | "validation"
  | "authentication"
  | "generic"
  | "crash"
  | "adapter_unavailable";
  since?: string;
  limit?: number;
  excludeQualitySignals?: string[];
  baselineId?: string;
  },
  ): PerformanceSummary

  Aggregate outcomes into a performance summary.

  #### Parameters

  - `Optional` filter: {
    cli?: "claude" | "gemini" | "codex" | "opencode";
    category?:
    | "planning"
    | "code_generation"
    | "code_review"
    | "research"
    | "architecture"
    | "security_review"
    | "documentation"
    | "testing"
    | "devops"
    | "exploration";
    source?: "delegate"
    | "consensus"
    | "manual";
    success?: boolean;
    failureCategory?:
    | "unknown"
    | "timeout"
    | "parse"
    | "connection"
    | "execution"
    | "rate_limit"
    | "validation"
    | "authentication"
    | "generic"
    | "crash"
    | "adapter_unavailable";
    since?: string;
    limit?: number;
    excludeQualitySignals?: string[];
    baselineId?: string;
    }

    - ##### `Optional` cli?: "claude" | "gemini" | "codex" | "opencode"

    - ##### `Optional` category?:
      | "planning"
      | "code_generation"
      | "code_review"
      | "research"
      | "architecture"
      | "security_review"
      | "documentation"
      | "testing"
      | "devops"
      | "exploration"

    - ##### `Optional` source?: "delegate" | "consensus" | "manual"

    - ##### `Optional` success?: boolean

    - ##### `Optional` failureCategory?:
      | "unknown"
      | "timeout"
      | "parse"
      | "connection"
      | "execution"
      | "rate_limit"
      | "validation"
      | "authentication"
      | "generic"
      | "crash"
      | "adapter_unavailable"

    - ##### `Optional` since?: string

    - ##### `Optional` limit?: number

    - ##### `Optional` excludeQualitySignals?: string[]

      Exclude outcomes with any of these quality signals (#1680).

    - ##### `Optional` baselineId?: string

      Restrict to outcomes recorded against a specific baseline (#2697).

  #### Returns PerformanceSummary

  Inherited from OutcomeStore.summarize

  - Defined in packages/nexus-agents/src/orchestration/outcomes/outcome-store.ts:156

### clear

- clear(): void

  Remove all stored outcomes.

  #### Returns void

  Inherited from OutcomeStore.clear

  - Defined in packages/nexus-agents/src/orchestration/outcomes/outcome-store.ts:187

### reclassifyAll

- reclassifyAll(): number

  Backfill: reclassify all entries missing failureCategory (#1444). Also reclassifies 'unknown' entries with no error message as 'execution' (#1511) since 'unknown' with no diagnostic info is less useful than the default 'execution' category. Returns count of reclassified entries.

  #### Returns number

  Inherited from OutcomeStore.reclassifyAll

  - Defined in packages/nexus-agents/src/orchestration/outcomes/outcome-store.ts:198

### purgeSkippedWorkers

- purgeSkippedWorkers(): number

  Purge false failures with zero execution time (#1528). Removes non-success entries with durationMs=0 — these are either:

  - Skipped workers (circuit breaker, role auto-disable)
  - Test-generated entries (E2E eval artifacts)
  - Pre-execution short-circuits (validation, initialization) Real model execution always takes >0ms. Returns count of purged entries.

  #### Returns number

  Inherited from OutcomeStore.purgeSkippedWorkers

  - Defined in packages/nexus-agents/src/orchestration/outcomes/outcome-store.ts:236