# client.proposals

> client.proposals — the proposals operations.

`client.proposals` — the `proposals` operations.

On `AsyncKindgi` every method is the same, awaited.

## `client.proposals.list()`

```python signature
list(
    *,
    limit: int | None = None,
    cursor: str | None = None,
    status: Literal['draft', 'evaluating', 'evaluated', 'not-better', 'evaluation-failed', 'in-review', 'promoted', 'refused', 'rejected', 'expired', 'superseded', 'rolled-back', 'withdrawn'] | None = None,
    agent_id: str | UUID | None = None,
    tier: Literal['settings-block', 'prompt-block'] | None = None,
    scope_kind: Literal['tenant', 'org', 'project', 'segment'] | None = None,
    scope_id: str | UUID | None = None,
    segments: Sequence[ScopeSegment | Mapping[str, str]] | None = None,
    timeout: float | None = None,
) -> FixProposalCollectionPage
```

List improvement proposals. `GET /v1/proposals`

Newest first, cursor-paginated, only the proposals of agents the caller can read. Filters: `?agentId=`, `?tier=`, `?status=` (statuses are derived, so a page filtered by status can hold fewer rows than `limit`), and the live scope a proposal is for (`scopeKind`, `scopeId`, `segment`, exactly as the promotions history takes it).

## `client.proposals.create()`

```python signature
create(
    body: CreateProposalBody | Mapping[str, Any] | None = None,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    **fields: Any,
) -> FixProposal
```

Propose new content for a data block. `POST /v1/proposals`

A hand-written proposal: new settings values or a new prompt template for a block `fromVersion` pins, for a live scope. Checked as publishing that block version would be (its schema carries over), and refused when it equals the pinned content. The same change from the same version for the same scope is one proposal: answered `200` with `X-Proposal-Deduped: true`. Needs `publish` on the agent.

## `client.proposals.improve()`

```python signature
improve(
    body: ImproveBody | Mapping[str, Any] | None = None,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    **fields: Any,
) -> ImprovementPass
```

Start an improvement pass. `POST /v1/proposals/improve`

The runtime looks for better values for the version's tunable settings (keys its settings blocks' schemas mark `x-kindgi-tunable`) on the test set, within the budget, and writes its best candidate as an improvement proposal, which waits for a reviewer when requested. It answers at once with the pass, `running`. Checked first: the version is active and pins a settings block with tunable keys (`400 validation-failed`), the agent registry takes writes (`409 registry-read-only`), and the agent has a live version for the whole tenant (`409 proposal-needs-pin`). Needs `publish` on the agent. Without improvement passes in this runtime, `501 improve-unsupported`.

## `client.proposals.get()`

```python signature
get(proposal_id: str | UUID, /, *, timeout: float | None = None) -> FixProposal
```

Fetch an improvement proposal. `GET /v1/proposals/{proposalId}`

Needs `read` on its agent.

## `client.proposals.evaluate()`

```python signature
evaluate(
    proposal_id: str | UUID,
    body: EvaluateProposalBody | Mapping[str, Any] | None = None,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    **fields: Any,
) -> FixProposal
```

Compare a proposal on a test set. `POST /v1/proposals/{proposalId}/evaluate`

The first evaluation publishes the block version and derives the agent version (`derivedFrom.proposalId`); they serve no scope until a promotion makes them live. Then a comparison eval run replays that version on the test set, against the recorded outputs (`baseline: 'recorded'`). Needs `publish` on the agent, and a live version of it for the whole tenant: an agent with none serves its latest version wherever nothing is pinned, so a new version would go live there at once (`409 proposal-needs-pin`). Allowed from `draft`, `evaluated`, `not-better`, `evaluation-failed`, `refused`, `superseded` and `expired`.

## `client.proposals.rescore()`

```python signature
rescore(
    proposal_id: str | UUID,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
) -> FixProposal
```

Rescore a proposal's latest evaluation. `POST /v1/proposals/{proposalId}/rescore`

After people judge a comparison's new answers on its replay runs (`perCase[].changes.new`, `runIds`), a new comparison eval run scores the same replays again, counting those judgments, as `POST /v1/eval-runs/{runId}/rescore` does: same test set version and settings, `comparison.rescoreOf`, nothing replayed. It becomes the proposal's evaluation, so the proposal is `evaluating`, then `evaluated` or `not-better` as the rescore says; the run rescored stays as it was. Takes no body fields. Needs `publish` on the agent. Allowed from `evaluated`, `not-better`, `refused`, `superseded` and `expired`.

## `client.proposals.request()`

```python signature
request(
    proposal_id: str | UUID,
    body: ProposalReasonBody | Mapping[str, Any] | None = None,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    **fields: Any,
) -> FixProposal
```

Request a proposal's promotion for its scope. `POST /v1/proposals/{proposalId}/request`

A promotion of the candidate for the proposal's scope, with its evaluation's comparison, through the scope's gate: as `POST /v1/agents/{agentId}/promotions` answers. Needs `promote` on the agent. Allowed from `evaluated`, `not-better` (the gate decides), `refused`, `superseded` and `expired`.

## `client.proposals.rollback()`

```python signature
rollback(
    proposal_id: str | UUID,
    body: ProposalReasonBody | Mapping[str, Any] | None = None,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    **fields: Any,
) -> FixProposal
```

Roll back a promoted proposal. `POST /v1/proposals/{proposalId}/rollback`

The scope goes back to the version its own pin held before the proposal's promotion (or, with none, falls back to the scope above). Only while the proposal's version still serves the scope. Needs `promote` on the agent.

## `client.proposals.withdraw()`

```python signature
withdraw(
    proposal_id: str | UUID,
    body: WithdrawProposalBody | Mapping[str, Any] | None = None,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    **fields: Any,
) -> FixProposal
```

Withdraw a proposal. `POST /v1/proposals/{proposalId}/withdraw`

Closes it. Not while it's in review (decide its approval instead), nor once promoted, rejected or rolled back. Needs `publish` on the agent.

## `client.proposals.draft()`

```python signature
draft(*args: Any, **kwargs: Any) -> NoReturn
```

Removed in 0.1.5: use `client.proposals.create`.

## `client.proposals.dry_run()`

```python signature
dry_run(*args: Any, **kwargs: Any) -> NoReturn
```

Removed in 0.1.5: use `client.proposals.evaluate`.

## `client.proposals.submit_review()`

```python signature
submit_review(*args: Any, **kwargs: Any) -> NoReturn
```

Removed in 0.1.5: use `client.proposals.request`.

## `client.proposals.apply()`

```python signature
apply(*args: Any, **kwargs: Any) -> NoReturn
```

Removed in 0.1.5: use `client.proposals.request`.
