Context
Wave 10 raised two refusals that 0137 does not list.LiveReadOnlyError (live_read_only, in @stackra/errors) is
raised when an action declared structural: true runs where live configuration is read-only (0359 decision 3).
ApprovalRequiredError (approval_required, in @stackra/actions) is raised when the approval step parks a call
(0098 decision 3). @stackra/settings raised its own setting_live_read_only for the same rule on a setting, because
the code comes from the class name. 0359 left the option names open.
Decision
live_read_only. A write to structural configuration where live is read-only refuses withlive_read_only, kindConflict(409), not retryable, no details. It is one code for actions and settings:@stackra/settingsraisesLiveReadOnlyErrorfrom@stackra/errorsand dropssetting_live_read_only.approval_required. A call the approval step parks refuses withapproval_required, kindFailedPrecondition(412), not retryable as it is, with one detail,approvalId. The caller resubmits the same call with that id once it is granted. Nothing of the input travels in the refusal.- Option names. An action that changes structural configuration declares
structural: trueinAction({...}); a setting field that is live-editable declares@Setting({ live: true }), one essential for normal mode@Setting({ essential: true }), and one bounded by a pack floor@Setting({ floor: "<pack key>" }). These names are final. - The guard is a port.
LiveConfigurationGuard(@stackra/actions/contracts) answers whether live is read-only for the call’s scope and whether a break-glass grant is open; the tenancy package binds it. A structural action with no bound guard is an error, never an allowed write. - Values. None of these is data: the codes and option names are mechanism. Which keys are live or structural is
declared in code per kind (0359 decision 5); who may break glass is a permission, and whether a change needs
approval is a rule set evaluated by the
ApprovalGatedriver.
Consequences
- Clients branch on two more stable codes; a sandbox banner and an approval card can key on them.
- One code for a read-only live write, whichever package refused it.
Enforcement
planned — gen’s refusal-code list (0137 enforcement) gains both codes; the@stackra/errors and @stackra/actions
tests already fix their kinds.
Supersedes and sources
Supersedes: none. Amends, when accepted: 0137 decisions 2 and 3; settles 0359 open question 5. Sources:notes/handover/build-wave10-2026-10-25.md (runtime builder, questions 2 and 3; settings builder, questions 2 and 3);
packages/foundation/errors/src/core/errors/live-read-only.error.ts;
packages/application/actions/src/core/errors/approval-required.error.ts.