Every requirement in this project has a named verification tier, and none is unknown. That is
itself a requirement, and this page is the published statement of it.

Five tiers, in the order you meet them:

Tier What it means
Unit a decision, checked without a compositor or a display
E2E the running program, against a real nested Hyprland
CI a check that gates a pull request
Release a precondition or a step of the release workflow
Inspection a named item on the release checklist, walked by a person

The commands behind the first three are in testing.

Inspection is not a shrug. It is what a requirement gets when only a person can judge whether it
holds — whether the README actually answers a newcomer’s questions, whether a security channel
actually reaches someone. Each one is an item on a checklist that is walked before every release,
not a gap.

Requirements of feature 003 — release readiness

This table is not copied from the plan; it is the plan’s table, included at build time from
specs/003-oss-release-readiness/plan.md.
The published statement and the planning document are the same bytes, so they cannot diverge.

Tiers: Unit (cargo test --lib) · E2E (cargo test --test 'e2e_*') · CI (a check in
the pull-request workflow) · Release (a precondition or step of the release workflow) ·
Inspection (a named item on the release checklist in quickstart.md).

Requirement Tier Verified by
FR-062 licence text present, matches metadata CI licence-files check: LICENSE exists, holder/year present, Cargo.toml license agrees
FR-063 third-party components attributable CI same check: every path in protocols/, assets/ appears in THIRD-PARTY.md
FR-064 dependency licence position CI the gating licenses job: cargo deny check licenses
FR-065 package metadata complete CI licence-files check asserts description, licence, repository, documentation, keywords
FR-066 packages ship the licence Release .deb/.rpm contents asserted after build
FR-066a history reviewed before publication Inspection history-review.md recorded (R44)
FR-067 README answers six questions in order Inspection README review item
FR-068 no development instructions in README CI docs-map check: README carries no cargo test/cargo clippy/architecture headings
FR-069 requirements section complete CI docs-map check: compositor range matches SUPPORTED_HYPRLAND, toolchain matches rust-version
FR-070 overlay shown in both presentations Inspection both images present and current (R47)
FR-071 scope and privacy statement Inspection README review item
FR-072 development document covers setup/tests/run/architecture Inspection DEVELOPMENT.md review item
FR-073 architecture conveys the pure/shell seam Inspection same
FR-074 every top-level directory and module described CI docs-map check: every src/**/*.rs and top-level directory named in DEVELOPMENT.md
FR-075 per-tier requirements, container route stated Inspection DEVELOPMENT.md review item
FR-076 site builds CI docs job: pnpm install --frozen-lockfile && pnpm build && pnpm validate
FR-077 two navigable sections CI the navigation in docmd.config.mjs, asserted by the docs-map check
FR-078 auto-published, failure reported CI the docs workflow itself (R46)
FR-078a one version, states its release CI docs-map check: front page names a released version
FR-079 complete configuration reference Unit + CI catalogue walk (extended, R32); include resolves at build
FR-080 theming account sufficient Unit catalogue walk covers every colour, font and geometry value
FR-081 end-user section covers install/binds/keys/icons/diagnostics/troubleshooting CI docs-map check: required page set and troubleshooting entries present, each naming a real Condition
FR-082 developer section complete CI docs-map check: required page set
FR-083 reference verified against behaviour Unit the catalogue walk — the check that cannot be bypassed
FR-084 one authoritative answer per question CI docs-map check against contracts/documentation.md
FR-084a specs stay authoritative CI same check: developer pages link to specs/, do not restate
FR-084b development record retained Inspection published tree contains specs/, .specify/, .claude/, CLAUDE.md
FR-085 checks run unprompted, one verdict CI the ci-required aggregate job (R39)
FR-086 build, unit, lint, format CI those four jobs
FR-087 minimum toolchain built CI msrv job pinned from rust-version
FR-088 E2E runs against a supplied compositor Developer machine — requirement unmet there is no e2e job: both routes for supplying automation a compositor were built and measured and neither hosts a nested one (R29, failed). Recorded as a deviation at FR-088; the tier runs on a contributor’s own session, quickstart.md scenario 5, optionally through the pinned image of R30
FR-089 image defined in-repo and usable locally Inspection + E2E docker/e2e/Dockerfile; the local run is quickstart scenario 5
FR-090 failures name the reproducing command CI each job’s failure step; asserted by the ci-required job’s summary
FR-091 gating distinguishable from informational Inspection branch protection requires only ci-required; contracts/ci.md lists both sets
FR-092 published coverage of every requirement Inspection this table, ::include[]d into the developer section, beside the derived rows for 001 and 002
FR-093 advisories surfaced, bounded acceptance CI + Unit cargo deny check advisories (informational); the expiry test is gating; the site’s npm tree watched by Dependabot (R38)
FR-094 contribution guidance Inspection CONTRIBUTING.md review item
FR-095 spec-driven expectations stated Inspection same
FR-096 conduct expectations Inspection CODE_OF_CONDUCT.md present with a reporting address
FR-097 bug form requires environment facts Inspection issue form fields marked required
FR-098 feature form asks for the goal, shows scope Inspection issue form review item
FR-099 change checklist Inspection pull-request template
FR-100 expected response stated Inspection CONTRIBUTING.md review item
FR-101 semver from 1.0.0 Release version input validated; first release is 1.0.0
FR-101a breaking change defined over the contract surface Inspection contracts/versioning.md
FR-102 hand-written user-facing changelog Inspection changelog review item
FR-102a [Unreleased] section maintained CI changelog check: the section exists and is non-empty when the change touches src/
FR-103 tag, runtime version and entry agree Release + E2E workflow asserts all three; e2e_version_matches_metadata asserts the runtime half
FR-104 non-release build identifies its source Unit + E2E compose_version unit-tested over its inputs; e2e_version_reports_build
FR-105 one triggered workflow, no manual steps Release the workflow (R36)
FR-106 artefact set published Release upload step asserts the five files
FR-107 Arch recipe in step Release recipe regenerated from the published artefacts
FR-108 integrity values published Release SHA256SUMS generated and verified after upload
FR-109 conventional locations, declared dependencies, clean install Release install-and-run smoke test in a clean container of each family
FR-109a built on oldest supported, matrix published Release build containers pinned; smoke test on oldest and current
FR-110 refuses on a dirty tree, existing tag, or red checks; re-runnable Release preconditions at the top of the workflow
FR-111 packager has what they need Inspection release notes carry dependencies, build steps and install map
FR-112 start record with version E2E e2e_records_start_with_version
FR-113 stop record with cause E2E e2e_records_stop_on_signal, e2e_records_stop_on_fatal_startup
FR-114 existing diagnostics unchanged Unit + E2E Condition policy tests; existing E2E suite unchanged and still passing
FR-115 where the compositor collects output Inspection troubleshooting page review item
FR-116 environment report on demand E2E e2e_environment_report
FR-117 old configuration not reinterpreted E2E e2e_config_from_previous_release
FR-118 compositor version mismatch named Unit + E2E version parse tests; e2e_unsupported_compositor_version
FR-119 private security channel Inspection SECURITY.md review item
FR-120 supported versions published Inspection same
FR-121 dependency policy stated Inspection CONTRIBUTING.md review item

