# `GEPA.CandidateProposal`
[🔗](https://github.com/nshkrdotcom/gepa_ex/blob/v0.3.0/lib/gepa/candidate_proposal.ex#L21)

A proposed new candidate program with metadata for acceptance testing.

A proposal contains the new candidate program along with information about
its parents and subsample evaluation results that can be used to decide
whether to accept the proposal.

## Fields

- `candidate`: The new program as a map of component name -> text
- `parent_program_ids`: List of parent program indices (1 for mutation, 2+ for merge)
- `subsample_indices`: Data IDs used for subsample evaluation
- `subsample_scores_before`: Parent scores on subsample
- `subsample_scores_after`: New candidate scores on subsample
- `eval_before`: Rich parent minibatch evaluation data
- `eval_after`: Rich proposed-candidate minibatch evaluation data
- `tag`: Proposal type identifier ("reflective_mutation", "merge", etc.)
- `metadata`: Additional proposal-specific data

# `t`

```elixir
@type t() :: %GEPA.CandidateProposal{
  candidate: GEPA.Types.candidate(),
  eval_after: GEPA.CandidateProposal.SubsampleEvaluation.t() | nil,
  eval_before: GEPA.CandidateProposal.SubsampleEvaluation.t() | nil,
  metadata: map(),
  parent_program_ids: [GEPA.Types.program_idx()],
  subsample_indices: [GEPA.Types.data_id()] | nil,
  subsample_scores_after: [float()] | nil,
  subsample_scores_before: [float()] | nil,
  tag: String.t()
}
```

# `should_accept?`

```elixir
@spec should_accept?(t()) :: boolean()
```

Check if proposal should be accepted.

The default acceptance criterion is strict improvement:
`sum(new_scores) > sum(old_scores)`.

## Examples

    iex> proposal = %GEPA.CandidateProposal{
    ...>   candidate: %{},
    ...>   parent_program_ids: [0],
    ...>   tag: "test",
    ...>   subsample_scores_before: [0.5, 0.6],
    ...>   subsample_scores_after: [0.7, 0.8]
    ...> }
    iex> GEPA.CandidateProposal.should_accept?(proposal)
    true

    iex> proposal = %GEPA.CandidateProposal{
    ...>   candidate: %{},
    ...>   parent_program_ids: [0],
    ...>   tag: "test",
    ...>   subsample_scores_before: [0.9],
    ...>   subsample_scores_after: [0.8]
    ...> }
    iex> GEPA.CandidateProposal.should_accept?(proposal)
    false

# `should_accept?`

```elixir
@spec should_accept?(
  t(),
  GEPA.Strategies.Acceptance.criterion() | nil,
  GEPA.State.t() | nil
) ::
  boolean()
```

Check if proposal should be accepted using a configurable criterion.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
