Address PR #515 review follow-ups - #530
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Summary
Validation
WalkthroughThe change centralizes Jinja telemetry, preserves native executable paths, injects environments into manifest loading, redacts duration diagnostics, and strengthens integration-test contracts. ChangesManifest and test contracts
Sequence Diagram(s)sequenceDiagram
participant MacroInvocation
participant Telemetry
participant MiniJinja
participant Metrics
MacroInvocation->>Telemetry: instrument_macro_invocation
Telemetry->>MiniJinja: evaluate macro
MiniJinja-->>Telemetry: return result
Telemetry->>Metrics: record bounded outcome and duration
Telemetry-->>MacroInvocation: return original result
Possibly related PRs
Suggested reviewers: Poem
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error, 2 warnings, 1 inconclusive)
✅ Passed checks (16 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Reviewer's GuideThis PR addresses follow-up review comments from #515 by tightening environment handling in tests and helpers, hardening workflow and packaging contracts, improving Whitaker lint boundary checks, documenting several test-support contracts, and splitting installation-related documentation tests into their own binary, while also correcting English locale wording and small platform-specific behaviours. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
22bb232 to
f094bc3
Compare
3e463ff to
aa9ecba
Compare
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@locales/en-GB/messages.ftl`:
- Line 142: Restore en-GB spelling at all affected sites: update
locales/en-GB/messages.ftl lines 142-142 to “initialise”, update the en-GB
diagnostic snapshot in src/manifest/jinja_macros/invocation.rs lines 142-142 to
“initialise”, and change “initialization” to “initialisation” in the Rust
comment at src/stdlib/config_types.rs lines 34-34.
In `@test_support/src/env_lock.rs`:
- Around line 255-257: Update the recovery test around EnvLock::acquire so the
held-state check does not panic while recovered_guard is live: read
ENV_LOCK_STATE non-panically into a boolean, drop recovered_guard, then assert
the captured state. Keep the existing poison-state assertion and subsequent
release assertion unchanged.
In `@test_support/src/http/tests.rs`:
- Around line 59-63: Add an expected warning-length field to DurationCase and
populate it for every invalid-value case, including empty input. Update the
warning assertions in the affected test sections to verify the rendered byte
length alongside the variable name, parse-error text, and redaction check, while
leaving valid cases without warnings unchanged.
In `@tests/packaging_smoke_tests.rs`:
- Around line 98-109: Update assert_forbidden_roots_absent to use
camino::Utf8Path::new instead of std::path::Path::new for both path
constructions, and compare the first component via Utf8Component::as_str() for
an exact root match so names like test_support-extra remain allowed.
In `@tests/workflow_contracts/ci_lint_test.py`:
- Around line 53-58: Update the YAML parsing in the workflow document loading
path to avoid treating YAML 1.1 boolean aliases such as yes and true as the
GitHub Actions on key. Use a YAML 1.2-compatible loader, or normalize only a
literal on key while preserving all other keys, then keep the existing workflow
validation behavior unchanged.
🪄 Autofix
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 Plus
Run ID: 864e13f1-a0e1-4375-8c80-d89fca081940
📒 Files selected for processing (31)
docs/developers-guide.mdlocales/en-GB/messages.ftllocales/en-US/messages.ftlsrc/manifest/jinja_macros/invocation.rssrc/manifest/jinja_macros/mod.rssrc/manifest/jinja_macros/telemetry.rssrc/manifest/tests/macro_invocation_telemetry.rssrc/manifest/tests/mod.rssrc/runner/mod.rssrc/stdlib/config_types.rssrc/stdlib/which/env.rstest_support/src/check_ninja.rstest_support/src/command_helper.rstest_support/src/dev_fast/mod.rstest_support/src/env_lock.rstest_support/src/exec.rstest_support/src/http/mod.rstest_support/src/http/tests.rstest_support/src/stdlib_assert.rstests/bdd/steps/ir.rstests/bdd/steps/manifest/environment.rstests/bdd/steps/manifest/mod.rstests/cli_tests/config_discovery_scopes.rstests/cli_tests/config_selection.rstests/cli_tests/merge.rstests/cli_tests/merge_probe.rstests/manifest_jinja_tests.rstests/novice_flow_smoke_tests.rstests/packaging_smoke_tests.rstests/whitaker_boundary_contract.rstests/workflow_contracts/ci_lint_test.py
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
leynos/rstest-bdd(auto-detected)leynos/ortho-config(auto-detected)leynos/whitaker(auto-detected)leynos/shared-actions(auto-detected)
|
@coderabbitai resume |
✅ Action performedReviews resumed. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test_support/src/env_lock.rs`:
- Around line 101-102: Update assert_current_thread_lock_is_held and its callers
to avoid asserting while an EnvLock guard remains live: capture the
current_thread_lock_is_held result, explicitly drop all relevant guards, then
perform the assertion using the captured value. Preserve the existing assertion
message and ensure both caller paths release their EnvLock guards before
assertion.
🪄 Autofix
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 Plus
Run ID: 5523864c-5336-4e13-ba98-628b8adf6853
📒 Files selected for processing (31)
docs/developers-guide.mdlocales/en-GB/messages.ftllocales/en-US/messages.ftlsrc/manifest/jinja_macros/invocation.rssrc/manifest/jinja_macros/mod.rssrc/manifest/jinja_macros/telemetry.rssrc/manifest/tests/macro_invocation_telemetry.rssrc/manifest/tests/mod.rssrc/runner/mod.rssrc/stdlib/config_types.rssrc/stdlib/which/env.rstest_support/src/check_ninja.rstest_support/src/command_helper.rstest_support/src/dev_fast/mod.rstest_support/src/env_lock.rstest_support/src/exec.rstest_support/src/http/mod.rstest_support/src/http/tests.rstest_support/src/stdlib_assert.rstests/bdd/steps/ir.rstests/bdd/steps/manifest/environment.rstests/bdd/steps/manifest/mod.rstests/cli_tests/config_discovery_scopes.rstests/cli_tests/config_selection.rstests/cli_tests/merge.rstests/cli_tests/merge_probe.rstests/manifest_jinja_tests.rstests/novice_flow_smoke_tests.rstests/packaging_smoke_tests.rstests/whitaker_boundary_contract.rstests/workflow_contracts/ci_lint_test.py
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
leynos/rstest-bdd(auto-detected)leynos/ortho-config(auto-detected)leynos/whitaker(auto-detected)leynos/shared-actions(auto-detected)
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
test_support/src/env_lock.rs (1)
254-263: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winCorrect the poisoning-test safety comment.
Line 271 asserts before
ENV_LOCK.clear_poison()at Lines 272-273. Therefore, the statement that every assertion runs with the poison flag cleared is false. State that only the post-clear assertions have this guarantee. Keep the separate no-live-guard guarantee for the join assertion.Proposed comment correction
- /// Every assertion here is made with no guard live and the poison flag - /// already cleared, so a failure cannot leave process-global poisoning - /// behind: clearing the flag covers the deliberate poisoning, and - /// capturing the held state before dropping the guard covers the unwind - /// path, where a panic would otherwise drop the `MutexGuard` and poison - /// the mutex afresh. + /// The post-recovery assertions run with no guard live and the poison flag + /// already cleared. The join assertion runs before the clear and has no + /// live `EnvLock` guard in the current thread. Capturing the held state + /// before dropping the guard prevents an assertion unwind from poisoning + /// the mutex afresh.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test_support/src/env_lock.rs` around lines 254 - 263, Correct the safety documentation above the poisoning test: in the comment covering the join and recovery assertions, state that only post-ENV_LOCK.clear_poison() assertions have the poison-cleared guarantee, while the join assertion occurs before clearing and has no live EnvLock guard in the current thread. Preserve the explanation that capturing held state before dropping the guard prevents assertion unwinding from re-poisoning the mutex.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/adr-008-bounded-redacted-manifest-telemetry.md`:
- Line 21: Remove the unnecessary commas before “because” in both affected
sentences in the ADR, including the sentence near “recording it in a trace” and
the one near “only because imports evaluate.”
---
Outside diff comments:
In `@test_support/src/env_lock.rs`:
- Around line 254-263: Correct the safety documentation above the poisoning
test: in the comment covering the join and recovery assertions, state that only
post-ENV_LOCK.clear_poison() assertions have the poison-cleared guarantee, while
the join assertion occurs before clearing and has no live EnvLock guard in the
current thread. Preserve the explanation that capturing held state before
dropping the guard prevents assertion unwinding from re-poisoning the mutex.
🪄 Autofix
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 Plus
Run ID: 144555cb-9caa-4da9-8487-7a29cb6b6d36
📒 Files selected for processing (8)
docs/adr-008-bounded-redacted-manifest-telemetry.mddocs/contents.mddocs/developers-guide.mddocs/netsuke-design.mdtest_support/src/env_lock.rstests/data/ir_env.ymltests/features/ir.featuretests/novice_flow_smoke_tests.rs
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
leynos/rstest-bdd(auto-detected)leynos/ortho-config(auto-detected)leynos/whitaker(auto-detected)leynos/shared-actions(auto-detected)
d195b1a to
115b310
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/developers-guide.md (1)
275-280: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winAdd a caption for this table.
Place a concise caption immediately before the table. Document readers need its purpose without inferring it from the surrounding prose.
Triage:
[type:docstyle]As per coding guidelines, caption every table and diagram.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/developers-guide.md` around lines 275 - 280, Add a concise descriptive caption immediately before the table listing workflows, jobs, shared actions, and Rust flags in the developers guide. Keep the existing table content unchanged.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/adr-008-bounded-redacted-manifest-telemetry.md`:
- Line 9: Update the ADR Date value to the bare YYYY-MM-DD date 2026-08-06,
removing the trailing full stop while preserving the rest of the document.
In `@tests/novice_flow_smoke_tests.rs`:
- Around line 3-7: Update the imports in the novice flow smoke tests so bail is
imported separately under #[cfg(unix)], alongside the existing Unix-only PathBuf
import. Keep Context, Result, and ensure available for all platforms, and
preserve the Unix-only test behavior.
---
Outside diff comments:
In `@docs/developers-guide.md`:
- Around line 275-280: Add a concise descriptive caption immediately before the
table listing workflows, jobs, shared actions, and Rust flags in the developers
guide. Keep the existing table content unchanged.
🪄 Autofix
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 Plus
Run ID: ae0f8f31-f487-41d8-8ec6-ad2320cbe087
📒 Files selected for processing (10)
docs/adr-008-bounded-redacted-manifest-telemetry.mddocs/contents.mddocs/developers-guide.mddocs/netsuke-design.mdsrc/manifest/jinja_macros/mod.rssrc/manifest/jinja_macros/telemetry.rstest_support/src/env_lock.rstests/data/ir_env.ymltests/features/ir.featuretests/novice_flow_smoke_tests.rs
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
leynos/rstest-bdd(auto-detected)leynos/ortho-config(auto-detected)leynos/whitaker(auto-detected)leynos/shared-actions(auto-detected)
|
@coderabbitai please create a new GitHub issue for the following: ❌ Failed checks (1 error)
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="leynos/netsuke"
pr_number="530"
needle='Add focused loader tests that assert `on` remains a string'
comment_url="$(
gh api --paginate "repos/$repo/issues/$pr_number/comments?per_page=100" \
--jq ".[] | select(.body | contains(\"$needle\")) | .html_url" \
| head -n1
)"
if [ -z "$comment_url" ]; then
echo "Could not locate the originating PR comment." >&2
exit 1
fi
existing="$(
gh issue list --repo "$repo" --state open --search 'WorkflowLoader _load YAML tests in:title,body' \
--json number,title,url --jq '.[] | "\(.number)\t\(.title)\t\(.url)"'
)"
if [ -n "$existing" ]; then
printf 'Existing matching issue:\n%s\n' "$existing"
exit 0
fi
body_file="$(mktemp)"
trap 'rm -f "$body_file"' EXIT
cat >"$body_file" <<EOF
## Summary
Add focused unit tests for the YAML workflow loader validation added in \`tests/workflow_contracts/ci_lint_test.py\`.
## Rationale
The current change adds YAML 1.2 boolean handling and validates documents returned by \`_load\`. Existing tests do not cover these branches. Add direct coverage to prevent regressions in GitHub Actions workflow parsing and validation.
## Affected area
- \`tests/workflow_contracts/ci_lint_test.py\`
- Its associated Python test module
## Required changes
Add focused tests for \`_WorkflowLoader\` and \`_load\`.
## Acceptance criteria
- A workflow document keeps the \`on\` key as a string.
- YAML \`true\` and \`false\` values resolve as booleans.
- \`_load\` rejects an empty document.
- \`_load\` rejects scalar documents.
- \`_load\` rejects list documents.
- \`_load\` rejects mappings that contain non-string keys.
- The tests assert the intended error behaviour without depending on unrelated workflow contract tests.
## Backlinks
- Follow-up from PR `#530`: https://github.com/leynos/netsuke/pull/530
- Originating review comment: $comment_url
- Requested by: `@leynos`
EOF
issue_url="$(
gh issue create \
--repo "$repo" \
--title "Add YAML loader validation tests for workflow contracts" \
--body-file "$body_file" \
--assignee leynos
)"
printf 'Created issue: %s\n' "$issue_url"Length of output: 2367
You are interacting with an AI system. |
|
@coderabbitai resume |
✅ Action performedReviews resumed. |
Work through the code-review comments left on #515 after merge, verifying each against the current tree before changing anything. Correctness and isolation: - Compile IR from BDD manifests through `from_path_with_policy_and_env` with the scenario environment reader, matching the manifest steps instead of reading host variables. - Wrap both `tests/cli_tests/merge.rs` merge sites in `isolated_environment` so host XDG configuration cannot perturb the precedence assertions. - Forward `LD_LIBRARY_PATH` and `DYLD_FALLBACK_LIBRARY_PATH` through the merge-probe allowlist; Cargo supplies them and the re-executed worker cannot start without them. - Give the project-scope discovery test its own home directory so it can only pass through project-scope discovery. - Assert the `UndefinedError` cause before downcasting in the missing-environment-variable manifest test, so the check applies whatever the outer error type. - Strengthen the explicit-config assertion to require the stable diagnostic alongside the missing path. - Parse `--package` selections into arguments in the Whitaker boundary contract, rejecting extra flags and prefixed names. - Validate the workflow YAML root structurally in `_load`, restoring the `on:` key that PyYAML coerces to a boolean. - Fail loudly on a non-UTF-8 ninja override instead of converting lossily, and name the offending path in the packaging assertion. - Clear the `ENV_LOCK` poison flag before asserting, so a failing assertion cannot leak process-global poisoning. Structure and documentation: - Replace the `cfg`-gated bare `return` in `EnvSnapshot::capture_with_env` with per-platform wrappers. - Keep the compiler-wrapper marker sidecar in camino's UTF-8 domain. - Brought `documentation_examples_tests.rs` back under the 400-line limit by moving the installation, release, and Windows setup contracts into their own test binary. Main reached the same split independently in #532, so this branch adopts `tests/documentation_installation_tests.rs` from there rather than carrying a duplicate; its version literals derive from `CARGO_PKG_VERSION`. - Fix `initialise`/`initialisation` to Oxford spelling in the macro initialization message and the fetch-cache Rustdoc, updating the inline snapshot in lockstep. - Document the native-path contract for the injected Ninja executable, and fill the Rustdoc gaps in `fake_ninja_check_build_file_in`, `real_utility_with_env`, `stdlib_output_or_error`, and the non-Unix `make_executable`. One comment is not actioned: the `run_netsuke_in` environment-contract comment already matches the implementation. That helper does not call `env_clear`, so the suggested wording describes `run_netsuke_in_with_env` and would have made the comment wrong. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Address the second review round on #515. Six of the ten findings had already been fixed or never held; the four below were verified against the current tree first. Separate observability from evaluation. `make_macro_fn` created a span, timed with `Instant::now()`, and emitted metrics inside the Jinja callback, mixing instrumentation into what is a query. `render_template` did the same at the template boundary. Both now compose a pure evaluation closure with an instrumentation wrapper in a new `jinja_macros::telemetry` module, which also gives the emitted fields' privacy contract a single place to be reviewed. Cover the macro-invocation boundary with tests. Its counter, histogram, and span appeared only in production code, so deleting them left the suite green. `macro_invocation_telemetry` now pins the success and failure paths and asserts the failure event carries the bounded error category without the macro's name or arguments. Confirmed by deleting the metrics and watching both tests fail. Redact the fixture duration value in `test_support`'s HTTP server. An unparsable override was logged verbatim, putting caller-controlled environment content into the log. The warning now carries the variable name, the bounded parse error, and the value's byte length; the tests assert on that category and additionally assert the value does not appear. An empty-value case joins the table, which the length now distinguishes. Correct two stale developer-guide entries: the executable helpers take `&Path`/`PathBuf` and there is no `exec::utf8_path` conversion point, and `push_file_layers` is really `push_file_layers_with_env`. Not actioned, with reasons: - Imported-macro renders were said to lack instrumentation. They do not: `render_template` has always had its own span and metrics, tested in `macros_telemetry`. A regression test now pins the boundary split. - `env_reader` was said to leak manifest-controlled variable names. It does not; the diagnostics are fixed text and a test asserts the name is absent, which is the documented decision. - The `merge_probe` clone already uses `merged.command.take()`. - `EnvProvider` was said to be renamed to `LocaleEnvProvider`. They are unrelated traits that both still exist, and the distinction is already documented in the developers' guide. - The claimed module cycles do not exist: `ENV_PREFIX` lives in `cli::constants` and `call_macro_value` in the sibling `call` module, which is where the finding asked for them. - Proptests for keyword forwarding and `EnvLock` acquire/drop interleavings already exist. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Address the third review round on #515. Four findings held; one was half right, and the reasons for each are below. Stop the poisoning-recovery test leaking poison on failure. `env_lock_recovers_after_mutex_poisoning` asserted the held state while `recovered_guard` was still live. Had that assertion failed, unwinding would have dropped the guard mid-panic and poisoned `ENV_LOCK` afresh — the very leak the test's own doc comment claimed to have covered, since clearing the flag earlier only guards the deliberate poisoning. The state is now read through a non-asserting `current_thread_lock_is_held`, the guard dropped, and only then asserted; the doc comment no longer overclaims. Add property coverage for the redaction invariants. Both were pinned only by fixed sentinels, so they held for the sentinel and said nothing about the range: - `macro_telemetry_stays_bounded_for_arbitrary_macros` generates macro names, arguments, and undefined-variable names, then asserts the outcome labels stay within `{success, error}` and that none of the generated identifiers reach a tracing event. Verified by making the failure event log the full `MiniJinja` error instead of its kind: the test fails, naming the leaked macro. - `invalid_duration_warnings_are_composed_only_of_bounded_parts` generates unparsable overrides and asserts the rendered warning equals a message rebuilt from bounded parts alone. Exact match rather than a `!contains` check, which a value of `bytes` would satisfy while sitting in plain sight. Pin the redacted value's byte length in the duration table via a new `expected_warning_len`, measured after trimming to match the call site. It is the one piece of shape the warning still surfaces, so it should not go missing — or revert to the value — unnoticed. Parse the workflow with a YAML 1.2 boolean resolver. Mapping `True` back to `"on"` conflated GitHub Actions' `on:` with a literal `yes:` or `true:` key; under YAML 1.1 those three collapse into a single key, silently dropping entries. Narrowing the resolver to `true`/`false` leaves `on` a string, so the normalization disappears rather than being patched. Use `camino::Utf8Path` in the packaging forbidden-root check, per the project's stated preference over `std::path`. The finding also asked for an exact root match to keep names such as `test_support-extra` allowed; that already held, because comparing whole path components is exact already — only the type changed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Address the fourth review round on #515. All three findings held. Finish the job started last round in `env_lock`. Capturing the lock state before asserting fixed only the poisoning-recovery test; the two reentrant tests still called `assert_current_thread_lock_is_held` with guards live, so a failure there would drop a guard mid-unwind and poison `ENV_LOCK`, burying the real cause. Both now capture their observations, release the guards, then assert, preserving the original messages. The helper had no remaining callers and is gone; `current_thread_lock_is_held` stays. Test the IR environment injection. Compiling a manifest to IR was switched to `from_path_with_policy_and_env`, but no scenario combined a forwarded variable with `compiled to IR`, so reverting to `from_path` left the suite green. A new fixture derives both a target name and an input path from `env(...)`, and two scenarios pin the outcome: one asserts the resulting graph edge, the other that generation fails when the variable is unset. Confirmed by reverting the step to `from_path` — the first scenario fails because the graph never builds. The value had to travel through a target name rather than a command: `BuildEdge` carries no recipe, so `ir.rs` exposes no step that can assert command text. Cover the non-UTF-8 `NETSUKE_NINJA` branch too, Unix-only since building such a path needs POSIX byte semantics. Document the telemetry boundary. A new module arrived with a published metric contract and a redaction policy but no record of either. ADR-008 records the decision to keep observability out of manifest evaluation and telemetry bounded and redacted, with the alternatives; the developers' guide now describes both instrumentation boundaries, the label vocabulary, the redaction rule, and where the contract is tested. The design document and documentation index reference the ADR. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Address the fifth review round on #515. Both findings were prose. The comment above `env_lock_recovers_after_mutex_poisoning` claimed every assertion runs with the poison flag already cleared. That is wrong for the first one: the `join` assertion precedes `ENV_LOCK.clear_poison()`, and at that point the mutex is still poisoned — deliberately, since that is the state under test. It is nonetheless safe, because the poisoned guard belonged to the spawned thread and this thread holds none, so a failure has no live guard to drop. The note now separates the two cases and keeps the explanation of why the held state is captured before its guard is dropped. Drop the comma before "because" in the two ADR sentences named by the review. The second needed more than deleting the comma: "covers the compiled-expression fallback only because imports evaluate" reads as "merely because", so "only" moves ahead of the noun phrase to keep the meaning that the counter covers that path alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`render_template` called `describe_render_metrics()` on every render, so the query function reached for the global metric registry itself. The call moves into `instrument_template_render`, behind the same one-time guard, leaving rendering to name only the instrumentation boundary it composes with. The macro-side registration stays where it is: it runs when a macro is registered, which is setup rather than evaluation. This is a partial response to a review finding asking for a clock and telemetry sink to be injected instead. That part is not actioned; see ADR-008, which records the decision and the reasoning, and the pull request discussion. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Moving `describe_render_metrics` into `instrument_template_render` left the developers' guide asserting it "runs at the top of every `render_template` call". Describe where the registration actually happens, and why neither description call sits in a query function. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`bail!` is reached only from `non_utf8_ninja_override_is_rejected`, which is `#[cfg(unix)]` because building a non-UTF-8 path needs POSIX byte semantics. The import was unconditional, so on any other target it became an unused import — and the workspace builds with `-D warnings`, making that a hard error rather than a warning. Gate it alongside the `PathBuf` import that the same test needs. Verified rather than assumed: the pre-fix shape (unconditional import whose sole user is gated out) fails `rustc -D warnings` with `error: unused import`, and the gated shape compiles clean. A direct Windows cross-check was not possible here because a build dependency needs MSVC's `lib.exe`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5685166 to
df0b242
Compare
Summary
Works through the code-review comments left on #515 (Harden workspace lint
configuration) after it merged. Every finding was verified against the current
tree before any change; one was found to be stale and is left alone with a
reason below.
Correctness and isolation
compile_manifest_implcalledmanifest::from_path, bypassing the injected environment, so IR scenarios readhost variables while the manifest scenarios read scenario values. It now uses
from_path_with_policy_and_envwith the samemanifest_env_readerseam.tests/cli_tests/merge.rsnow sandboxes both merge sites.with_config_fileand the precedence test called
merge_in_childdirectly, letting host XDGconfiguration reach the child. Both now go through
isolated_environment.LD_LIBRARY_PATHand
DYLD_FALLBACK_LIBRARY_PATHare Cargo-supplied; clearing them leaves there-executed worker unable to start on Linux and macOS.
project directory, so the assertions can only pass through project scope.
UndefinedErroris asserted before the downcast in themissing-environment-variable manifest test, so the cause is checked whatever
the outer error type; the
ManifestError::Parsecheck is retained for wrappedvalues.
missing path, so a generic I/O failure cannot satisfy it.
tell
--package test_supportfrom--package test_support-extra, nor spot asecond selection; a small tokenizer now requires exactly one selection per
invocation.
_loadpattern-matches theyaml.safe_loadresult and rejects scalar, list, andNoneroots. Note thatGitHub Actions'
on:key is a YAML 1.1 boolean word, so PyYAML returns it asTrue; the key is restored to"on"before the string-key check.the packaging assertion now names the offending path.
ENV_LOCKpoison flag cleared before asserting, so a failing assertioncannot leak process-global poisoning; the test carries a note that its direct
global-mutex probe depends on nextest's per-test process isolation.
Structure and documentation
cfg-gated barereturninEnvSnapshot::capture_with_envwithper-platform wrappers over the two divergent
capture_implarities.once at the
std::pathboundary.tests/documentation_examples_tests.rs(495 lines) intotests/documentation_examples_installation_tests.rs, following the existingconvention of one test binary per concern sharing the
documentation_examplesloader module. The original file is now 354 lines.
initialise/initialisationto Oxford spelling in the macroinitialization message (both English locales) and the fetch-cache Rustdoc,
updating the inline
instasnapshot in lockstep.filled the Rustdoc gaps in `fake_ninja_check_build_file_in`,
`real_utility_with_env`, `stdlib_output_or_error`, and the non-Unix
`make_executable` (whose `#[cfg]` also sat inside its doc comment).
Not actioned
One comment asked to rewrite the `run_netsuke_in` environment-contract comment
to say no process environment variables are inherited. That helper does not call
`env_clear` — it inherits the parent environment except for the selectors it
explicitly sets or removes — so the existing comment is accurate and the
suggested wording describes `run_netsuke_in_with_env` instead. Applying it
would have made the comment wrong.
Validation
All deterministic commit gates pass on a clean tree: `check-fmt`, `lint`
(rustdoc, Clippy with `-D warnings`, Whitaker for both crates), `typecheck`,
`test` (1652 nextest tests, 83 doctests), `markdownlint`, `nixie`, and
`test-workflow-contracts` (12/12).
References
🤖 Generated with Claude Code
Summary by Sourcery
Address post-merge review feedback to harden lint-related tests, environment handling, and documentation contracts across manifests, workflows, packaging, and installation flows.
Bug Fixes:
Enhancements:
Documentation: