Change proposals
An agent can prepare several configuration changes and give you one page to review them. Each item shows the current setting, proposed value, explanation, and when the change takes effect. Submitting a proposal changes no app settings.
Open your app's Proposals section to see pending requests and decision history. Select the items you want and choose Approve selected or Decline selected. Unselected items stay pending. You can approve a deployment-policy change and leave a public-path change for someone else. Developers can approve deployment policy. Administrators can also approve access mode and public paths, matching the permissions for editing those settings manually.
Approval saves configuration. Public paths and access mode take effect on each affected branch's next deployment. Deployment-policy changes affect future deployment triggers. Approval does not start a deployment. If settings change while you review, refresh the page and review the new diff.
Submit a batch through the CLI
Use this for changes to an existing app that need review now. Write changes.json:
{
"title": "Allow Stripe webhook delivery",
"items": [
{
"id": "stripe-webhook",
"type": "public_path.add",
"value": { "path": "/webhooks/stripe" },
"reason": "Stripe must reach this endpoint. The handler verifies Stripe signatures."
}
]
}
apphaven proposals create my-app --file changes.json --open
apphaven proposals list my-app
apphaven proposals list my-app --source manifest --status all
apphaven proposals show my-app <proposal-id> --json
apphaven proposals open my-app <proposal-id>
The CLI returns a proposal ID and review URL. --open opens that page for the human reviewer.
If opening the browser fails, the proposal is still stored and you can open the printed URL.
Use --file - to read JSON from stdin, --project to select a project, and --json for structured
output. A successful create means submitted, not approved. Read each item's outcome in show;
a closed batch may contain both approved and declined items.
The CLI generates a request ID, saves a small receipt locally, and prints the ID before sending. After a timeout or lost response, reuse that ID with the same file and app:
apphaven proposals create my-app --file changes.json --request-id <printed-request-id> --open
The retry returns the original proposal. Changed content requires a new request ID. Running
create without --request-id generates a new one, so do not use that as an uncertain retry.
If the CLI reports INSUFFICIENT_SCOPE, run apphaven login to authorize proposal submission.
Existing read access keeps working until you approve the expanded grant.
Recommendations that travel with the repository
Use the optional proposals section alongside your workload in apphaven.yaml:
proposals:
- id: stripe-webhook
type: public_path.add
value:
path: /webhooks/stripe
reason: Stripe must reach this endpoint. The handler verifies Stripe signatures.
- id: branch-previews
type: deploy_policy.set
value:
policy: PRODUCTION_AND_PREVIEWS
previewBranchPattern: preview/*
maxPreviewDeployments: 3
reason: Test preview branches before merging them into production.
AppHaven imports recommendations only from the configured production branch, usually main.
It checks when the repository is connected and on subsequent production changes, including when
automatic deployment is off. A feature-branch edit appears for review after merging into production.
A local clone carries the recommendations; connecting it to an app starts their import.
Keep an item's id when editing it. IDs start with a lowercase letter and contain lowercase letters,
digits, underscores or hyphens, up to 64 characters. They must be unique in the file.
| Change to a recommendation | Result |
|---|---|
| Same ID and value, reordered or reformatted | No new request. |
| Only the explanation changes | Updated explanation; previous decisions are kept. |
| Same ID, different operation or value | New version for review; previous configuration stays in place. |
| Item removed | Pending item withdrawn; accepted settings remain. |
| Previously accepted or declined version returns | Existing decision remembered; no repeat request. |
| User changes an accepted setting manually | The unchanged manifest does not restore it. |
For example, you decline stripe-webhook for /webhooks/stripe. An explanation-only edit does
not ask again. Changing the path proposes a new version. Reverting to /webhooks/stripe keeps the
original decline. Do not rename IDs to repeat a rejected request. An authorized user can explicitly
request reconsideration in the console.
Run apphaven validate before committing. Invalid recommendations appear as import errors and
validation errors, but do not block an otherwise valid workload from deploying. Recommendations
never change settings by themselves. Existing workload fields keep their normal deployment behavior.
Supported changes
| Type | Value | Approval permission |
|---|---|---|
public_path.add | {"path":"/webhooks/stripe"} | Administrator |
public_path.remove | {"path":"/webhooks/stripe"} | Administrator |
access_mode.set | {"mode":"PRIVATE"} | Administrator |
deploy_policy.set | {"policy":"PRODUCTION_AND_PREVIEWS","previewBranchPattern":"preview/*","maxPreviewDeployments":3} | Developer |
Access modes are PRIVATE, PUBLIC (public production, private previews), and PUBLIC_PREVIEWS
(public production and previews). Deployment policies are NONE, PRODUCTION, and
PRODUCTION_AND_PREVIEWS. Supply both preview fields when enabling previews; for other policies,
omitting both preserves the saved preview settings. Preview cap: 0 to 50; pattern: 1 to 200 characters.
Every item needs a reason of 1 to 1000 characters. A CLI batch has 1 to 50 items and a title of 1 to 160 characters; its JSON body can be up to 256 KiB. A manifest can carry up to 50 recommendations. An app can have 100 pending batches. The existing limit of 10 active public paths still applies. Do not include credentials or secrets in explanations or values.
Public paths use an exact path or a trailing /* and can contain up to 128 characters. They expose
requests without an AppHaven login, so the explanation should say how your app authenticates callers.
See public paths for the complete matching rules.
Withdraw a mistaken request
apphaven proposals withdraw my-app <proposal-id>
apphaven proposals withdraw my-app <proposal-id> --item stripe-webhook
The first command cancels all remaining pending items. To cancel only some, pass the id you gave
each item in the batch file with --item, once per item.
A CLI token can withdraw only CLI batches submitted by the same account. It cannot withdraw repository
recommendations or another account's batches, even when the account is an administrator.
In the console you can cancel your own CLI submissions. Cancelling repository recommendations or another account's requests requires permission to edit the proposed setting. Explicitly withdrawn manifest versions stay withdrawn across later imports; a changed value can create a new version. Withdrawal never undoes approved configuration. Agents must leave approval to the human reviewer.