Revision history for Concierge

v0.13.0  2026-08-04
    - BREAKING: Removed component method promotion (the 'promote' key in
      a components-block entry). Per spec V3, an added component's
      methods are reachable only through the object the component
      itself returns ($concierge->{$compName} / $concierge->$compName()),
      never merged into the concierge's own method namespace. No
      automatic access is provided in either direction between added
      components and Concierge's core objects ($desk, $concierge,
      $auth, $sessions, $users, $user, $session); the application is
      responsible for passing whatever arguments a component's methods
      need.
    - Added $user-level mirror methods verify_password(), reset_password(),
      and logout(), delegating to the same closures used internally.
      logout() clears the user object's session and credential-checking
      closures on success (self-cleanup), and capability-bearing mirror
      methods are gated by a live session-validity check
      (_session_valid()/_session_ok()) so a second, stale $user instance
      can no longer mutate data after another instance has logged out.

v0.12.0  2026-07-25
    - Added deferred component initialization: a components-block entry
      may set defer => 1 to postpone its real, potentially expensive
      new() call until first actual use, instead of paying that cost for
      every process that opens the desk regardless of whether the
      component is ever called. defer forces optional (build_desk()
      rejects defer => 1, optional => 0), preserving Concierge's
      guarantee that its API is never fatal once a desk is open.
      Implemented as a three-tier model: a mandatory build-time probe
      (tier 1b, unconditionally build-fatal, via the new
      Concierge::Desk::Component::probe_component() shared helper), an
      open-time revalidation of the same probe (tier 2, resolving to
      Concierge::Desk::UnavailableComponent on failure), and a new
      Concierge::Desk::DeferredComponent AUTOLOAD proxy that performs
      the real build on first use, caches the result, and never retries
      a failed build (tier 3). No existing component or desk config is
      affected unless defer is explicitly set.
    - Fixed login_guest(): a known user browsing as a guest (e.g.
      building a shopping cart before logging in at checkout) no longer
      fails with an "already exists" error. login_guest() now checks
      verify_user() first: a known user (found in both Auth and Users)
      skips straight to login and carries over guest session/cart data;
      an unknown user is registered as before; a user found in only one
      of Auth/Users (an inconsistent state) fails fast with a clear
      message instead of attempting either path.

v0.11.0  2026-07-23
    - BREAKING: Sessions and Users backend selection now follows the same
      backend_class convention as Auth (introduced in v0.9.0): Desk::Setup
      gains %SESSIONS_BACKENDS and %USERS_BACKENDS catalogs, resolving a
      desk config's friendly sessions.backend/users.backend name
      ('database', 'file', 'yaml') to a fully-qualified class, exactly
      mirroring %AUTH_BACKENDS. The desk config format itself is
      unchanged -- still friendly names under sessions.backend/
      users.backend -- but the resolved backend_class is now what gets
      passed down to Concierge::Sessions->new() and Concierge::Users->
      setup(), matching Concierge::Sessions v0.11.3's and Concierge::Users
      v0.9.4's own backend_class rename. sessions.backend and
      users.backend also lost their implicit 'database' default and are
      now required, matching auth.backend. Desks built before this
      change will fail at open_desk() -- there is no migration path;
      rebuild the desk with the same original configuration.
    - validate_setup_config(): replaced hardcoded
      database|file/database|yaml|file regex checks for sessions.backend/
      users.backend with catalog-based validation (including per-backend
      required-field checks), matching auth.backend's existing validation.
    - Concierge.pm, Desk::Setup.pm POD: updated EXTENSIBILITY and
      build_desk() documentation to describe backend_class propagation;
      added a "The backend_class Pattern" subsection recommending the
      same convention for new components with their own interchangeable
      backend implementations.
    - Makefile.PL: bumped PREREQ_PM minimums for Concierge::Sessions,
      Concierge::Users, and Concierge::Auth to the first versions
      containing their respective backend_class changes.
    - %USERS_BACKENDS' database entry and build_quick_desk()'s hardcoded
      Users backend_class now point to Concierge::Users::SQLite, matching
      Concierge::Users v0.9.4's rename of Concierge::Users::Database to
      Concierge::Users::SQLite (the module was always SQLite-specific;
      the old name implied a generic swappable database backend that
      never existed). The 'database' friendly name at the desk-config
      layer is unaffected.
    - open_desk(): Auth backend-initialization failures (including
      the pre-v0.5 missing-auth_backend case) are fatal again, matching
      Sessions and Users -- a desk must never open half-functional.
      Reverts the graceful { success => 0, ... } handling added in
      v0.9.0/0.10.0-dev; see commit 50a38bd for the change being
      reverted.

