Reserve fundamental daw_error/v1 id for unavailable error facility #11

Open
opened 2026-08-15 19:13:01 +02:00 by michael · 0 comments
Owner

Problem

DAW runtime code protects require() calls with pcall(require, ...)
so that a component below main.lua never terminates the host process
through an unhandled Lua loading error.

This creates one fundamental edge case:

local ok_error, daw_error = pcall(require, "daw.common.error")

If loading daw.common.error itself fails, the raw Lua failure is
successfully caught, but the component cannot use daw_error.new() to
represent that failure as daw_error/v1 because the error facility is
the dependency that is unavailable.

Copying the full error constructor/bootstrap implementation into every
component is not acceptable.

Decision to specify

Reserve one special daw_error/v1.id sentinel exclusively for failure
to establish/access the DAW error facility itself.

Proposed sentinel:

daw-error-facility-unavailable

This is intentionally not a UUID. Its non-UUID form makes the
fundamental infrastructure state recognizable and avoids requiring any
ID-generation dependency when the error facility itself is unavailable.

A component that catches failure of:

require("daw.common.error")

may construct the minimal daw_error/v1 representation directly, for
example:

{
  schema  = "daw_error/v1",
  id      = "daw-error-facility-unavailable",
  source  = "<detecting component>",
  code    = "error_unavailable",
  message = "daw.common.error not available"
}

The normal process-ownership rule remains unchanged: the component
returns nil, err; only main.lua decides whether the host process
terminates.

Scope restriction

The sentinel MUST be reserved for this exact fundamental condition:
the DAW error facility itself cannot be established or accessed.

It MUST NOT be used for:

  • ordinary dependency failures;
  • UUID-generation failures;
  • validation failures inside daw.common.error;
  • missing optional submodules;
  • normal runtime/domain errors.

All normal errors continue to use ordinary daw_error/v1 identity
rules.

Rationale

In a correctly bootstrapped host, normal components should never need
this path because main.lua establishes daw.common.error before
normal runtime work begins.

The sentinel is therefore a last-resort contract-preserving fallback,
not a normal runtime mechanism.

It allows all of the following rules to remain true simultaneously:

  • require() remains guarded with pcall;
  • no component below main.lua terminates the process;
  • the returned error still has daw_error/v1 form;
  • no per-component bootstrap constructor or UUID generator is needed.

Acceptance criteria

  • daw_error/v1 defines the reserved sentinel id
    daw-error-facility-unavailable.
  • The sentinel is explicitly exempt from the normal UUID syntax rule.
  • The exception is restricted exclusively to failure of the DAW
    error facility itself.
  • A normative example shows direct minimal object construction.
  • Normal daw_error/v1 identities remain UUIDs.
  • Components still return nil, err; process termination remains
    owned by main.lua.
  • The specification states that this path should be unreachable in
    a correctly bootstrapped normal runtime.
  • DAW/daw-docs#23
  • DAW/daw-docs#26
  • DAW/daw-lua-common#50
## Problem DAW runtime code protects `require()` calls with `pcall(require, ...)` so that a component below `main.lua` never terminates the host process through an unhandled Lua loading error. This creates one fundamental edge case: ```lua local ok_error, daw_error = pcall(require, "daw.common.error") ``` If loading `daw.common.error` itself fails, the raw Lua failure is successfully caught, but the component cannot use `daw_error.new()` to represent that failure as `daw_error/v1` because the error facility is the dependency that is unavailable. Copying the full error constructor/bootstrap implementation into every component is not acceptable. ## Decision to specify Reserve one special `daw_error/v1.id` sentinel exclusively for failure to establish/access the DAW error facility itself. Proposed sentinel: ```text daw-error-facility-unavailable ``` This is intentionally not a UUID. Its non-UUID form makes the fundamental infrastructure state recognizable and avoids requiring any ID-generation dependency when the error facility itself is unavailable. A component that catches failure of: ```lua require("daw.common.error") ``` may construct the minimal `daw_error/v1` representation directly, for example: ```lua { schema = "daw_error/v1", id = "daw-error-facility-unavailable", source = "<detecting component>", code = "error_unavailable", message = "daw.common.error not available" } ``` The normal process-ownership rule remains unchanged: the component returns `nil, err`; only `main.lua` decides whether the host process terminates. ## Scope restriction The sentinel MUST be reserved for this exact fundamental condition: the DAW error facility itself cannot be established or accessed. It MUST NOT be used for: - ordinary dependency failures; - UUID-generation failures; - validation failures inside `daw.common.error`; - missing optional submodules; - normal runtime/domain errors. All normal errors continue to use ordinary `daw_error/v1` identity rules. ## Rationale In a correctly bootstrapped host, normal components should never need this path because `main.lua` establishes `daw.common.error` before normal runtime work begins. The sentinel is therefore a last-resort contract-preserving fallback, not a normal runtime mechanism. It allows all of the following rules to remain true simultaneously: - `require()` remains guarded with `pcall`; - no component below `main.lua` terminates the process; - the returned error still has `daw_error/v1` form; - no per-component bootstrap constructor or UUID generator is needed. ## Acceptance criteria - [ ] `daw_error/v1` defines the reserved sentinel id `daw-error-facility-unavailable`. - [ ] The sentinel is explicitly exempt from the normal UUID syntax rule. - [ ] The exception is restricted exclusively to failure of the DAW error facility itself. - [ ] A normative example shows direct minimal object construction. - [ ] Normal `daw_error/v1` identities remain UUIDs. - [ ] Components still return `nil, err`; process termination remains owned by `main.lua`. - [ ] The specification states that this path should be unreachable in a correctly bootstrapped normal runtime. ## Related - `DAW/daw-docs#23` - `DAW/daw-docs#26` - `DAW/daw-lua-common#50`
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
DAW/daw-contracts#11
No description provided.