leases: wire the Valkey lease store into the runtime with the observability metrics hook #11

Merged
nsaspy merged 1 commit from feat/valkey-lease-runtime into master 2026-09-11 08:40:35 +00:00
Owner

What

Wires the Valkey lease store into the runtime as the configurable production lease backend, with the observability metrics hook attached. Closes the durable gap documented in doc/observability.org ("VALKEY_* env is read by nothing").

  • star:initialize-lease-store (source/lease-store-runtime.lisp) is the runtime composition root: called in start-runtime right after the auth-store initialization point, installs the global star:*lease-store*, and star:shutdown-lease-store closes it in stop-runtime. Idempotent; init.lisp may pre-install a store before start-runtime and it is honored.
  • Backend selection via *lease-store-backend* (STAR_LEASE_STORE_BACKEND, default memory). The default keeps the current production path: no external dependency, no network, and no consumer change (target-dispatch/target-recovery still use inline document lease fields until #32).
  • Valkey selection reads the compose env that already exists in docker-compose.yml: *valkey-lease-host* (VALKEY_HOST), *valkey-lease-port* (VALKEY_PORT), *valkey-lease-password-file* (VALKEY_PASSWORD_FILE, the store's existing read-password-from-file pattern; the password value is never read from env).
  • Observability: star:observability-lease-metrics-hook is attached to the store by default (both backends, same seam). Fix: the hook previously expected a bare outcome code while both stores emit one event plist (:operation :request-id :code :retryable-p) — the stale-writer counter could never fire. It now parses the event plist.
  • Valkey unreachable behavior (verified against the adapter contract, integration-tested on master): construction is config-only and never connects; per-operation call-valkey-request retries up to reconnect-attempts (2) with bounded backoff inside the caller's deadline and returns retryable :backend-unavailable / :timeout / :outcome-unknown outcomes instead of signaling. Missing password file with valkey selected fails startup loudly (explicit opt-in misconfiguration).

Env knobs

Variable Default Runtime variable
STAR_LEASE_STORE_BACKEND memory star:*lease-store-backend*
VALKEY_HOST 127.0.0.1 star:*valkey-lease-host*
VALKEY_PORT 6379 star:*valkey-lease-port*
VALKEY_PASSWORD_FILE unset star:*valkey-lease-password-file* (required for valkey)

Tests

New hermetic FiveAM suite lease-store-runtime-tests (9 tests, no Valkey binary): default memory selection + idempotency, valkey selection from knobs with hook attachment and zero connection attempts, fail-fast on missing password file / unknown backend, shutdown idempotency, hook dispatch per outcome code, and end-to-end stale-token/conflict/acquisition counter increments through an installed store.

Local gates (all recorded via the Prolog verifier at HEAD 5a753c4):

  • nix run .#star-unit-tests — 24 suites, 230 tests, all passed
  • nix run .#doc-coverage-test — 851/851 symbols documented, 0 missing
  • nix run .#gen-api-docs — regenerated; git diff --exit-code doc/api clean (committed)
  • nix flake check — all checks passed
  • prolog-verify check — passed

CI state disclosure

The Docstring coverage workflow is pre-existing red on master (issue #10); this PR will therefore also show that CI check red despite passing the same gate locally with 0 missing docstrings (851/851). Everything else is expected green. Merging on local gates when mergeable:true with that disclosure.

Out of scope (unchanged)

  • No Prolog/RLM spans (separate slice).
  • No consumer wiring: HTTP lease routes keep returning 501 and target execution keeps inline document leases until #32.
  • No unrelated systems modified; nothing force-started in start-runtime (default backend stays memory; Valkey is operator opt-in via env or init.lisp).

Refs #8 (observability slice, closed by PR #9), #10 (pre-existing CI doc-coverage red).

## What Wires the Valkey lease store into the runtime as the configurable production lease backend, with the observability metrics hook attached. Closes the durable gap documented in doc/observability.org ("VALKEY_* env is read by nothing"). - `star:initialize-lease-store` (source/lease-store-runtime.lisp) is the runtime composition root: called in `start-runtime` right after the auth-store initialization point, installs the global `star:*lease-store*`, and `star:shutdown-lease-store` closes it in `stop-runtime`. Idempotent; init.lisp may pre-install a store before start-runtime and it is honored. - Backend selection via `*lease-store-backend*` (`STAR_LEASE_STORE_BACKEND`, default `memory`). The default keeps the current production path: no external dependency, no network, and no consumer change (target-dispatch/target-recovery still use inline document lease fields until #32). - Valkey selection reads the compose env that already exists in docker-compose.yml: `*valkey-lease-host*` (VALKEY_HOST), `*valkey-lease-port*` (VALKEY_PORT), `*valkey-lease-password-file*` (VALKEY_PASSWORD_FILE, the store's existing read-password-from-file pattern; the password value is never read from env). - Observability: `star:observability-lease-metrics-hook` is attached to the store by default (both backends, same seam). **Fix:** the hook previously expected a bare outcome code while both stores emit one event plist `(:operation :request-id :code :retryable-p)` — the stale-writer counter could never fire. It now parses the event plist. - Valkey unreachable behavior (verified against the adapter contract, integration-tested on master): construction is config-only and never connects; per-operation `call-valkey-request` retries up to `reconnect-attempts` (2) with bounded backoff inside the caller's deadline and returns retryable `:backend-unavailable` / `:timeout` / `:outcome-unknown` outcomes instead of signaling. Missing password file with `valkey` selected fails startup loudly (explicit opt-in misconfiguration). ## Env knobs | Variable | Default | Runtime variable | |---|---|---| | `STAR_LEASE_STORE_BACKEND` | `memory` | `star:*lease-store-backend*` | | `VALKEY_HOST` | `127.0.0.1` | `star:*valkey-lease-host*` | | `VALKEY_PORT` | `6379` | `star:*valkey-lease-port*` | | `VALKEY_PASSWORD_FILE` | unset | `star:*valkey-lease-password-file*` (required for `valkey`) | ## Tests New hermetic FiveAM suite `lease-store-runtime-tests` (9 tests, no Valkey binary): default memory selection + idempotency, valkey selection from knobs with hook attachment and zero connection attempts, fail-fast on missing password file / unknown backend, shutdown idempotency, hook dispatch per outcome code, and end-to-end stale-token/conflict/acquisition counter increments through an installed store. Local gates (all recorded via the Prolog verifier at HEAD 5a753c4): - `nix run .#star-unit-tests` — 24 suites, 230 tests, all passed - `nix run .#doc-coverage-test` — 851/851 symbols documented, 0 missing - `nix run .#gen-api-docs` — regenerated; `git diff --exit-code doc/api` clean (committed) - `nix flake check` — all checks passed - `prolog-verify check` — passed ## CI state disclosure The Docstring coverage workflow is pre-existing red on master (issue #10); this PR will therefore also show that CI check red despite passing the same gate locally with 0 missing docstrings (851/851). Everything else is expected green. Merging on local gates when mergeable:true with that disclosure. ## Out of scope (unchanged) - No Prolog/RLM spans (separate slice). - No consumer wiring: HTTP lease routes keep returning 501 and target execution keeps inline document leases until #32. - No unrelated systems modified; nothing force-started in start-runtime (default backend stays memory; Valkey is operator opt-in via env or init.lisp). Refs #8 (observability slice, closed by PR #9), #10 (pre-existing CI doc-coverage red).
leases: wire the Valkey lease store into the runtime with the observability metrics hook
Some checks failed
Docstring coverage / doc-coverage (pull_request) Failing after 58s
5a753c4498
star:initialize-lease-store is the runtime composition root for the target
lease store: it installs star:*lease-store* during start-runtime and is
closed by stop-runtime. The default backend (memory) preserves the inline
lease behavior; STAR_LEASE_STORE_BACKEND=valkey opts into the durable Valkey
adapter using the existing VALKEY_HOST / VALKEY_PORT / VALKEY_PASSWORD_FILE
compose env, with fail-fast configuration errors and no connection at
startup (bounded retryable :backend-unavailable/:timeout/:outcome-unknown
degradation at operation time).

star:observability-lease-metrics-hook now parses the event plist the lease
stores emit (it previously received the plist as a bare code and could never
count stale-token rejections); the initializer attaches it to both backends
so starintel_lease_stale_writer_rejections_total, _conflicts_total,
_acquisitions_total and the bounded _outcomes_total flow when the
observability addon is loaded.

Docs: configuration.org env rows + lease backend section, lease-store-usage.org
composition root and degradation contract, observability.org gap closure,
example init stanza. New hermetic suite lease-store-runtime-tests (no Valkey
binary required).

Closes the lease-store gap tracked in doc/observability.org; consumer wiring
remains issue #32. Refs #8.
nsaspy merged commit 8533dc4094 into master 2026-09-11 08:40:35 +00:00
Sign in to join this conversation.
No reviewers
No labels
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
starintel-labs/starintel-server!11
No description provided.