v0.10.0  2026-07-16
    - Removed Concierge::Desk::Base and Concierge::Desk::RecordsStore.
      Component.pm (pure POD contract) and UnavailableComponent.pm
      (AUTOLOAD stand-in for a component that fails to instantiate)
      now fully replace the old Base.pm split; a component's CRUD
      methods are its own responsibility, no longer scaffolded or
      standardized by Concierge.
    - Added component method promotion: a component's 'promote' config
      entry (arrayref or hashref, in its components.$name block) exposes
      a curated subset of its methods directly on $concierge, e.g.
      $concierge->method(...) instead of $concierge->component->method(...).
      Convenience/clarity only, never access control -- the bare-accessor
      escape hatch ($concierge->{name} / $concierge->name) remains
      unrestricted regardless of promotion. All validation (shape,
      can(), name collisions against core methods and other components'
      accessors) happens once, at build_desk() time; open_desk() only
      replays already-trusted concierge.conf entries. See perldoc
      Concierge::Desk::Component for the full contract.
    - build_desk(): setup() failures now self-report the failing
      top-level component name (name is passed into setup()'s args
      alongside dir), fixing a build-error message that previously
      could not identify which optional component failed.
    - Concierge.pm POD: documented previously-undocumented public
      methods new_concierge, save_user_keys, and the auth/sessions/users
      component accessors (raised POD coverage from 71% to 95% on this
      module).
    - Fixed stale MANIFEST: was still listing the removed Base.pm and
      missing Component.pm, UnavailableComponent.pm, and two test files
      -- the CPAN tarball would have shipped without two required
      modules.
    - README.md, SECURITY.md: updated stale version references.

