Files
latchd/CHANGELOG.md
Zane Walker f2a885d621 refactor: split the TUI and refresh project docs
Move login state, authentication, discovery, input, rendering, and tests into focused TUI modules. Add detailed CLI error reports with recovery commands, align the build and host-check documentation, and keep the legacy Go tree outside normal builds.

Checks: make check; make integration-test; go test ./... (legacy/go).
2026-10-05 21:37:15 +05:30

8.9 KiB

Changelog

Unreleased

  • TUI module layout — crates/latchd-tui/src/lib.rs held state, input, authentication, discovery, rendering, and tests in one file; split those responsibilities into app.rs, app/auth.rs, app/discovery.rs, app/input.rs, app/render.rs, and app/tests.rs, which makes each change surface easier to locate
  • error reports — crates/latchd-core/src/error.rs::Error::user_report now adds a detail line and recovery commands; rust/main.rs prints the report for CLI failures instead of one short error line
  • TUI checks — keep the render and state tests beside the new modules; cargo test --locked --workspace --all-targets covers the split without changing the login flow
  • service configuration — document /etc/latchd/config.toml as the service file and keep preview, build, and end-to-end instructions aligned with the Makefile

0.5.0 — password and session handoff

  • password-change state — before this change, an expired password had no separate screen state; crates/latchd-tui/src/app/auth.rs now switches to a new-password prompt for PAM_NEW_AUTHTOK_REQD and PAM_AUTHTOK_EXPIRED, then starts authentication again after the change
  • password conversation — crates/latchd-auth/src/lib.rs::converse handles the current-password and new-password prompts in order; tests cover both prompt sequences in crates/latchd-auth/src/lib.rs
  • audit events — crates/latchd-core/src/audit.rs records authentication, password-change, and session results with stable PamReason values, so the service log can group failures without copying module text into the event fields
  • session preferences — crates/latchd-core/src/preferences.rs stores one bounded entry per account, writes through a private temporary file, and replaces the target atomically; invalid ownership or file mode stops the save
  • Wayland handoff — crates/latchd-core/src/session.rs::build_spec carries the selected session type, desktop, seat, VT, runtime directory, session ID, and D-Bus address into latchd-auth before the session opens
  • PAM fixture — crates/latchd-auth/tests/pam_fixture.rs covers denied authentication, password change, session metadata, and child environment values; scripts/test-pam-fixture.sh installs the temporary service files for the test run
  • test coverage — crates/latchd-core, crates/latchd-auth, and crates/latchd-tui now test configuration, account state, session parsing, authentication conversations, preferences, rendering, and background animation

0.4.0 — account and session workflow

  • account status — crates/latchd-core/src/accounts.rs::inspect_account reads lock markers, password age, account expiry, inactivity, login shell, and shadow availability; the TUI shows the matching state beside the selected account
  • faillock parsing — crates/latchd-core/src/accounts.rs::faillock_status_from_output accepts legacy counts, username prefixes, and timestamp rows; malformed output or a timeout removes the extra count from the screen
  • account switching — crates/latchd-tui/src/app/input.rs::select_account_index changes the account, clears the password, resets authentication state, and reapplies the saved session for the new account
  • session refresh — crates/latchd-tui/src/app/discovery.rs::start_refresh moves account and session discovery to a worker; the screen keeps accepting input while the lists refresh
  • filtering — crates/latchd-tui/src/app/input.rs::matches_filter adds smart-case filtering for account and session names; uppercase query characters select case-sensitive matching
  • terminal display — crates/latchd-tui/src/app/render.rs adds high-contrast styles, footer hints, account status text, notifications, and a minimum terminal size of 60 columns by 16 rows
  • authentication backoff — crates/latchd-tui/src/app/auth.rs::auth_backoff delays repeated failures from one to sixteen seconds and resets the delay when the account changes
  • host checks — scripts/test-cli.sh and scripts/test-system-e2e.sh cover CLI preflight and the available PAM, faillock, VT, X11, Wayland, and systemd-logind capabilities
  • VM gate — docs/e2e-testing.md lists the host requirements for the strict check and the commands for a disposable VM
  • version — set the workspace package version to 0.4.0 in Cargo.toml

