[ 'test' => 'Test mode', 'live' => 'Live mode', ], 'billing' => [ 'stripe_secret' => 'Stripe key (:mode)', 'stripe_secret_breaks' => 'Without it the checkout accepts no order at all — no order is ever created.', 'webhook_secret' => 'Stripe signing secret', 'webhook_secret_breaks' => 'Without it a payment is never recorded: the customer pays, and nothing happens.', 'company_details' => 'Company details complete', 'company_details_breaks' => 'IssueInvoice refuses to issue the invoice. Provisioning still goes through — the customer gets a running cloud with no invoice.', 'invoice_series' => 'Invoice series for every document kind', 'invoice_series_breaks' => 'IssueInvoice aborts while issuing whenever a series is missing or switched off. Provisioning still goes through — the customer gets a running cloud with no invoice, and the failure is only written to the log.', 'catalogue_synced' => 'Stripe catalogue in sync', 'catalogue_synced_breaks' => 'A verified EU business customer cannot check out, because their net price is missing at Stripe.', ], 'onboarding' => [ 'ssh_key' => 'SSH key for hosts', 'ssh_key_breaks' => 'EstablishSshTrust only deploys the public half onto the host; every step after it — and every Traefik change on a host already live — connects with this private key. Without it, onboarding stalls at the second step, and no routing update reaches a host that is already running.', 'secrets_key' => 'Vault key (SECRETS_KEY)', 'secrets_key_breaks' => 'Without it, nothing can be stored or read in this installation — not the Stripe key, not the DNS token, no host token. The console shows every one of these fields as empty, no matter what was ever entered.', 'vpn_config_key' => 'VPN config key (VPN_CONFIG_KEY)', 'vpn_config_key_breaks' => 'Without it, ConfigVault refuses to store any VPN config rather than write it in the clear — an issued access can then not be looked up anywhere again.', 'wg_hub' => 'WireGuard hub fully configured', 'wg_hub_breaks' => 'Two of three values are not half a tunnel, they are none: ConfigureWireguard writes the peer config from all three at once. Missing one leaves the new host with no management tunnel, and nobody can reach it.', 'datacenter' => 'At least one datacenter', 'datacenter_breaks' => 'Without a datacenter the host-create form has nothing to offer, and ValidateHostInput aborts as the very first step of the chain — before an SSH connection is even attempted.', ], 'provisioning' => [ 'dns_token' => 'Hetzner DNS token', 'dns_token_breaks' => 'Without it, ConfigureDnsAndTls fails to create the A record for the new instance — in the middle of provisioning, after the machine is already running and the customer has already paid.', 'dns_zone' => 'DNS zone', 'dns_zone_breaks' => 'Every customer subdomain, the link in the ready mail, and the monitoring URL are built by appending this zone to a hostname. Empty means every new instance gets a name that points at nothing.', 'traefik_path' => 'Traefik config path', 'traefik_path_breaks' => 'Empty, and SshTraefikWriter writes the route file at the filesystem root instead of Traefik\'s own directory. The step still reports success — Traefik simply never sees the new route, and the customer\'s cloud stays unreachable at its address.', 'usable_host' => 'At least one usable host', 'usable_host_breaks' => 'An active host with no readable token is still picked by ReserveResources for a new order. The order then dies in CloneVirtualMachine — after the customer has already paid.', 'vm_template' => 'VM template for every published version', 'vm_template_breaks' => 'A published version with no template_vmid makes CloneVirtualMachine fail instantly with "template_missing" — for every order of that plan, after the customer has already paid.', 'monitoring_token' => 'Monitoring token', 'monitoring_token_breaks' => 'Without it, RegisterMonitoring fails; the cloud still gets delivered, just without monitoring until the key is added. Monitoring must never hold up a delivery.', ], 'delivery' => [ 'mailer_not_log' => 'Mail transport is not a log file', 'mailer_not_log_breaks' => 'With mail.default=log the machine runs, the invoice is issued, and the mail announcing the finished cloud lands in a file on the server. The customer never learns they paid for something that is running.', 'mailbox' => 'At least one mailbox', 'mailbox_breaks' => 'With no mailbox, sending from CompleteProvisioning throws — the last step of provisioning fails and keeps retrying, even though the machine is already running and the customer has already paid.', 'mail_templates' => 'At least one reply template', 'mail_templates_breaks' => 'Without a template, every support reply is typed from scratch — and two customers get two different answers to the same question.', 'inbound_password' => 'Inbound mail password', 'inbound_password_breaks' => 'Without it, fetching mail returns an empty list every time. The schedule keeps running quietly, but no customer reply ever reaches the console inbox, and no error appears anywhere.', ], ];