v0.9.0  2026-07-05
    - BREAKING: Auth backend is now selected via a friendly name resolved
      through Desk::Setup's %AUTH_BACKENDS catalog, matching the 5-verb
      contract introduced in Concierge::Auth v0.5.0. Desks built before
      this change (bare auth_file, no auth_backend/auth_args in
      concierge.conf) will fail at open_desk() -- there is no migration
      path or fallback; affected desks must be rebuilt via
      build_desk()/build_quick_desk(). Requires Concierge::Auth >= 0.5.0
      (bumped in PREREQ_PM); running against an older Concierge::Auth
      will fail outright since it no longer has the backend factory.
    - open_desk(): instantiating the configured Auth backend is now
      wrapped so failures return gracefully instead of croaking. A
      pre-v0.5 desk (missing auth_backend) gets a specific
      { success => 0, message => '...' } explaining that the desk must
      be rebuilt, that rebuilding will archive existing user data but
      delete session/credential storage and install the default
      built-in ID-password auth system, and pointing at the POD for
      alternative auth approaches. Any other backend init failure (bad
      backend name, backend constructor error) returns a generic
      wrapped { success => 0, message => "Failed to initialize auth
      backend: ..." } instead of propagating the croak.
    - Desk::Setup: added %AUTH_BACKENDS catalog (currently 'pwd' ->
      Concierge::Auth::Pwd); build_desk() and validate_setup_config()
      resolve/validate auth.backend through it. Documented (POD +
      commented-out catalog entries) that additional backends -- e.g.
      OAuth, SAML, or a non-Concierge::-namespaced class -- can be added
      as one-entry additions; the backend class is not required to live
      under the Concierge:: namespace.
    - Concierge.pm: six call sites (add_user, remove_user, verify_user,
      login_user, verify_password, reset_password) converted from the
      old Auth primitives to the new authenticate/is_id_known/enroll/
      change_credentials/revoke verbs.
    - Fixed three call sites (admit_visitor, checkin_guest,
      Desk::User::enable_user) that called Concierge::Auth as a class
      method for ID generation -- broken outright under the new factory,
      which has no class methods; now call the configured backend
      instance or Concierge::Auth::Generators directly.
    - BREAKING: Desk::Setup's build_desk() config is reshaped: the
      former storage => { base_dir, sessions_dir, users_dir, auth_dir }
      block is gone. base_dir is now a top-level setting (it was the
      only entry left in storage once each component's own directory
      moved into its own block), and each component's storage location
      is a 'dir' setting within that component's own block (auth.dir,
      sessions.dir, users.dir), keeping location and backend settings
      together per component instead of split across two structures.
      Each 'dir' defaults to the top-level base_dir if omitted; a
      relative 'dir' is resolved *against* base_dir (so it moves along
      with it), while an absolute 'dir' is used as-is, letting a
      component's storage live entirely outside the rest of the desk
      (e.g. a more restrictively permissioned location for the 'pwd'
      backend's password file). auth.file remains a filename only
      (default 'auth.pwd' for 'pwd'), never a path -- previously an
      explicit path in auth.file that was given relative to '.' could
      silently end up outside the desk directory once base_dir '.'/
      './' was normalized to './desk'; naming (file) and location
      (dir) are now fully independent, and passing a full path in
      auth.file is no longer supported.

v0.8.4  2026-06-05
    - Desk::Setup POD: add UI Formatting Hints section documenting format_as
      with template example using app-native tokens (t/b/sel)
    - Desk::Setup POD: add format_as to field attribute reference
    - Desk::Setup POD: fix field table -- move last_login_date from standard
      to system fields; fix standard count 12 -> 11; fix Complete Example
      system count 2 -> 3, total 15 -> 16
    - Desk::Setup POD: update get_field_hints() return comment to include
      format_as

v0.8.3  2026-06-01
    - Fix MANIFEST: remove .perl-version (file does not exist in repo,
      causing CPAN Testers MANIFEST mismatch error)
    - Add .perl-version to MANIFEST.SKIP to prevent recurrence
    - Fix POD VERSION sections in all four modules (were stale at v0.8.1)

v0.8.2  2026-05-31
    - Fix version consistency: update Makefile.PL provides section to v0.8.2
      (was not updated when modules were bumped from v0.8.0 to v0.8.1)

v0.8.1  2026-05-27
    - Desk::Setup POD: update show_default_config/show_config examples and
      prose to reflect service-hashref returns (Concierge::Users v0.8.3);
      add validate_as, default, null to get_field_hints return-value comment

v0.8.0  2026-05-25
    - Rename Concierge::Setup, ::User, ::Base into Concierge::Desk:: namespace
      (Concierge::Desk::Setup, ::User, ::Base)
    - Resolves visual ambiguity between Concierge::User (object) and
      Concierge::Users (data-store component) in the installed library tree

v0.7.2  2026-05-25
    - Add "What the Suite Provides" section to DESCRIPTION in Concierge.pm
    - Expand README.md into a full suite overview (components, lifecycle,
      backends, field schema, return values, extensibility, installation)

v0.7.1  2026-05-25
    - Fix POD rendering: C<{ ... }> → C<< { ... } >> in EXTENSIBILITY section
    - Expand Return Values documentation with per-method-category field list
    - Add Password Operations intro clarifying add_user() handles registration

v0.7.0  2026-05-21
    - Added Concierge::Desk::Base: records-store base class for custom components
    - Added EXTENSIBILITY POD section to Concierge.pm (component substitution
      API, additional component pattern, future components, contributor invitation)
    - Updated README.md

v0.6.1  2026-02-15
    - POD version number updating issue

v0.6.0  2026-02-15
    - Update and corrections to POD

v0.5.9  2026-02-15
    - Fixed distribution issue with MANIFEST.SKIP

v0.5.8  2026-02-15
    - Fixed distribution issue with MANIFEST.SKIP

v0.5.6 2026-02-13
    - Fixed CPAN testers build failure: require Params::Filter 0.014
      (earlier versions do not export make_filter)

v0.5.5 2026-02-12
    - Rebuilt tarball with GNU tar (fixes PaxHeader issue on CPAN)

v0.5.4 2026-02-12
    - Fixed CPAN testers timeout failure on Windows: session expiry in
      installation tests now mocked via direct SQLite update (no sleep).
      Real-time timeout tests moved to xt/ (author tests only).

v0.5.3 2026-02-12
    - Updated docs: session IDs are now random hex strings, not UUIDs
      (reflects Concierge::Sessions v0.8.5 security improvement)

v0.5.2 2026-02-11
    - Corrected production of tar file