0.3.0 — Rust workspace release

  • Rust service — rust/main.rs became the supported login-manager entry point; the Go prototype stayed under legacy/go/ and is excluded from normal builds
  • workspace crates — split authentication, configuration, accounts, sessions, and the TUI into latchd-core, latchd-auth, and latchd-tui
  • session commands — crates/latchd-core/src/session.rs::parse_argv stores a program and argument list instead of sending desktop entries through a shell, which rejects shell operators and desktop field codes
  • terminal effects — crates/latchd-tui/src/background.rs adds wallpaper loading, a bounded cellular animation, reduced motion, and the background toggle
  • release pipeline — .gitlab-ci.yml and Makefile add format, test, Clippy, rustdoc, Docker, version, package, checksum, and release targets
  • deployment gate — scripts/test-system-e2e.sh and docs/e2e-testing.md separate container checks from live VT, display, and logind checks

Legacy Go history

The entries below describe the first Go prototype. The Rust workspace does not build or ship this code.

0.1.0 — first public prototype

  • login screen — legacy/go/login/login.go added username and password fields, a session switcher, status messages, and preview mode
  • session types — legacy/go/session/scan.go added X11, Wayland, script, and TTY entries
  • authentication — legacy/go/auth/pam.go added cgo login support with one OS thread per PAM transaction
  • faillock — legacy/go/auth/faillock.go added lockout counts, remaining attempts, and the administrator reset key
  • terminal effects — legacy/go/tui/bg/automata.go added the cellular background, switcher motion, and failed-login shake
  • terminal details — legacy/go/login/login.go added the caps-lock indicator, power keys, clock, and preview mode
  • configuration — legacy/go/config/config.go added configuration parsing, variable replacement, and configurable power programs
  • accounting — legacy/go/auth/utmpx.go added UTMPX records for who, w, and last on glibc
  • X11 startup — legacy/go/session/x11.go added Xauthority cookies, the SIGUSR1 readiness signal, and a server timeout
  • privilege drop — legacy/go/session/exec.go started the selected child with the account UID, GID, and supplementary groups
  • logs — legacy/go/session/exec.go capped the client log at 64 MiB

Fixes

  • DesktopNames parsing — legacy/go/session/scan.go::splitDesktopNames previously dropped desktop names from the session environment; it now maps the first semicolon-delimited value to XDG_SESSION_DESKTOP and the full list to XDG_CURRENT_DESKTOP, which fixes GNOME and KDE sessions that start without their desktop values
  • UTMPX time fields — legacy/go/auth/utmpx.go used fixed C integer types for ut_tv; legacy/go/auth/utmpx_time.h now accepts the platform time fields, which fixes builds where ut_tv uses struct timeval
  • cgo pointer storage — legacy/go/auth/pam.go passed a Go pointer through pam_conv; storeHandle and loadHandle keep the numeric handle in C memory, which fixes the Go 1.22 pointer check
  • PAM conversation — legacy/go/auth/pam.go::latchd_pam_conv used a pointer-to-pointer as the response slice; it now writes to the allocated response array and answers only prompt messages, which fixes corrupted responses and the pam_unix password error
  • cgo handle lifetime — legacy/go/auth/pam.go::Credentials now owns the handle until session close; the previous Validate cleanup released it before OpenSession
  • session spawning — legacy/go/session/exec.go starts the selected desktop directly with dropped credentials; the previous path relaunched latchd with an undefined -user flag
  • file names — rename the lemurs policy and unit files in extra/ to latchd
  • extra files — add extra/config.toml, extra/xsetup.sh, extra/latchd.pam, and extra/latchd.service, which lets make install find its source files
  • Make targets — add deps, enable, and update targets for dependency checks, service enablement, and local updates
  • terminal rendering — remove the unused background layer and fixed top-bar width from the Go renderer, which fixes garbage characters and narrow-terminal layout errors
  • session environment — legacy/go/session/env.go now sets display, VT, desktop, seat, XDG, and home values before the desktop starts, which fixes missing DISPLAY, XDG_VTNR, and HOME
  • session startup — handle pam_open_session errors as session log entries and remove the obsolete login include from the prototype service file
  • global session switching — accept , and . from every screen state while keeping arrow keys for the focused switcher