# Delivery policy

**A project's delivery policy bounds how far it runs without a person.** hlix is autonomous: a project plans, builds, reviews and delivers without waiting for anyone. Two controls bound it, and each answers a different question.

| Control | Question it answers |
| --- | --- |
| Budgets | How much may this project spend, how often may it re-plan, and how much work may it open? |
| Client deployment | Does a customer's sign-off ship the code? |

The decision a person holds comes at the end of a project, not before each cycle: a repository-backed project finishes with one pull request from its preview branch into your default branch, which hlix opens and never merges. See [Review & QA gates](/concepts/review-gates/#the-one-human-decision).

## Prerequisites

- A project in your Workspace.
- `manage` access on the project. Every write here refuses a client collaborator, including one with steer access.

## Budgets

Three ceilings, set on the project. A project that sets none runs with the defaults below.

| Field | Range | Default | What it bounds |
| --- | --- | --- | --- |
| `costCapUsd` | Above `0`, up to `1000000` | `25` | Total spend for the project. At the cap the project **pauses**; raising the cap resumes it |
| `maxRevisions` | `2` to `100` | `5` | How many re-plans may pass without a newly completed cycle before the planner changes strategy |
| `cycleCap` | `1` to `500` | `30` | How many open cycles a re-plan may add |

```bash
curl -sS -X PATCH "$HLIX_BASE_URL/v1/api/projects/$PROJECT_ID" \
  -H "x-api-key: $HLIX_API_KEY" \
  -H "X-Organization-Id: $HLIX_WORKSPACE_ID" \
  -H 'content-type: application/json' \
  -d '{"costCapUsd":250,"maxRevisions":4,"cycleCap":20}'
```

Expected result: `200` and the updated project. Send `null` for any field to return it to the default.

None of these ceilings fails a project. A project reaching its cost cap waits until you raise it; the other two shape how the project manager plans. hlix checks them on every pass, so a raised cap takes effect without any further action.

**The minimum for `maxRevisions` is 2:** The initial plan counts as the first pass, so `2` is the smallest value that allows a re-plan.

Budgets apply to one project. They are separate from the Workspace's own spend limits, which apply across every project.

## Client deployment

Off by default. It answers one question: when a customer approves a deliverable in the client portal, does that approval **deploy**, or is it a sign-off the agency then acts on?

```bash
curl -sS -X PUT "$HLIX_BASE_URL/v1/api/projects/$PROJECT_ID/delivery-policy" \
  -H "x-api-key: $HLIX_API_KEY" \
  -H "X-Organization-Id: $HLIX_WORKSPACE_ID" \
  -H 'content-type: application/json' \
  -d '{"deployOnClientApproval":true}'
```

Expected result: `200` and the stored policy.

Read it back with `GET /v1/api/projects/{projectId}/delivery-policy`. A project that never configured one answers `{"projectId": …, "deployOnClientApproval": false}`.

Both requests are **agency-only**, including for a client collaborator with steer access: whether a customer's sign-off ships code is a decision about the agency's own process. Turning it on is recorded in the [audit log](/security/audit-log/) as `deliverable.deploy_policy_changed`, at warning severity.

## If a policy does not behave as expected

- **`{"error":"Project not found"}` with `404`.** The project is not in the Workspace named by `X-Organization-Id`.
- **`{"error":"Failed to save the delivery policy"}` with `500`.** The write did not persist. Read it back before assuming it took effect.
- **A `400` on `maxRevisions`.** The minimum is `2`.
- **A `400` on an unknown field.** The project update is strict: a field it does not apply is rejected, so a `200` always means the change happened.
- **A `400` on `requiresApproval`.** That is not a setting. No cycle waits for a person; the end-of-project pull request is the decision you hold.
- **The project paused.** It reached `costCapUsd`. Work already running finishes; raise the cap to continue.
- **A customer approved and nothing deployed.** `deployOnClientApproval` is off, which is the default. The approval is recorded; the deployment is the agency's to make.
- **A `403` on any of these.** They need `manage` access on the project.

## Where to go next

| If you want to… | Read |
| --- | --- |
| See what is in the request queue | [Approvals](/running/approvals/) |
| Understand risk lanes | [Triage](/concepts/triage/) |
| See what a cycle cost | [Delivery metrics](/running/metrics/) |
| Control what may create work at all | [Work intake](/configure/work-intake/) |

## Next steps

[Approvals](/running/approvals/)
  [Review & QA gates](/concepts/review-gates/)
  [Work intake](/configure/work-intake/)
  [Delivery metrics](/running/metrics/)