# change-server-quote

Owner-only and free, through `daski_use_asset`. Quotes a new CPU/RAM allocation and/or rental term. Saving the quote grants no capacity, time, control or deletion hold, and expires after a short window. While a change or reset of the server is still running the quote is refused with `operation_in_progress`; quote again once `get-server` shows it finished.

## Input

| Field | Required | Notes |
|---|---|---|
| `serverId` | yes | A running, stopped or retained (expired) server you own. |
| `vcpu`, `ramGiB` | yes | Minimums for the new allocation; send the current values for a term-only change. |
| `storageGiB` | yes | Must equal the current disk size. |
| `adjustTime` | yes | `true`: convert unused value into time at the new rate and pay nothing (omit `hours`). `false`: request a total remaining term. |
| `hours` | when `adjustTime` is false | The desired total remaining term at quotation, 1-720 — not additional hours. |

## Accounting

```text
unused value = credit left now at the current rate
target cost  = hours × new hourly rate
amount due   = adjustTime ? 0 : max(0, target cost − unused value), raised to at least the minimum change payment,
               then rounded up to the next whole cent (0.01 USDC)
time         = (unused value + amount due) / new hourly rate, at most 720 hours
```

All amounts are atomic USDC. The unused value stays exact; only the amount due is rounded. Every rounded-up unit becomes credit (extra time), except that the cent rounding never takes the term past 720 hours: a request for exactly 720 hours is accepted and the fraction above the cap is not credited. All remaining credit converts at the new rate when the change applies, even if only the term changes. A result above 720 remaining hours is refused without discarding value; wait until some time is used. Time keeps running while you decide; `minimumRemainingSeconds` is the least time the change will still accept, checked before the change touches the server. From then on, any stop or start the change needs pauses paid time, so the delivered result is at least that minimum.

## Result artifact — `change_quote`

`changeQuoteId`, `current` and `proposed` allocation and rate, `unusedValue`, `amountDue`, `estimatedRemainingSeconds`, `estimatedPaidThrough`, `minimumRemainingSeconds`, `expiresAt`, and `execution`:

```jsonc
{ "route": "purchase", "skillId": "change-server",
  "input": { "serverId": "srv-…", "changeQuoteId": "hcq_…", "minimumRemainingSeconds": 35100 },
  "payerAddress": "0x… (the owner wallet; null for the free route)" }
```

`route: purchase` means buy `change-server` with exactly that input from `payerAddress`. `route: asset-action` means run it free through `daski_use_asset`.
