feat: ship cheap fixture lanes and release controls#405
Conversation
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
Summary by CodeRabbitRelease Notes: v0.6.0
WalkthroughThe PR introduces version 0.6.0 with a new Changes
Sequence DiagramsequenceDiagram
actor User
participant build.rs as build.rs Script
participant uselesskey_cli as uselesskey_cli::materialize
participant Factory as Core Factory
participant FileSystem as File Output
participant Module as fixtures.rs Module
User->>build.rs: Runs cargo build
build.rs->>uselesskey_cli: load_materialize_manifest(path)
uselesskey_cli->>uselesskey_cli: parse TOML manifest
uselesskey_cli-->>build.rs: MaterializeManifest
build.rs->>uselesskey_cli: materialize_manifest_to_dir(manifest, out_dir, false)
loop For each fixture in manifest
uselesskey_cli->>Factory: generate deterministic bytes<br/>(entropy/token/rsa/pem/ssh)
Factory-->>uselesskey_cli: fixture bytes
uselesskey_cli->>FileSystem: write fixture file<br/>(entropy.bin, token.txt, etc.)
end
uselesskey_cli-->>build.rs: MaterializeSummary
build.rs->>uselesskey_cli: emit_include_bytes_module(manifest, out_dir, fixtures.rs)
uselesskey_cli->>FileSystem: generate fixtures.rs with include_bytes!
uselesskey_cli-->>Module: module code
build.rs->>FileSystem: include! fixtures.rs
FileSystem-->>build.rs: ENTROPY, TOKEN, RSA_PKCS8_DER, etc. as byte slices
build.rs-->>User: lib.rs built with fixtures available
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 214ac01247
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| entry.first_check_ms as f64 / 1000.0, | ||
| entry.repeat_check_ms as f64 / 1000.0, |
There was a problem hiding this comment.
Remove volatile timing fields from committed economics docs
The docs table is generated from wall-clock measurements (first_check_ms / repeat_check_ms), which are inherently non-deterministic across runs; because CI now enforces git diff --exit-code on docs/reference/dependency-economics.md, this can fail even when source code is unchanged (the measured seconds will drift between machines/runs). This makes the new drift gate flaky-to-blocking for normal PRs, so the committed docs should exclude volatile timing values (or the drift check should ignore that generated section/file).
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
crates/uselesskey/README.md (2)
49-101:⚠️ Potential issue | 🟡 MinorFix markdown fence spacing to satisfy MD031.
The dependency-snippet section has fenced blocks not surrounded by blank lines, which is flagged by markdownlint.
Example of required spacing (apply similarly to each snippet block)
- **Token-only** + ```toml [dev-dependencies] uselesskey = { version = "0.6.0", default-features = false, features = ["token"] }
</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@crates/uselesskey/README.mdaround lines 49 - 101, Each fenced code block in
the dependency snippets (e.g., the blocks after headings like "Quick start
(RSA)", "Token-only", "JWT/JWK", "X.509 + rustls", "jsonwebtoken adapter",
"JOSE/OpenID adapter", "pgp-native adapter") must be surrounded by blank lines
to satisfy MD031; edit README.md so there is an empty line immediately before
each opening triple-backtick and an empty line immediately after each closing
triple-backtick for every snippet in the dependency-snippets section.</details> --- `193-200`: _⚠️ Potential issue_ | _🟡 Minor_ **`full` feature description is now stale.** The README still describes `full` without `entropy`, but `Cargo.toml` now includes it. Please update the row to avoid misleading consumers. <details> <summary>Suggested doc fix</summary> ```diff -| `full` | Everything (`all-keys` + `token` + `x509` + `jwk`) | +| `full` | Everything (`entropy` + `all-keys` + `token` + `x509` + `jwk`) |🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/uselesskey/README.md` around lines 193 - 200, Update the `full` feature description in the README table to reflect that `entropy` is now included; replace the current "Everything (`all-keys` + `token` + `x509` + `jwk`)" text for the `full` row with "Everything (`all-keys` + `token` + `x509` + `jwk` + `entropy`)" so the `full` feature accurately lists `entropy` alongside `all-keys`, `token`, `x509`, and `jwk`.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/ci.yml:
- Around line 94-114: Add a cleanup step that removes cached receipt outputs
(e.g., rm -f target/xtask/economics/latest.*
target/xtask/audit-surface/latest.*) before running the receipt generation steps
and before the upload step so stale files can't be uploaded; insert a new step
named like "clean cached receipts" immediately before the "economics receipt"
and "audit-surface receipt" runs and also before the "Upload lane receipts"
step, and replicate the same cleanup in the other workflow block referenced (the
second pr/main block around the other occurrence) to ensure both PR and main
runs remove old latest.* files first.
In `@crates/materialize-buildrs-example/build.rs`:
- Around line 1-4: Add the crate-level attribute to prohibit unsafe code by
inserting the attribute directive at the top of the file before any items (i.e.,
above the existing use statements); specifically add the crate attribute
forbidding unsafe code so the crate-level directive applies to the whole file
containing the main function and the use declarations.
In `@crates/materialize-buildrs-example/src/lib.rs`:
- Around line 1-3: Add a crate-level forbid for unsafe code by inserting
#![forbid(unsafe_code)] at the top of this crate root (the file that contains
the include!(concat!(env!("OUT_DIR"), "/fixtures.rs")) and #[cfg(test)]), so the
generated source pulled in by include! is covered by the workspace safety
guarantee; place the attribute before any items or includes in this file.
In `@crates/materialize-shape-buildrs-example/build.rs`:
- Around line 1-5: Add the crate-level unsafe-code guard by inserting the
attribute #![forbid(unsafe_code)] at the top of the build script (before any use
statements) so the build.rs file enforces the workspace ban on unsafe code;
update the file that contains the main function in build.rs to include this
attribute above the existing items.
In `@crates/materialize-shape-buildrs-example/src/lib.rs`:
- Line 1: Add the crate-level attribute to forbid unsafe code by placing
#![forbid(unsafe_code)] at the top of this crate root (above the existing
include!(concat!(env!("OUT_DIR"), "/fixtures.rs")) line) so the crate-level
policy is enforced; ensure the attribute appears before any other items in
lib.rs to apply globally.
In `@crates/uselesskey-cli/src/lib.rs`:
- Around line 496-512: The SshPublicKeyShape branch
(MaterializeKind::SshPublicKeyShape) returns 32 random bytes encoded as an
"ssh-ed25519" blob using Seed::from_text, BASE64_STD.encode, and
normalize_ssh_comment, but that output is not a valid Ed25519 public key
structure; add a concise doc comment near the SshPublicKeyShape branch or the
function that emits this blob clarifying that this is a shape-only/test fixture
and not a cryptographically valid Ed25519 public key, and mention it
intentionally produces 32 random bytes rather than the real SSH key format so
future readers won't assume validity.
In `@docs/how-to/choose-features.md`:
- Around line 33-86: The fenced TOML code blocks under the "Dependency
snippets:" section (each ```toml ... ```) are missing surrounding blank lines
which triggers MD031; fix by adding a blank line before the opening ```toml and
a blank line after the closing ``` for every snippet (e.g., the blocks under the
"- **Quick start (RSA)**", "- **Token-only**", "- **JWT/JWK**", "- **X.509 +
rustls**", "- **jsonwebtoken adapter**", and "- **JOSE/OpenID adapter**", "-
**pgp-native adapter**" headings) so each fenced block is separated from
adjacent text and list items.
In `@docs/metadata/workspace-docs.json`:
- Line 1121: You added "entropy" to public_features but didn't add its
corresponding metadata entries; update the synced metadata by adding a matching
facade_feature_matrix row for "entropy" (so facade_feature_matrix includes the
new public lane entry) and add entropy-focused snippet/example metadata and
README/choose-features content references so the generated README and
choose-features docs include usage examples and description for the entropy
feature. Ensure identifiers match "entropy" and the existing schema used for
other features so the sync process picks up the new lane.
In `@README.md`:
- Around line 121-125: The README snippet assumes the binary is run from this
workspace (uses cargo run -p uselesskey-cli) and points at an internal manifest
path, which breaks for downstream users; update the example to instruct users to
either run the installed binary (uselesskey-cli) or run cargo with an explicit
manifest path, and change the manifest path to a generic/local file (e.g.,
./uselesskey-fixtures.toml) so the materialize and verify commands (materialize,
verify) are copy-pasteable outside this repo; mention installing the CLI (cargo
install or equivalent) or using cargo run with --manifest-path to make the
example portable.
In `@xtask/src/audit_surface.rs`:
- Around line 125-152: The matched_markers function currently embeds hardcoded
version-prefix checks (e.g., "rsa v0.9.", "rsa v0.10.", "jsonwebtoken v", etc.),
which makes updates error-prone; refactor by extracting these string literals
into named constants or a small static map/array (e.g., MARKER_PATTERNS or
RSA_LEGACY_PREFIX, RSA_MODERN_PREFIX, JSONWEBTOKEN_PREFIX, X509_STACK_PREFIX)
and update matched_markers to iterate over those patterns to insert the
corresponding marker strings, keeping the matching logic (trimmed.starts_with)
but centralizing patterns for easier maintenance and future updates.
In `@xtask/src/economics.rs`:
- Around line 196-222: The duration conversion in run_cargo currently does let
duration_ms = start.elapsed().as_millis() as u64 which can overflow when casting
u128 to u64; change this to a defensive conversion (e.g., use
try_into().unwrap_or(u64::MAX) or a saturating cast) when converting
start.elapsed().as_millis() to u64 so duration_ms is set safely; update the
assignment to duration_ms in the run_cargo function (referencing
Instant::elapsed, duration_ms, and the CommandRun return) to use the safe
conversion.
---
Outside diff comments:
In `@crates/uselesskey/README.md`:
- Around line 49-101: Each fenced code block in the dependency snippets (e.g.,
the blocks after headings like "Quick start (RSA)", "Token-only", "JWT/JWK",
"X.509 + rustls", "jsonwebtoken adapter", "JOSE/OpenID adapter", "pgp-native
adapter") must be surrounded by blank lines to satisfy MD031; edit README.md so
there is an empty line immediately before each opening triple-backtick and an
empty line immediately after each closing triple-backtick for every snippet in
the dependency-snippets section.
- Around line 193-200: Update the `full` feature description in the README table
to reflect that `entropy` is now included; replace the current "Everything
(`all-keys` + `token` + `x509` + `jwk`)" text for the `full` row with
"Everything (`all-keys` + `token` + `x509` + `jwk` + `entropy`)" so the `full`
feature accurately lists `entropy` alongside `all-keys`, `token`, `x509`, and
`jwk`.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 78769bb0-9731-4838-baf7-381eb801d3b9
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (96)
.github/workflows/ci.ymlCHANGELOG.mdCargo.tomlREADME.mdcrates/materialize-buildrs-example/Cargo.tomlcrates/materialize-buildrs-example/build.rscrates/materialize-buildrs-example/src/lib.rscrates/materialize-buildrs-example/uselesskey-fixtures.tomlcrates/materialize-shape-buildrs-example/Cargo.tomlcrates/materialize-shape-buildrs-example/build.rscrates/materialize-shape-buildrs-example/src/lib.rscrates/materialize-shape-buildrs-example/uselesskey-fixtures.tomlcrates/uselesskey-aws-lc-rs/Cargo.tomlcrates/uselesskey-aws-lc-rs/README.mdcrates/uselesskey-axum/Cargo.tomlcrates/uselesskey-bdd-steps/Cargo.tomlcrates/uselesskey-cli/Cargo.tomlcrates/uselesskey-cli/README.mdcrates/uselesskey-cli/src/lib.rscrates/uselesskey-cli/src/main.rscrates/uselesskey-cli/tests/cli.rscrates/uselesskey-core-base62/Cargo.tomlcrates/uselesskey-core-cache/Cargo.tomlcrates/uselesskey-core-factory/Cargo.tomlcrates/uselesskey-core-hash/Cargo.tomlcrates/uselesskey-core-hmac-spec/Cargo.tomlcrates/uselesskey-core-id/Cargo.tomlcrates/uselesskey-core-jwk-builder/Cargo.tomlcrates/uselesskey-core-jwk-shape/Cargo.tomlcrates/uselesskey-core-jwk/Cargo.tomlcrates/uselesskey-core-jwks-order/Cargo.tomlcrates/uselesskey-core-keypair-material/Cargo.tomlcrates/uselesskey-core-keypair/Cargo.tomlcrates/uselesskey-core-kid/Cargo.tomlcrates/uselesskey-core-negative-der/Cargo.tomlcrates/uselesskey-core-negative-pem/Cargo.tomlcrates/uselesskey-core-negative/Cargo.tomlcrates/uselesskey-core-rustls-pki/Cargo.tomlcrates/uselesskey-core-seed/Cargo.tomlcrates/uselesskey-core-sink/Cargo.tomlcrates/uselesskey-core-token-shape/Cargo.tomlcrates/uselesskey-core-token/Cargo.tomlcrates/uselesskey-core-x509-chain-negative/Cargo.tomlcrates/uselesskey-core-x509-derive/Cargo.tomlcrates/uselesskey-core-x509-negative/Cargo.tomlcrates/uselesskey-core-x509-spec/Cargo.tomlcrates/uselesskey-core-x509/Cargo.tomlcrates/uselesskey-core/Cargo.tomlcrates/uselesskey-ecdsa/Cargo.tomlcrates/uselesskey-ed25519/Cargo.tomlcrates/uselesskey-entropy/Cargo.tomlcrates/uselesskey-entropy/README.mdcrates/uselesskey-entropy/src/lib.rscrates/uselesskey-feature-grid/Cargo.tomlcrates/uselesskey-hmac/Cargo.tomlcrates/uselesskey-jose-openid/Cargo.tomlcrates/uselesskey-jsonwebtoken/Cargo.tomlcrates/uselesskey-jsonwebtoken/README.mdcrates/uselesskey-jwk/Cargo.tomlcrates/uselesskey-pgp-native/Cargo.tomlcrates/uselesskey-pgp/Cargo.tomlcrates/uselesskey-pkcs11-mock/Cargo.tomlcrates/uselesskey-ring/Cargo.tomlcrates/uselesskey-ring/README.mdcrates/uselesskey-rsa/Cargo.tomlcrates/uselesskey-rustcrypto/Cargo.tomlcrates/uselesskey-rustcrypto/README.mdcrates/uselesskey-rustls/Cargo.tomlcrates/uselesskey-rustls/README.mdcrates/uselesskey-ssh/Cargo.tomlcrates/uselesskey-test-grid/Cargo.tomlcrates/uselesskey-test-server/Cargo.tomlcrates/uselesskey-token-spec/Cargo.tomlcrates/uselesskey-token/Cargo.tomlcrates/uselesskey-tonic/Cargo.tomlcrates/uselesskey-tonic/README.mdcrates/uselesskey-webauthn/Cargo.tomlcrates/uselesskey-webhook/Cargo.tomlcrates/uselesskey-x509/Cargo.tomlcrates/uselesskey/Cargo.tomlcrates/uselesskey/README.mdcrates/uselesskey/src/lib.rsdocs/README.mddocs/how-to/choose-features.mddocs/how-to/choose-lane.mddocs/how-to/downstream-fixture-policy.mddocs/how-to/migration.mddocs/how-to/release.mddocs/metadata/workspace-docs.jsondocs/reference/audit-surface.mddocs/reference/dependency-economics.mddocs/reference/support-matrix.mdtests/Cargo.tomlxtask/src/audit_surface.rsxtask/src/economics.rsxtask/src/main.rs
| - name: economics receipt | ||
| run: cargo xtask economics | ||
|
|
||
| - name: audit-surface receipt | ||
| run: cargo xtask audit-surface | ||
|
|
||
| - name: receipt docs drift check | ||
| run: git diff --exit-code -- docs/reference/dependency-economics.md docs/reference/audit-surface.md | ||
|
|
||
| - name: Upload lane receipts | ||
| uses: actions/upload-artifact@v7 | ||
| with: | ||
| name: lane-receipts-pr | ||
| path: | | ||
| target/xtask/economics/latest.json | ||
| target/xtask/economics/latest.md | ||
| target/xtask/audit-surface/latest.json | ||
| target/xtask/audit-surface/latest.md | ||
| docs/reference/dependency-economics.md | ||
| docs/reference/audit-surface.md | ||
| if: always() |
There was a problem hiding this comment.
Clean cached receipt outputs before the always-run upload.
These artifacts come from target/xtask/..., and Upload lane receipts still runs after earlier failures. That makes it possible to publish stale latest.* files instead of receipts generated by the current run.
🧹 Suggested hardening
Apply the same cleanup in both pr and main before the receipt commands:
+ - name: Clean lane receipt outputs
+ run: rm -rf target/xtask/economics target/xtask/audit-surface
+
- name: economics receipt
run: cargo xtask economicsAlso applies to: 163-183
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/ci.yml around lines 94 - 114, Add a cleanup step that
removes cached receipt outputs (e.g., rm -f target/xtask/economics/latest.*
target/xtask/audit-surface/latest.*) before running the receipt generation steps
and before the upload step so stale files can't be uploaded; insert a new step
named like "clean cached receipts" immediately before the "economics receipt"
and "audit-surface receipt" runs and also before the "Upload lane receipts"
step, and replicate the same cleanup in the other workflow block referenced (the
second pr/main block around the other occurrence) to ensure both PR and main
runs remove old latest.* files first.
| use std::env; | ||
| use std::path::PathBuf; | ||
|
|
||
| fn main() { |
There was a problem hiding this comment.
Add crate-level unsafe prohibition.
This new Rust target should explicitly forbid unsafe code at crate root.
Suggested fix
+#![forbid(unsafe_code)]
+
use std::env;
use std::path::PathBuf;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| use std::env; | |
| use std::path::PathBuf; | |
| fn main() { | |
| #![forbid(unsafe_code)] | |
| use std::env; | |
| use std::path::PathBuf; | |
| fn main() { |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/materialize-buildrs-example/build.rs` around lines 1 - 4, Add the
crate-level attribute to prohibit unsafe code by inserting the attribute
directive at the top of the file before any items (i.e., above the existing use
statements); specifically add the crate attribute forbidding unsafe code so the
crate-level directive applies to the whole file containing the main function and
the use declarations.
| include!(concat!(env!("OUT_DIR"), "/fixtures.rs")); | ||
|
|
||
| #[cfg(test)] |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n crates/materialize-buildrs-example/src/lib.rsRepository: EffortlessMetrics/uselesskey
Length of output: 770
Add #![forbid(unsafe_code)] to crate root.
This crate root include!s generated source. The missing crate-level guard weakens the workspace safety guarantee for exactly the code this example materializes.
Proposed fix
+#![forbid(unsafe_code)]
+
include!(concat!(env!("OUT_DIR"), "/fixtures.rs"));As per coding guidelines, crates/**/src/{lib,main}.rs: Use #![forbid(unsafe_code)] in all Rust crate root modules.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| include!(concat!(env!("OUT_DIR"), "/fixtures.rs")); | |
| #[cfg(test)] | |
| #![forbid(unsafe_code)] | |
| include!(concat!(env!("OUT_DIR"), "/fixtures.rs")); | |
| #[cfg(test)] |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/materialize-buildrs-example/src/lib.rs` around lines 1 - 3, Add a
crate-level forbid for unsafe code by inserting #![forbid(unsafe_code)] at the
top of this crate root (the file that contains the
include!(concat!(env!("OUT_DIR"), "/fixtures.rs")) and #[cfg(test)]), so the
generated source pulled in by include! is covered by the workspace safety
guarantee; place the attribute before any items or includes in this file.
| use std::env; | ||
| use std::path::PathBuf; | ||
|
|
||
| fn main() { | ||
| println!("cargo::rerun-if-changed=build.rs"); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat crates/materialize-shape-buildrs-example/build.rsRepository: EffortlessMetrics/uselesskey
Length of output: 896
🏁 Script executed:
head -20 crates/materialize-shape-buildrs-example/build.rsRepository: EffortlessMetrics/uselesskey
Length of output: 896
🏁 Script executed:
git ls-files | grep -E "(Cargo.toml|rustfmt.toml|clippy.toml)" | head -20Repository: EffortlessMetrics/uselesskey
Length of output: 821
🏁 Script executed:
head -50 Cargo.tomlRepository: EffortlessMetrics/uselesskey
Length of output: 1698
🏁 Script executed:
cat crates/materialize-shape-buildrs-example/Cargo.tomlRepository: EffortlessMetrics/uselesskey
Length of output: 520
🏁 Script executed:
head -30 clippy.tomlRepository: EffortlessMetrics/uselesskey
Length of output: 119
🏁 Script executed:
grep -A 20 "^\[workspace.lints" Cargo.tomlRepository: EffortlessMetrics/uselesskey
Length of output: 54
🏁 Script executed:
grep -A 20 "^\[lints" Cargo.toml | head -30Repository: EffortlessMetrics/uselesskey
Length of output: 54
🏁 Script executed:
rg "forbid\(unsafe_code\)" --max-count 5Repository: EffortlessMetrics/uselesskey
Length of output: 5140
🏁 Script executed:
find . -name "build.rs" -type f -exec grep -l "forbid(unsafe_code)" {} \;Repository: EffortlessMetrics/uselesskey
Length of output: 54
🏁 Script executed:
find . -name "build.rs" -type fRepository: EffortlessMetrics/uselesskey
Length of output: 290
🏁 Script executed:
head -5 crates/materialize-buildrs-example/build.rsRepository: EffortlessMetrics/uselesskey
Length of output: 172
🏁 Script executed:
head -5 crates/uselesskey-aws-lc-rs/build.rsRepository: EffortlessMetrics/uselesskey
Length of output: 259
🏁 Script executed:
head -5 crates/uselesskey-bdd-steps/build.rsRepository: EffortlessMetrics/uselesskey
Length of output: 328
Add the crate-level unsafe-code guard to the build script.
This build script does not enforce the workspace unsafe ban. Per coding guidelines, all Rust crates must use #![forbid(unsafe_code)].
🛡️ Proposed fix
+#![forbid(unsafe_code)]
+
use std::env;
use std::path::PathBuf;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/materialize-shape-buildrs-example/build.rs` around lines 1 - 5, Add
the crate-level unsafe-code guard by inserting the attribute
#![forbid(unsafe_code)] at the top of the build script (before any use
statements) so the build.rs file enforces the workspace ban on unsafe code;
update the file that contains the main function in build.rs to include this
attribute above the existing items.
| @@ -0,0 +1,20 @@ | |||
| include!(concat!(env!("OUT_DIR"), "/fixtures.rs")); | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify all crate roots enforce forbid(unsafe_code)
fd -t f '^(lib|main)\.rs$' crates | while read -r f; do
if ! rg -n '^\s*#!\[forbid\(unsafe_code\)\]' "$f" >/dev/null; then
echo "MISSING forbid(unsafe_code): $f"
fi
doneRepository: EffortlessMetrics/uselesskey
Length of output: 227
Add #![forbid(unsafe_code)] to crate root
This file is missing the required #![forbid(unsafe_code)] attribute at the crate root, which is mandated for all Rust crate root modules.
🔧 Proposed fix
+#![forbid(unsafe_code)]
+
include!(concat!(env!("OUT_DIR"), "/fixtures.rs"));📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| include!(concat!(env!("OUT_DIR"), "/fixtures.rs")); | |
| #![forbid(unsafe_code)] | |
| include!(concat!(env!("OUT_DIR"), "/fixtures.rs")); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/materialize-shape-buildrs-example/src/lib.rs` at line 1, Add the
crate-level attribute to forbid unsafe code by placing #![forbid(unsafe_code)]
at the top of this crate root (above the existing
include!(concat!(env!("OUT_DIR"), "/fixtures.rs")) line) so the crate-level
policy is enforced; ensure the attribute appears before any other items in
lib.rs to apply globally.
| <!-- docs-sync:dependency-snippets-start --> | ||
| Dependency snippets: | ||
| - **Quick start (RSA)** | ||
| ```toml | ||
| [dev-dependencies] | ||
| uselesskey = { version = "0.5.1", features = ["rsa"] } | ||
| uselesskey = { version = "0.6.0", features = ["rsa"] } | ||
| ``` | ||
|
|
||
|
|
||
| - **Token-only** | ||
| ```toml | ||
| [dev-dependencies] | ||
| uselesskey = { version = "0.5.1", default-features = false, features = ["token"] } | ||
| uselesskey = { version = "0.6.0", default-features = false, features = ["token"] } | ||
| ``` | ||
|
|
||
|
|
||
| - **JWT/JWK** | ||
| ```toml | ||
| [dev-dependencies] | ||
| uselesskey = { version = "0.5.1", features = ["rsa", "jwk"] } | ||
| uselesskey = { version = "0.6.0", features = ["rsa", "jwk"] } | ||
| ``` | ||
|
|
||
|
|
||
| - **X.509 + rustls** | ||
| ```toml | ||
| [dev-dependencies] | ||
| uselesskey = { version = "0.5.1", features = ["x509"] } | ||
| uselesskey-rustls = { version = "0.5.1", features = ["tls-config", "rustls-ring"] } | ||
| uselesskey = { version = "0.6.0", features = ["x509"] } | ||
| uselesskey-rustls = { version = "0.6.0", features = ["tls-config", "rustls-ring"] } | ||
| ``` | ||
|
|
||
|
|
||
| - **jsonwebtoken adapter** | ||
| ```toml | ||
| [dev-dependencies] | ||
| uselesskey = { version = "0.5.1", features = ["rsa", "ecdsa", "ed25519", "hmac"] } | ||
| uselesskey-jsonwebtoken = { version = "0.5.1" } | ||
| uselesskey = { version = "0.6.0", features = ["rsa", "ecdsa", "ed25519", "hmac"] } | ||
| uselesskey-jsonwebtoken = { version = "0.6.0" } | ||
| ``` | ||
|
|
||
|
|
||
| - **JOSE/OpenID adapter** | ||
| ```toml | ||
| [dev-dependencies] | ||
| uselesskey = { version = "0.5.1", features = ["rsa", "ecdsa", "ed25519", "hmac"] } | ||
| uselesskey-jose-openid = { version = "0.5.1" } | ||
| uselesskey = { version = "0.6.0", features = ["rsa", "ecdsa", "ed25519", "hmac"] } | ||
| uselesskey-jose-openid = { version = "0.6.0" } | ||
| ``` | ||
|
|
||
|
|
||
| - **pgp-native adapter** | ||
| ```toml | ||
| [dev-dependencies] | ||
| uselesskey = { version = "0.5.1", features = ["pgp"] } | ||
| uselesskey-pgp-native = { version = "0.5.1" } | ||
| uselesskey = { version = "0.6.0", features = ["pgp"] } | ||
| uselesskey-pgp-native = { version = "0.6.0" } | ||
| ``` | ||
| <!-- docs-sync:dependency-snippets-end --> |
There was a problem hiding this comment.
Markdown fence spacing needs cleanup (MD031).
Several dependency snippet fences are missing surrounding blank lines and are currently lint-warning candidates.
Example fix pattern (repeat for each snippet block)
- **JWT/JWK**
+
```toml
[dev-dependencies]
uselesskey = { version = "0.6.0", features = ["rsa", "jwk"] }</details>
<details>
<summary>🧰 Tools</summary>
<details>
<summary>🪛 markdownlint-cli2 (0.22.0)</summary>
[warning] 36-36: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
---
[warning] 43-43: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
---
[warning] 50-50: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
---
[warning] 57-57: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
---
[warning] 65-65: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
---
[warning] 73-73: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
---
[warning] 81-81: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
</details>
</details>
<details>
<summary>🤖 Prompt for AI Agents</summary>
Verify each finding against the current code and only fix it if needed.
In @docs/how-to/choose-features.md around lines 33 - 86, The fenced TOML code
blocks under the "Dependency snippets:" section (each toml ... ) are
missing surrounding blank lines which triggers MD031; fix by adding a blank line
before the opening toml and a blank line after the closing for every
snippet (e.g., the blocks under the "- Quick start (RSA)", "-
Token-only", "- JWT/JWK", "- X.509 + rustls", "- jsonwebtoken
adapter", and "- JOSE/OpenID adapter", "- pgp-native adapter"
headings) so each fenced block is separated from adjacent text and list items.
</details>
<!-- fingerprinting:phantom:poseidon:hawk:4fb2f79d-4482-401e-9b1d-e2b4293ab7aa -->
<!-- This is an auto-generated comment by CodeRabbit -->
| "hmac", | ||
| "pgp", | ||
| "token", | ||
| "entropy", |
There was a problem hiding this comment.
entropy still needs the rest of its synced doc metadata.
Adding entropy to public_features here is only part of the update. There is still no matching facade_feature_matrix row or entropy-focused snippet/example metadata, so the synced README and choose-features docs will stay incomplete for the new public lane.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/metadata/workspace-docs.json` at line 1121, You added "entropy" to
public_features but didn't add its corresponding metadata entries; update the
synced metadata by adding a matching facade_feature_matrix row for "entropy" (so
facade_feature_matrix includes the new public lane entry) and add
entropy-focused snippet/example metadata and README/choose-features content
references so the generated README and choose-features docs include usage
examples and description for the entropy feature. Ensure identifiers match
"entropy" and the existing schema used for other features so the sync process
picks up the new lane.
| ```bash | ||
| # Build-time materialization, shape-only common lane | ||
| cargo run -p uselesskey-cli -- materialize --manifest crates/materialize-shape-buildrs-example/uselesskey-fixtures.toml --out-dir target/tmp-fixtures | ||
| cargo run -p uselesskey-cli -- verify --manifest crates/materialize-shape-buildrs-example/uselesskey-fixtures.toml --out-dir target/tmp-fixtures | ||
| ``` |
There was a problem hiding this comment.
Make the CLI example copy-pasteable for downstream users.
This snippet only works from this repository checkout: cargo run -p uselesskey-cli assumes the package is in the current workspace, and the manifest path points at a repo-internal example crate. Readers copying this into their own project will hit missing-package or missing-path errors.
📖 Suggested rewrite
- cargo run -p uselesskey-cli -- materialize --manifest crates/materialize-shape-buildrs-example/uselesskey-fixtures.toml --out-dir target/tmp-fixtures
- cargo run -p uselesskey-cli -- verify --manifest crates/materialize-shape-buildrs-example/uselesskey-fixtures.toml --out-dir target/tmp-fixtures
+ # After `cargo install uselesskey-cli`
+ uselesskey materialize --manifest ./uselesskey-fixtures.toml --out-dir ./target/uselesskey-fixtures
+ uselesskey verify --manifest ./uselesskey-fixtures.toml --out-dir ./target/uselesskey-fixtures📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ```bash | |
| # Build-time materialization, shape-only common lane | |
| cargo run -p uselesskey-cli -- materialize --manifest crates/materialize-shape-buildrs-example/uselesskey-fixtures.toml --out-dir target/tmp-fixtures | |
| cargo run -p uselesskey-cli -- verify --manifest crates/materialize-shape-buildrs-example/uselesskey-fixtures.toml --out-dir target/tmp-fixtures | |
| ``` |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@README.md` around lines 121 - 125, The README snippet assumes the binary is
run from this workspace (uses cargo run -p uselesskey-cli) and points at an
internal manifest path, which breaks for downstream users; update the example to
instruct users to either run the installed binary (uselesskey-cli) or run cargo
with an explicit manifest path, and change the manifest path to a generic/local
file (e.g., ./uselesskey-fixtures.toml) so the materialize and verify commands
(materialize, verify) are copy-pasteable outside this repo; mention installing
the CLI (cargo install or equivalent) or using cargo run with --manifest-path to
make the example portable.
| fn matched_markers(tree: &str) -> Vec<String> { | ||
| let mut matches = BTreeSet::new(); | ||
| for line in tree.lines() { | ||
| let trimmed = line.trim(); | ||
| if trimmed.starts_with("rsa v0.9.") { | ||
| matches.insert("rsa-legacy-0.9".to_string()); | ||
| } | ||
| if trimmed.starts_with("rsa v0.10.") { | ||
| matches.insert("rsa-modern-0.10".to_string()); | ||
| } | ||
| if trimmed.starts_with("jsonwebtoken v") { | ||
| matches.insert("jsonwebtoken".to_string()); | ||
| } | ||
| if trimmed.starts_with("pgp v") { | ||
| matches.insert("pgp".to_string()); | ||
| } | ||
| if trimmed.starts_with("ring v") { | ||
| matches.insert("ring".to_string()); | ||
| } | ||
| if trimmed.starts_with("rustls v") { | ||
| matches.insert("rustls".to_string()); | ||
| } | ||
| if trimmed.starts_with("x509-parser v") || trimmed.starts_with("rcgen v") { | ||
| matches.insert("x509-stack".to_string()); | ||
| } | ||
| } | ||
| matches.into_iter().collect() | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Version patterns in marker detection may need maintenance.
The hardcoded version prefixes (rsa v0.9., rsa v0.10., etc.) will need updates as dependencies evolve. Consider extracting these to constants or a configuration to make future maintenance easier.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@xtask/src/audit_surface.rs` around lines 125 - 152, The matched_markers
function currently embeds hardcoded version-prefix checks (e.g., "rsa v0.9.",
"rsa v0.10.", "jsonwebtoken v", etc.), which makes updates error-prone; refactor
by extracting these string literals into named constants or a small static
map/array (e.g., MARKER_PATTERNS or RSA_LEGACY_PREFIX, RSA_MODERN_PREFIX,
JSONWEBTOKEN_PREFIX, X509_STACK_PREFIX) and update matched_markers to iterate
over those patterns to insert the corresponding marker strings, keeping the
matching logic (trimmed.starts_with) but centralizing patterns for easier
maintenance and future updates.
| fn run_cargo(args: &[&str]) -> Result<CommandRun> { | ||
| let command = format!("cargo {}", args.join(" ")); | ||
| let start = Instant::now(); | ||
| let output = Command::new("cargo") | ||
| .args(args) | ||
| .output() | ||
| .with_context(|| format!("failed to run `{command}`"))?; | ||
| let duration_ms = start.elapsed().as_millis() as u64; | ||
|
|
||
| let status = if output.status.success() { | ||
| "ok" | ||
| } else { | ||
| "failed" | ||
| }; | ||
| let details = if output.status.success() { | ||
| None | ||
| } else { | ||
| Some(trim_command_output(&output.stderr, &output.stdout)) | ||
| }; | ||
|
|
||
| Ok(CommandRun { | ||
| command, | ||
| status: status.to_string(), | ||
| duration_ms, | ||
| details, | ||
| }) | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider using saturating conversion for duration.
Line 203 casts u128 to u64 with as, which could theoretically overflow for commands running longer than ~584 years. While practically impossible, using saturating_cast or try_into().unwrap_or(u64::MAX) would be more defensive.
Suggested fix
- let duration_ms = start.elapsed().as_millis() as u64;
+ let duration_ms = u64::try_from(start.elapsed().as_millis()).unwrap_or(u64::MAX);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@xtask/src/economics.rs` around lines 196 - 222, The duration conversion in
run_cargo currently does let duration_ms = start.elapsed().as_millis() as u64
which can overflow when casting u128 to u64; change this to a defensive
conversion (e.g., use try_into().unwrap_or(u64::MAX) or a saturating cast) when
converting start.elapsed().as_millis() to u64 so duration_ms is set safely;
update the assignment to duration_ms in the run_cargo function (referencing
Instant::elapsed, duration_ms, and the CommandRun return) to use the safe
conversion.
Summary
entropylane and wire it through the facadeuselesskey-clipublishable withmaterialize/verify, splitmaterialize-shapevsmaterialize-rsa, and add build-time examplesxtask economics/xtask audit-surface, CI drift enforcement, release/policy docs, and bump the workspace to0.6.0Key product-shape changes
entropy: cheap deterministic byte lanetoken: unchanged public lane, measured alongside the new lanesmaterialize-shape: common clean build-time lanematerialize-rsa: specialized opt-in build-time lane behindrsa-materializeCurrent receipts
entropy:58deps,common-lane-cleantoken:87deps,common-lane-cleanmaterialize-shape:81deps,common-lane-cleanmaterialize-rsa:120deps,specialized-laneValidation
cargo xtask gate --checkcargo run -p xtask -- docs-sync --checkcargo run -p xtask -- economicscargo run -p xtask -- audit-surfacecargo run -p xtask -- publish-preflightRelease order after merge
cargo publish -p uselesskey-entropycargo publish -p uselesskey-clicargo publish -p uselesskeyNotes
mainis blocked by repo rules, so this goes through PR as requiredmain