Conversation
Summary: use typed service commands. Scope: installer.
Summary: separate builtin readers and detection. Scope: stats.
Summary: separate grid, card, and worker ownership. Scope: stats.
Summary: bound normalization and truncation work. Scope: text.
Summary: preserve OS-native playback paths. Scope: sound.
Summary: reduce queue and collection churn. Scope: repository.
Summary: isolate builtin reader dispatch. Scope: stats.
Summary: cover optimized boundary behavior. Scope: repository.
Summary: classify shell wrappers and timeouts consistently. Scope: commands.
Summary: isolate refresh state and coverage. Scope: stats.
Summary: identify inline shell command strings precisely. Scope: core.
Summary: expose panel modules by responsibility. Scope: center.
Summary: reduce hover and overlay scroll work. Scope: panel.
Summary: add a reduced-motion policy. Scope: panel.
Summary: reject privileged execution early. Scope: installer.
Summary: apply reduced motion immediately. Scope: ui.
Summary: preserve modes in atomic user-file writes. Scope: filesystem.
Summary: harden service and config publication. Scope: installer.
…riptors Summary: publish binaries and backups through stable descriptors. Scope: installer.
Summary: remove artifacts through stable anchors. Scope: installer.
Summary: manage directories through stable descriptors. Scope: installer.
Summary: publish links through stable anchors. Scope: installer.
Summary: move and read files beneath stable descriptors. Scope: filesystem.
Summary: harden legacy theme migration. Scope: config.
Summary: cover reduced-motion and media lifecycle. Scope: ui.
Summary: cover config and installer filesystem lifecycle. Scope: repository.
Summary: colocate module coverage and reject orphans. Scope: repository.
Summary: reconcile brightness slider writes. Scope: center.
Summary: add guarded ownership transactions. Scope: filesystem.
Summary: harden reference scanning. Scope: css.
Build trusted control executable fingerprints while constructing DaemonState, before D-Bus names and control objects are published. Read only the immutable startup map during authorization and remove lazy first-caller trust initialization. Update authorization tests for startup snapshots and missing trusted binaries.
Resolve Cargo, rustc, and rustdoc from the effective account and execute canonical validated paths. Rebuild PATH from trusted toolchain and system directories, pin Rustup state, and remove inherited compiler and linker override variables. Cover poisoned HOME, PATH, and build-environment inputs with installer tests.
Resolve an issue where certain notification images could fail to appear. Incoming notification images were being subjected to the smaller retained model limit before they could be downsampled. This caused otherwise valid large sender and content images to be discarded. Separate transient wire-image validation from persistent image storage, validate and downsample images before applying retained-model limits, and keep the existing wire and storage security bounds unchanged. Also fix file-backed visuals so source images can be safely decoded before being reduced to their requested display size. Add regression coverage for large, non-square, padded RGB, oversized, and invalid image inputs.
Make config v5 a clean schema break and reject older schemas instead of silently migrating changed semantics. Match app= rules against daemon-resolved application identity and add claimed_app= for explicit matching of sender-provided app_name metadata. Use an explicit positive assurance allowlist so future assurance states fail closed. Keep forced urgency and retained urgency hints synchronized, and update config consumers and tests for the v5 schema.
Bound PropertiesChanged messages before dynamic deserialization and propagate timeouts across the complete property snapshot. Replace pass-count fairness with monotonic admission leases and scheduled wakeups so full player inventories cannot starve newcomers indefinitely. Construct replacement players before evicting incumbents, preserve incumbents when candidate construction fails, and add coverage for quiet full-capacity rotation, property limits, timeout handling, and selection behavior.
Harden notification ownership, callback routing, quotas, protocol validation, and lifecycle handling around stable Linux process identity. Prevent D-Bus name churn from resetting per-sender quotas, preserve callback delivery across reconnects, restrict replacement to active notifications, and make failed CloseNotification requests indistinguishable. Preserve absolute popup deadlines across renderer downtime, correct resident and critical expiration behavior, and give DropAll notifications a content-free lifecycle with reply-before-close ordering. Validate raw image channel and row layout, advertise only implemented capabilities, canonicalize stored urgency, and consume sound cooldown only after a sound request is actually accepted. Add integration coverage for D-Bus lifecycle ordering, ownership, reconnects, quota principals, images, sounds, expiration, and popup replay.
Treat session-only systemd masks as recoverable during explicit installs while preserving persistent masks and checking for package-owned artifacts. Clear runtime masks immediately before service activation, surface the config v5 clean-break requirement without exposing parser details, and derive test home layouts without hardcoded account paths.
Harden notification mutation and interaction boundaries against same-ID replacement races and unfair quota consumption. - serialize action, reply, close, and replacement commits by notification ID - revalidate exact notification generations before protocol signals and cleanup - make notify admission atomic across global and per-principal buckets - separate unauthorized close attempts from authorized close-commit budget - bound fresh-principal churn - enforce per-principal active notification limits - prevent one sender from monopolizing the global active set - add regression coverage for replacement races and quota accounting
Keep application identity, conversation identity, and message content as separate presentation concepts. - retain bounded conversation-avatar pixels without treating them as app trust - require positive attribution before materializing local application artwork - keep application-provided visuals out of the message-thumbnail lane - restore conversation avatars to the popup identity column - preserve avatars across collapsed and expanded notification-center rows - retain authenticated app-icon fallback and trust presentation - clamp configured popup timeouts and handle deadline overflow defensively - preserve fail-closed trial-mode owner inspection - harden SVG renderer test coverage for timeout and output bounds
Make backup restoration durable, validated, and recoverable. - validate restore input before publishing live configuration - stage restore contents before mutation - journal previous file state before replacing live files - reject unsafe paths, duplicate entries, invalid schemas, and oversized files - restore original files after interrupted or failed transactions - commit successful restores by removing transaction state - add recovery, validation, and exact-size boundary tests
Replace raw exit-status interpretation with bounded semantic service-manager probes. - add explicit Available, Unavailable, and Indeterminate manager states - bound subprocess runtime and captured output - interpret systemd and dinit manager state using backend-specific semantics - use native service probes for runit and s6 where no manager-wide query exists - fail closed on ambiguous active-state and manager-availability results - classify partial, unsafe, active, and indeterminate alternate-manager installs - make compatibility checks consume the same semantic availability API - add backend regressions for reachable, absent, inactive, and ambiguous states
Represent installed binaries as immutable verified release generations. - generate manifests for complete binary sets - record package version, file size, mode, and SHA-256 digests - stage complete generations before publication - verify staged and existing generations before trusting them - inspect installed entrypoints against the current verified generation - reject corrupt, mixed, malformed, or unmanaged binary layouts - retain generation health metadata for install-state reporting - add manifest, health, corruption, and generation-consistency tests
Make binary publication atomic and recoverable across interrupted installs. - create a durable pending-release journal before live entrypoint mutation - move legacy entrypoints into generation-scoped rollback storage - publish managed entrypoints without following unsafe links - atomically switch the current generation - recover interrupted release transactions before new mutation - revalidate the previous generation before rollback - retain rollback authority until service readiness commits the release - prune superseded generations only after successful activation - add journal, entrypoint, rollback, recovery, and transaction regressions
Distinguish healthy installs from missing and damaged installations. - replace binary existence checks with verified generation health - require all managed binaries to belong to one verified generation - include service artifact and manager inspection health in installed state - introduce NotInstalled, InstalledHealthy, and RepairRequired dispositions - expose verified installed version from generation metadata - label healthy installs as Reinstall and damaged installs as Repair - avoid presenting incomplete installations as clean fresh installs - add install-state and UI disposition regressions
Fail closed when existing installation ownership cannot be established. - canonicalize systemd fragment and executable identity before classifying channels - reject mixed, package-owned, partial, and unrecognized installations - treat systemctl inspection failures as errors rather than absence - preserve persistent user masks and recover supported runtime masks safely - validate installed service artifacts by expected object shape - serialize mutating installer sessions with an owned runtime-directory lock - refuse symlink-redirection and foreign lock-file ownership - add channel-classification, path-identity, and installer-lock regressions
Close the reinstall activation race across daemon shutdown, binary publication, and service preparation. - stop the selected daemon and wait for actual runtime quiescence - distinguish transient shutdown convergence from strict mutation checks - reserve both org.freedesktop.Notifications and com.unixnotis.Control - make the activation reservation a non-forgeable production capability - require the reservation for binary and service-artifact publication - retain the guard through manager refresh and pre-start preparation - recheck selected service state around destructive transaction boundaries - release activation exclusion only immediately before controlled startup - verify service readiness before committing the pending release - retain strict checks for direct service-manager starts - add reservation, quiescence, handoff, and reinstall-race tests
Keep daemon activation inhibited when failed installation recovery cannot prove a safe runtime and disk state. - distinguish ordinary recovered failures from ActivationInhibited failures - retain the dual-name reservation when pending-journal inspection fails - retain activation exclusion when guarded rollback itself fails - treat contradictory in-memory and on-disk release state as catastrophic - keep the worker and installer lock alive while activation remains inhibited - expose a dedicated Manual recovery required progress state - prevent returning to the installer menu while the recovery guard is held - preserve concise status errors and complete anyhow chains in logs - test guard lifetime across install steps and catastrophic recovery branches
Allow an advertised default notification action only when the callback owner is bound to a concrete sender process lifetime. Keep application identity independent from callback ownership. Arbitrary action buttons and inline reply remain denied for owner-bound unresolved senders. Require stable sender name, PID, process start time, and UID evidence. Credential failures, incomplete evidence, conflicts, and relay fallback paths continue to fail closed. Add resolver, sender-evidence, and action-target regression coverage.
Preserve bounded desktop-entry metadata as presentation-only application branding without treating caller claims as identity evidence. Separate wire conversation visuals, application-provided visuals, and content media so choosing a presentation slot cannot grant filesystem or interaction authority. Keep local visual paths gated on positive attribution while allowing bounded wire avatar pixels to retain communication semantics. Normalize desktop identifiers used for local presentation lookup and keep conflict and relay trust states authoritative over decorative branding. Clarify unresolved presentation as "App identity could not be verified" and add shared generic visual and trust regression coverage.
Restore compact application identity in the popup header and keep conversation avatars beside message content. Prevent fixed application and avatar slots from inheriting horizontal expansion so short messages retain correct spacing. Resolve presentation-only application branding without allowing it to override conflict or relay trust states. Include claimed desktop branding and trust-dependent candidate order in icon cache identity so attribution transitions cannot reuse stale icons. Keep content thumbnails independent from sender avatars and application branding. Add generic popup visual-matrix, layout, cache, trust, malformed-image, and short-message regression coverage.
Restore application branding and conversation-avatar presentation in notification and group rows while keeping trust state visually separate. Invalidate asynchronous icon ownership whenever rows are cleared, rebound, grouped, or unbound so late decode completion cannot resurrect stale branding. Include every branding and trust input in row icon signatures and clear recycled conflict, relay, recognized, unresolved, tooltip, and warning state when a group loses its sample notification. Keep semantic conflict and relay badges authoritative over presentation branding. Add generic row-recycling, group-lifecycle, icon-cache, trust-transition, thumbnail, and visual-matrix regression coverage.
Treat human-readable CLI diagnostics as terminal trust boundaries. Sanitize and bound every free-form attribution field rendered by explain-notification so notification metadata cannot inject lines, terminal controls, bidi controls, or unbounded output. Apply the existing doctor text sanitizer to every free-form field in human-readable doctor reports while preserving the structured JSON schema unchanged. Keep empty sanitized diagnostic values rendered as "none" and add deterministic terminal-injection regression coverage.
Remove ~/.local/bin as an independent executable trust root in trial mode. Require privileged UnixNotis control and renderer processes to resolve to the known trial build/install tree, including the expected debug/release siblings, instead of trusting a same-UID executable by writable launcher pathname alone. Preserve temporary ~/.local/bin/noticenterctl symlinks when they resolve to the genuine trial binary, while rejecting copied or renamed noticenterctl, center, popup, and daemon executables. Keep Linux process-handle and executable fingerprint verification intact and add regression coverage for forged local-bin component names and trial-shim compatibility.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR promotes the current dev baseline to master.
The release updates UnixNotis across configuration, notification lifecycle handling, application attribution, theming, preset management, service-manager integration, diagnostics, media/artwork handling, and installer/reset behavior.
The largest compatibility change is the move to configuration schema 5. Current builds require an explicit
config_version = 5; older, newer, and unversioned configurations are rejected rather than silently migrated.Highlights
Notification lifecycle and control
noticenterctl explain-notification <id>Trusted application attribution
claimed_appfor explicitly matching the untrusted freedesktopapp_nameclaimed_desktop_idonly as bounded presentation/decorative metadata rather than trusted identityNotification images and artwork
unixnotis-svg-rendererhelper for local SVG rasterizationSound hardening
sound.allow_file_hintssound.allowed_file_hint_dirsD-Bus and DND behavior
body-markupcapability advertisementGetApiVersion()SetDndUntilaccepts a bounded future timestamp; clearing DND is done throughSetDnd(false)rather than using a zero deadlineno_popupsanddrop_allConfiguration
config_version = 5style.cssTheming
base.css,panel.css,popup.css,widgets.css, andmedia.css[theme]pathstheme.tomlas compatibility metadata rather than a runtime requirement or normal preset-export inputvar(...)/calc(...)expressions as part of the normal theme contractPresets and reset workflow
theme.tomlas a required payloadnoticenterctl preset reset-confignoticenterctl preset reset-config --yesnoticenterctl theme export-stockReset targets are:
config.tomlbase.csspanel.csspopup.csswidgets.cssmedia.cssunixnotis-blue-light-*helper scriptsBackups use timestamped names with collision suffixes when necessary:
Backup-YYYY-MM-DD-HHMMSSBackup-YYYY-MM-DD-HHMMSS-001Backup-YYYY-MM-DD-HHMMSS-002CLI and diagnostics
Expand the locally usable command families and add operational tooling including:
noticenterctl explain-notification <id>noticenterctl refresh-applicationsnoticenterctl sync-session-environmentnoticenterctl preset reset-confignoticenterctl theme export-stockdoctor --verbosenow covers configuration/CSS, D-Bus ownership, private-control authorization, compositor environment, service-manager state, and available service logs.Service-manager and session integration
UnixNotis continues to use
systemd --useras the default service-manager path and supports user-service backends for:Add
sync-session-environmentto validate and propagate the compositor/session environment after login, compositor restart, or service-manager migration.Relevant session state includes Wayland, runtime-directory, desktop/session, PATH, display, and D-Bus environment values.
Installer and release packaging
unixnotis-svg-rendererin release archivesBreaking changes / migration notes
This release is not configuration-compatible with older schemas.
Before upgrading:
config.tomlto schema 5