Rust dependency policy

No command parser, async runtime or web UI runtime is used. What each dependency is for is listed below.

On Unix development hosts, clock-windows directly uses the already locked libc crate for descriptor-relative, no-follow inventory report opens. This prevents report and parent-directory link swaps during portable summary tests. It uses the maintained rust-lang bindings with default features and their MIT/Apache-2.0 license choice; it adds no dependency to shipped Windows binaries.

Windows uses the in-box shlwapi.dll function SHDeleteEmptyKeyW to prune only empty protocol registry keys, preserving unrelated values and subkeys. Summary publication uses ntdll.dll handle-relative file operations so an output-path substitution cannot redirect the write. Neither DLL is bundled with the app.

Commit Cargo.lock and use —locked for all checks/builds. New dependencies must explain product need, maintenance, feature selection and license impact. Update in a dedicated PR against the default branch. Run the Linux and Windows jobs and the advisory/license inventory checks. Do not raise the declared rust-version merely to absorb an update; record the justification if it changes. Transitive updates need the same checks. No audit failure is silently suppressed; any exception needs a reviewed, dated rationale and remediation issue.

Dependabot follows the default branch for both GitHub Actions and the root Cargo workspace. GitHub Actions updates are checked daily and Cargo updates weekly, with separate dependency PRs and the default open-PR limit.

CI cargo-audit denies warnings; unavailable advisory data is a failure. License checks fail on terms outside the explicit reviewed set or with missing original LICENSE/COPYING/NOTICE text; CI does not upload the inventory. Regenerate it on demand with cargo metadata --locked --format-version 1 > dependency-metadata.json and python3 scripts/rust-license-check.py dependency-metadata.json. Review the inventory on updates. SPDX metadata is not a substitute for shipping attribution. The inventory script is development-only. Release packaging must retain applicable notices and satisfy the selected terms for each dependency.

The root LICENSE and workspace metadata declare Apache 2.0 for the original Rust implementation. Licensing explains that scope. The GPLv3 Python code and inherited artwork were removed at cutover and remain in Git history (migration guide); the active icon is original Apache-licensed artwork. Dependency licenses and original notices are unchanged. The packaging workflow includes the original inventory and toolchain notices in every package. The source is the tagged commit on GitHub, and Cargo.lock pins the exact dependency versions.

Releases do not ship dependency source, because none of the allowed licenses require it: every license in the checker’s allowlist is permissive, and where LGPL is offered as an alternative, MIT is selected. A dependency whose license requires source distribution (for example MPL-2.0, or (L)GPL without a permissive alternative) must not be added without revisiting this decision. The license checker’s allowlist rejects these today. CI uploads one runnable development build (elevenclock-dev-x64) for testing, and test evidence (screenshots, JSON, logs) only when a run fails; neither is a release package or installer.

The notice checker recognizes only explicit historical dual-license aliases: MIT/Apache-2.0, Apache-2.0 / MIT and Unlicense/MIT. They correspond to the already reviewed OR choices; arbitrary slash expressions remain rejected. For rustix/linux-raw-sys’s Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT and zerocopy/zerocopy-derive’s BSD-2-Clause OR Apache-2.0 OR MIT, this project selects the MIT alternative. Acceptance of these exact OR expressions does not approve standalone BSD-2-Clause, the LLVM exception, new exceptions, or arbitrary expressions containing MIT. Unrecognized terms still fail review.

The version-specific supplemental notice manifest restores anes 0.1.6’s omitted original license files and recognizes r-efi 6.0.0’s bundled AUTHORS license/copyright text. Source commits and digests are retained; missing, changed, unreadable or empty notices fail the check. These are retained original notices, not missing-notice exemptions. The checker uses no network. Run python3 scripts/test-rust-license-check.py for its positive and rejection regressions; the dependency CI job runs them before the inventory.

windows-bindgen, windows-core and windows-numerics are on the 0.100 line. The bindings are generated against windows-core, so the three must stay on matching versions and Dependabot updates them as one group. A version bump regenerates the bindings (cargo run -p clock-bindgen --locked) in the same PR; CI fails when the checked-in file differs from a fresh generation.

Criterion 0.8 (MSRV 1.86) adds alloca, which compiles a small C file, and page_size → winapi, whose winapi-*-pc-windows-gnu import-library crates publish no license files; their original notices are supplemented under dependency-notices. Because alloca needs the MSVC toolchain for x86_64-pc-windows-msvc, the Windows-target clippy runs on the Windows CI runner instead of cross-checking from Linux.

What each dependency is for

The manual release check uses the Windows OS component WinHTTP (winhttp.dll), under ADR 0003. It adds no crate or bundled notice; JSON uses the existing serde_json dependency. The launcher still forbids network DLLs.

Optional features

Presentation templates

The template workflow adds no packages or service. The core uses bounded value parsing; the existing Serde/JSON dependencies store named local presets. The website uses plain JavaScript and URL fragments, with no upload or fetch. Sharing copies a link only on request. Opening the editor explicitly uses the default browser. Per-user protocol registration and the bounded single-instance handoff use generated Shell/registry/window APIs; no background worker, network client, polling timer or vendor endpoint is added. Only presentation fields cross the template boundary; Apply retains its existing validation and persistence rules.

A heavyweight or network-dependent capability requires an explicit design decision covering product need, dependency size/maintenance/license impact, data collected and transmitted (destination, consent, retention and diagnostic redaction), and ownership of background work, cancellation, timeouts, failure recovery and shutdown. Record how disabling it removes its work and resources, and how it behaves offline. The default app must remain usable offline without network access or mandatory accounts unless a deliberate reviewed product-policy change says otherwise. An optional feature must not silently add startup traffic or background polling. Use the contributor extension checklist and the existing dependency checks; this policy introduces no plugin system or optional-feature framework.

Managed local inventory

clock-launcher reuses the existing serde 1.0 (derive) and serde_json 1.0 versions and features for bounded inventory JSON; there are no new packages or license terms. Both are maintained upstream and already used for preference persistence. The lockfile only adds these existing packages to the launcher’s dependency edges. Windows fact helpers use generated in-box Advapi32/Ole32/Version APIs, without a new Rust dependency. Version.dll is allowed for fixed local executable version lookup. Account lookup uses Advapi32 and GUID generation uses Ole32. These helpers run only after explicit administrator opt-in, inside the bounded inventory process. No network client is added. Optional central drop-box reporting uses normal file I/O inside the same bounded helper; it adds no HTTP/network client dependency or persistent service.

The launcher’s direct clock-core dependency reuses the workspace’s existing format validator and preset catalog for optional managed format inventory and aggregation; it adds no packages, versions or license terms.