Wanderland

Wanderland Core: Diagnostics

Process-wide cache for boot-time conditions that don't warrant halting the runtime but also shouldn't vanish silently. A missing boundary directory, a file that fails to require, a storage mount whose driver isn't registered — each becomes an entry here. The /healthcheck boundary surfaces them so operators can see on boot what almost went wrong.

The Module

Wanderland::Diagnostics is a module-level singleton with a thread-safe entries array.

module Wanderland
  module Diagnostics
    module_function

    def record(severity, source, message, **extra)
      # append an entry — thread-safe
    end

    def entries(severity: nil)  # all, or filtered
    def errors                   # severity == :error
    def warnings                 # severity == :warning
    def any_errors?
    def any_warnings?
    def summary                  # { errors: N, warnings: N, total: N }
    def clear!
  end
end

Entry shape

{
  "severity": "error",
  "source": "boot_load_boundaries",
  "message": "failed to load lib/boundaries/greet.rb: NameError: uninitialized constant Wannderland",
  "at": "2026-04-22T22:31:04Z",
  "file": "lib/boundaries/greet.rb",
  "error_class": "NameError"
}

severity, source, message, at are always present. Any extra keyword arguments to record serialize as additional string-keyed fields (file, dir, error_class, driver, etc. — whichever are relevant for the recording site).

Recording pattern

A boundary that wants to record a recoverable condition wraps the risky call and continues:

unless File.directory?(dir)
  Wanderland::Diagnostics.record(
    :warning, "boot_load_boundaries",
    "boundary_path does not exist",
    dir: dir, target: target.to_s
  )
  return { "loaded" => [], "dir" => dir, "exists" => false }
end

Dir.glob(File.join(dir, "**/*.rb")).sort.each do |f|
  begin
    require f
  rescue ScriptError, StandardError => e
    Wanderland::Diagnostics.record(
      :error, "boot_load_boundaries",
      "failed to load #{f}: #{e.class}: #{e.message}",
      file: f, error_class: e.class.name
    )
  end
end

Two rules guide when to record versus raise:

Recording preserves the forensic signal without crashing the service on an issue that only affects one route.

Severity

/healthcheck integration

The core healthcheck boundary reads Diagnostics.summary, Diagnostics.errors, and Diagnostics.warnings, and derives status from the error count:

{
  "status": "degraded",
  "service": "hello-world",
  "diagnostics": {
    "summary": { "errors": 1, "warnings": 1, "total": 2 },
    "errors": [
      {
        "severity": "error",
        "source": "boot_load_boundaries",
        "message": "failed to load lib/boundaries/greet.rb: NameError: uninitialized constant Wannderland",
        "file": "lib/boundaries/greet.rb",
        "error_class": "NameError",
        "at": "2026-04-22T22:31:04Z"
      }
    ],
    "warnings": [
      {
        "severity": "warning",
        "source": "boot_load_boundaries",
        "message": "boundary_path does not exist",
        "dir": "/app/lib/my_app/boundaries",
        "at": "2026-04-22T22:31:04Z"
      }
    ]
  }
}

/health and /status stay minimal — load-balancer and monitoring pings shouldn't carry the full diagnostics array. /healthcheck is the operator view, where drift from a clean boot shows up.

/inspect/diagnostics route

Dedicated surface for the diagnostics cache, separate from /healthcheck. Where /healthcheck nests diagnostics inside the full compliance payload (manifest, routes, summary), /inspect/diagnostics returns just the cache — summary plus entries — so operators can ask "what went sideways at boot?" without parsing past the rest.

Two route shapes, both core (mounted by Engine::CORE_ROUTES):

Response shape:

{
  "summary": { "errors": 1, "warnings": 1, "total": 2 },
  "severity": null,
  "entries": [
    {
      "severity": "error",
      "source": "boot_load_boundaries",
      "message": "failed to load lib/hello_world/boundaries/baby_lookup.rb: ArgumentError: unknown keyword: :capabilitiese",
      "file": "lib/hello_world/boundaries/baby_lookup.rb",
      "error_class": "ArgumentError",
      "at": "2026-04-25T13:02:11Z"
    },
    {
      "severity": "warning",
      "source": "boot_load_boundaries",
      "message": "boundary_path does not exist",
      "dir": "/app/lib/my_app/boundaries",
      "target": "site",
      "at": "2026-04-25T13:02:11Z"
    }
  ]
}

severity echoes the filter when one was supplied (so a CLI consumer doesn't have to remember which path it called); null when the unfiltered route was used.

The motivating case: a typo'd kwarg (capabilitiese: instead of capabilities:) at the boundary DSL site raises ArgumentError during require, gets caught by boot_load_boundaries, and recorded as an error. Boot continues. The boundary class never registers. The first signal the operator sees on dispatch is RuntimeError: No boundary registered for: <name> — half a runtime away from the actual cause. /inspect/diagnostics closes that loop: hit it after boot to see the recorded ArgumentError with file path and class name.

Source: wanderland-core/lib/wanderland/boundaries/inspect_diagnostics.rb.

Scope

The diagnostics cache collects at boot only. Recording sites:

Each of these wraps its per-item loop in begin / rescue ScriptError, StandardError / Diagnostics.record / continue. The good items still land; the failures are visible at /inspect/diagnostics and /healthcheck.

Request-time error recording is out of scope. Crossings and the trace already capture per-request failures; sending those through the diagnostics cache would duplicate what the merkle chain already records and would unbound the cache over the service's lifetime.

Retention

The entries array is unbounded within a process lifetime. Boot diagnostics are bounded by the number of boundary files, mounts, triggers, etc.; in practice, tens of entries on a rich site, zero on a clean one. Restarts clear the cache. Diagnostics.clear! is available for tests and tooling but not wired to any HTTP surface.

Thread safety

All reads and writes go through a Mutex. entries and the filtered variants return duped copies, so callers can iterate without holding the lock.

Source

Site Audit

wanderland.dev

oculus-view: fence: fence execute HTTP 404