Requirements of features 001 and 002 — the program itself

Derived from those features’ own E2E coverage mappings in
001-workspace-swap-overlay/plan.md
and
002-overlay-visuals/plan.md,
which remain authoritative for what each test drives. The overwhelming majority are E2E, because
the overwhelming majority describe what the program does when a real person presses a real key
against a real compositor — and that is the only place such a claim can honestly be checked.

Requirement Tier Verified by
FR-001 overlay opens on the switcher shortcut E2E e2e_activate_same_monitor
FR-002 stays open while the modifier is held E2E e2e_activate_same_monitor
FR-002a holds exclusive keyboard focus E2E e2e_focus_returns_on_close
FR-003 a tap advances the highlight E2E e2e_navigation_wraps_and_reverses, e2e_repeat_trigger_advances
FR-004 the highlight moves backwards E2E e2e_navigation_wraps_and_reverses
FR-004a the in-overlay keys are fixed E2E e2e_navigation_wraps_and_reverses
FR-005 commits on release E2E e2e_activate_same_monitor, e2e_fast_tap_commits
FR-006 cancellable without changing workspaces E2E e2e_cancel_leaves_state
FR-007 lists every ordinary workspace E2E e2e_grid_empty_workspace, e2e_special_workspaces_excluded
FR-008 indicates the highlight and the active workspace Unit ui/layout.rs highlight-index tests; a visual property 001 R14 rules out asserting by screenshot
FR-008a entry order is configurable E2E e2e_mru_order_and_highlight, e2e_configured_order
FR-008b MRU opens the highlight on the second entry E2E e2e_mru_order_and_highlight, e2e_configured_order
FR-008c an activation history is maintained E2E e2e_external_switch_tracked
FR-008d never-active workspaces still appear E2E e2e_mru_order_and_highlight
FR-009 same-monitor selection switches E2E e2e_activate_same_monitor, e2e_swap_single_monitor_degrades
FR-010 cross-monitor selection swaps E2E e2e_swap_active_workspaces, e2e_swap_inactive_target
FR-011 selecting the active workspace does nothing E2E e2e_select_active_is_noop
FR-012 a swap loses no window E2E e2e_swap_active_workspaces
FR-013 both monitors active after a swap E2E e2e_swap_active_workspaces
FR-013a a swap is all-or-nothing E2E e2e_swap_rollback_on_failure
FR-013b a rolled-back swap is reported E2E e2e_swap_rollback_on_failure
FR-013c a failed rollback is reported Unit injected double failure in actions.rs — provoking it end-to-end would mean corrupting the compositor
FR-014 flat list presentation E2E e2e_list_shows_window_names
FR-015 grid presentation E2E e2e_grid_miniature_layout
FR-015a miniatures are schematic and to scale E2E e2e_grid_miniature_layout, e2e_grid_offscreen_workspace
FR-015b long titles truncate visibly E2E e2e_title_truncation
FR-016 presentation is configurable, both commit alike E2E e2e_grid_commit_matches_list
FR-017 placement is configurable E2E e2e_placement_all_monitors
FR-018 renders above all other windows E2E e2e_above_fullscreen
FR-019 fixed readable size; scrolls rather than shrinks E2E e2e_scrolls_many_workspaces, e2e_overlay_scales_with_the_monitor
FR-020 new-workspace shortcut jumps to the lowest unused E2E e2e_new_workspace_lowest_unused
FR-021 no-op when already on an empty one E2E e2e_new_workspace_noop_when_empty
FR-022 exactly two named shortcuts E2E the_application_registers_both_named_shortcuts
FR-022a commit-on-release is mandatory E2E e2e_activate_same_monitor, a_held_modifier_with_taps_is_delivered_as_one_gesture
FR-022b documents the exact bind lines; starts unbound E2E + Unit e2e_unbound_shortcut_is_harmless for starting unbound; the_documented_bind_lines_are_the_ones_this_module_generates for the documented lines
FR-022c sticky mode without a modifier E2E e2e_sticky_mode_commits_on_enter
FR-023 documented defaults with no configuration file E2E e2e_defaults_without_config
FR-024 invalid values reported, per-setting fallback E2E e2e_invalid_config_falls_back
FR-025 unreachable compositor reported, non-zero exit E2E e2e_no_compositor_at_start
FR-025a a second instance is refused E2E e2e_second_instance_refuses_to_start
FR-026 external changes are reflected E2E e2e_external_switch_tracked
FR-026a connection loss is survived E2E e2e_reconnects_after_restart
FR-026b state is rebuilt on reconnect E2E e2e_reconnects_after_restart
FR-026c history is discarded and rebuilt E2E e2e_reconnects_after_restart
FR-026d disconnected retries are bounded E2E e2e_no_overlay_while_disconnected
FR-027 a vanished target cancels the commit E2E e2e_vanished_target_cancels, e2e_monitor_removed_degrades
FR-028 re-triggering does not stack overlays E2E e2e_repeat_trigger_advances
FR-029 every diagnostic goes to standard error E2E e2e_invalid_config_falls_back
FR-030 notifications for what the user must act on E2E e2e_invalid_config_falls_back, e2e_version_and_help
FR-031 self-recovered conditions are not notified E2E asserted as part of e2e_reconnects_after_restart; the notification policy itself is unit-tested in diag.rs
FR-032 runs on without a notification service E2E e2e_no_notification_daemon
FR-033 starts with no arguments; --version/–help E2E e2e_version_and_help
FR-034 --config names an alternative file E2E e2e_explicit_config_path_is_used_and_must_exist
FR-035 every window carries its program icon E2E e2e_icons_in_flat_list
FR-036 the icon precedes the name in the list E2E e2e_icons_in_flat_list, e2e_icons_keep_row_height_and_count
FR-036a icons occupy row space, truncating sooner E2E e2e_icons_truncate_names_sooner
FR-037 icons are drawn inside grid rectangles E2E e2e_icons_in_grid_miniatures
FR-038 a small rectangle drops title, then icon E2E e2e_miniature_drops_title_then_icon
FR-039 icons scale without distorting aspect Unit icons/decode.rs against computed rectangles (001 R14)
FR-040 the icon follows the window’s program identity E2E e2e_icons_in_flat_list
FR-040a both raster and vector icons decode E2E e2e_vector_icon_renders, e2e_raster_icon_renders
FR-041 a placeholder where nothing resolves E2E e2e_icon_placeholder_for_unknown_program, e2e_no_icon_set_installed
FR-042 resolution happens once per program, cached E2E e2e_icon_resolved_once_per_program
FR-043 resolution precedes the overlay opening E2E e2e_icons_resolved_before_overlay_opens
FR-043a an unresolved icon shows the placeholder E2E e2e_icons_resolved_before_overlay_opens
FR-043b icons are held in memory, never written to disk E2E e2e_no_icon_cache_on_disk
FR-044 a malformed icon is reported once E2E e2e_malformed_icon_reported_once
FR-045 eleven colours are configurable E2E e2e_builtin_theme_applies
FR-046 font family and text size are configurable E2E e2e_font_override_applies
FR-047 the geometry values are configurable E2E e2e_geometry_override_resizes, e2e_grid_geometry_override
FR-048 a theme applies to both presentations, every monitor E2E e2e_builtin_theme_applies, e2e_theme_on_all_monitors
FR-049 built-in themes selectable by name E2E e2e_theme_switch_does_not_move_layout
FR-049a the default appearance is unchanged, byte for byte E2E e2e_refactor_is_pixel_neutral, e2e_default_appearance_unchanged
FR-050 any single style value is overridable E2E e2e_colour_override_wins_over_theme, e2e_overrides_without_theme
FR-051 program artwork is never recoloured Unit icons/decode.rs — artwork is drawn as supplied (001 R14)
FR-052 the icon slot follows the themed text height Unit ui/layout.rs icon-slot tests against computed rectangles (001 R14)
FR-053 layout guarantees survive icons and theming E2E e2e_builtin_theme_applies, e2e_geometry_override_still_caps_and_scrolls
FR-054 every geometry value has a documented range, clamped E2E e2e_out_of_range_geometry_clamped
FR-055 themed geometry uses the same units and scaling E2E e2e_geometry_override_resizes, e2e_geometry_scales_with_monitor
FR-056 icons can be turned off E2E e2e_icons_disabled_matches_pre_feature
FR-057 the icon set is selectable, independent of theme E2E e2e_icon_set_selected, e2e_unknown_icon_set_falls_back
FR-058 an unknown theme name falls back and is reported E2E e2e_unknown_theme_falls_back
FR-059 an unparseable visual value falls back alone E2E e2e_invalid_value_falls_back_alone
FR-060 visual settings are read once, at start-up E2E e2e_visual_settings_need_restart
FR-061 every visual setting is documented Unit the catalogue walk in theme.rs against contracts/style-values.md

The seven that are not end-to-end, and why

Six of them are pixel properties — that the highlight is visible, that an icon keeps its aspect
ratio, that artwork is not recoloured, that the icon slot follows the text height. Asserting those
end-to-end would mean comparing screenshots, which was considered and rejected as brittle across
fonts, scaling and compositor versions. They are unit-tested against computed rectangles instead,
and confirmed by eye on the quickstart walk.

One, FR-013c, is the failure of a rollback — provoking it end-to-end would mean corrupting the
compositor mid-swap, so it is unit-tested against an injected double failure.

FR-061 is documentation completeness, which no end-to-end test could see. It is the catalogue
walk: a unit test reads the published style catalogue and compares it against the const tables
theme.rs actually resolves from. Adding a setting without documenting it fails
cargo test --lib — which is the same mechanism that keeps the configuration
and appearance pages honest.

What is measured rather than tested

Three of the project’s success criteria are human measurements, not checks: how long it takes a
newcomer to get an overlay on screen, how long to get a test suite running, and whether a user can
assemble a custom appearance from the documentation alone. These are walked once along the published
path and recorded, in the same way feature 001 measures its own usability criterion. A number that
can only be got by watching a person is not improved by automating something adjacent to it.