Skip to main content
Amends 0098: actions declare options, and each option runs in a step the pipeline already has.

Context

An action needs to say how it is consent-checked, rate-limited, locked, cached or limited in includes. The owner’s intent-map item P5 set these as declared options, each run by one pipeline step. Two refusal codes came from later answers (I5 and EN3). The first draft had two casings. The owner decided on 2026-10-20: every machine code is snake_case (ADR 0231).

Decision

  1. An action may declare these optional options: consent, rateLimit, lock, cache and maxInclude. Each is run by an existing pipeline step (ADR 0138 fixes the order).
  2. The stable refusal codes are snake_case:
    • module_disabled;
    • entitlement_missing;
    • flag_off;
    • consent_missing;
    • rate_limited;
    • region_unsupported;
    • maintenance.
  3. Two more codes come from later answers, also snake_case: step_up_required (I5, mem L609) and limit_exceeded, with an upgrade hint (EN3, mem L676).
  4. A refusal code is returned in the error envelope as its code and carries the category of ADR 0140. An entitlement refusal uses the entitlement_required category (402) in that envelope.

Consequences

  • Clients branch on a stable snake_case code. A code added later is a new ADR, so the list does not drift silently.
  • Generated clients can use the list as a contract.

Enforcement

planned — gen reads the option declarations and rejects an unknown refusal code, and the naming rule (.agents/rules/naming-and-casing.md, wave 1 part 5) rejects a kebab-case code.

Alternatives

  • Kebab-case codes (P5): replaced by the owner’s snake_case decision.
  • Free-text refusal messages: rejected, clients need stable codes.

Supersedes and sources

Supersedes: none. Amends: 0098. Sources: owner intent-map item P5 (stackra-notes/owner-docs-intent-map.md, Part 4), I5 (mem L609), EN3 (mem L676), and the owner’s naming decision for machine codes (2026-10-20, ADR 0231). Contradiction C-14 is resolved by that decision.