feat: add Linux F4 provisioning policy manifests#127
Conversation
|
Warning Review limit reached
Next review available in: 43 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a new Linux F4 linter provisioning module that models tool provisioning policies (mechanisms, package mappings, release-blocking rules) and builds/writes/verifies deterministic JSON manifests. Integrates this into the provisioning CLI, updates related documentation, and adds a comprehensive test suite. ChangesLinux Provisioning Manifest
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant CLI as provision_f4_linters.py
participant Helper as _write_linux_manifest_if_needed
participant Builder as build_linux_provisioning_manifest
participant Writer as write_linux_provisioning_manifest
participant Verifier as verify_linux_provisioning_manifest
CLI->>Helper: process artifact evidence
Helper->>Builder: build manifest from selected tools
Builder-->>Helper: manifest dict
Helper->>Writer: write manifest JSON
Helper->>Verifier: verify written manifest
Verifier-->>Helper: list of errors
Helper-->>CLI: failed flag (verification/release_blocking)
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 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.
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 `@scripts/f4_linter_linux_provisioning.py`:
- Around line 756-794: The _tool_item_errors function is too complex because it
contains mechanism-specific branching for os-package-manager and
blocked-missing-provenance. Extract that validation into a small helper such as
_tool_mechanism_errors and have _tool_item_errors call it with
errors.extend(...) so the main function stays flat and behavior remains
unchanged. Keep the existing checks and messages for tool_id, package_names,
release_blocking, and blocker_reason in the new helper, and use the existing
symbols _tool_item_errors and LINUX_ALLOWED_MECHANISMS to locate the code.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4e82e553-ad6e-49f0-8fb8-5e3ccd561d05
📒 Files selected for processing (4)
scripts/f4_linter_linux_provisioning.pyscripts/f4_linter_packaging.pyscripts/provision_f4_linters.pytests/packaging/test_f4_linter_linux_provisioning.py
| def _tool_item_errors( | ||
| item: Mapping[str, Any], | ||
| manifest: Mapping[str, Any], | ||
| expected_policy: LinuxToolProvisioningPolicy | None, | ||
| ) -> list[str]: | ||
| prefix = str(item.get("tool_id", "<unknown>")) | ||
| errors: list[str] = [] | ||
| tool_id = item.get("tool_id") | ||
| if not isinstance(tool_id, str) or not tool_id: | ||
| errors.append(f"{prefix}: missing tool_id") | ||
| item_artifact_id = item.get("artifact_entry_id") | ||
| if item_artifact_id is not None and item_artifact_id != manifest.get( | ||
| "artifact_entry_id" | ||
| ): | ||
| errors.append( | ||
| f"{prefix}: artifact_entry_id differs from manifest artifact_entry_id" | ||
| ) | ||
| mechanism = item.get("mechanism") | ||
| if mechanism not in LINUX_ALLOWED_MECHANISMS: | ||
| errors.append(f"{prefix}: invalid Linux mechanism {mechanism!r}") | ||
| if expected_policy is not None: | ||
| errors.extend(_tool_policy_mismatch_errors(prefix, item, expected_policy)) | ||
| if ( | ||
| not isinstance(item.get("executable_names"), list) | ||
| or not item["executable_names"] | ||
| ): | ||
| errors.append(f"{prefix}: missing executable_names") | ||
| if not isinstance(item.get("version_probe"), list) or not item["version_probe"]: | ||
| errors.append(f"{prefix}: missing version_probe") | ||
| if mechanism == "os-package-manager" and not item.get("package_names"): | ||
| errors.append(f"{prefix}: os-package-manager policy requires package_names") | ||
| if mechanism == "blocked-missing-provenance": | ||
| if item.get("release_blocking") is not True: | ||
| errors.append(f"{prefix}: blocked policy must be release_blocking") | ||
| reason = item.get("blocker_reason") | ||
| if not isinstance(reason, str) or not reason.strip(): | ||
| errors.append(f"{prefix}: blocked policy requires blocker_reason") | ||
| errors.extend(_tool_path_errors(prefix, item, manifest)) | ||
| return errors |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Reduce cognitive complexity of _tool_item_errors to clear the SonarCloud CI gate.
SonarCloud reports this function at cognitive complexity 18 (limit 15) as a failing check. Extracting the mechanism-specific validation (the os-package-manager / blocked-missing-provenance branches) into a small helper flattens the branching and clears the gate without behavior change.
♻️ Suggested extraction
+def _tool_mechanism_errors(prefix: str, item: Mapping[str, Any]) -> list[str]:
+ errors: list[str] = []
+ mechanism = item.get("mechanism")
+ if mechanism == "os-package-manager" and not item.get("package_names"):
+ errors.append(f"{prefix}: os-package-manager policy requires package_names")
+ if mechanism == "blocked-missing-provenance":
+ if item.get("release_blocking") is not True:
+ errors.append(f"{prefix}: blocked policy must be release_blocking")
+ reason = item.get("blocker_reason")
+ if not isinstance(reason, str) or not reason.strip():
+ errors.append(f"{prefix}: blocked policy requires blocker_reason")
+ return errorsThen replace the inline os-package-manager / blocked-missing-provenance blocks in _tool_item_errors with errors.extend(_tool_mechanism_errors(prefix, item)).
🧰 Tools
🪛 GitHub Check: SonarCloud Code Analysis
[failure] 756-756: Refactor this function to reduce its Cognitive Complexity from 18 to the 15 allowed.
🤖 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 `@scripts/f4_linter_linux_provisioning.py` around lines 756 - 794, The
_tool_item_errors function is too complex because it contains mechanism-specific
branching for os-package-manager and blocked-missing-provenance. Extract that
validation into a small helper such as _tool_mechanism_errors and have
_tool_item_errors call it with errors.extend(...) so the main function stays
flat and behavior remains unchanged. Keep the existing checks and messages for
tool_id, package_names, release_blocking, and blocker_reason in the new helper,
and use the existing symbols _tool_item_errors and LINUX_ALLOWED_MECHANISMS to
locate the code.
Source: Linters/SAST tools
|



Summary
Add Linux F4 provisioning policy manifests and fail-closed Linux provisioning behavior.
This PR starts the concrete Linux provisioning layer after the provider-neutral provisioning framework and artifact evidence gates. It does not vendor binaries, run package managers, download upstream tools, or claim that all external Full-required linters are already fully bundled.
Instead, it adds deterministic Linux manifest generation, canonical policy validation, package-manager dependency metadata, Docker helper inheritance metadata, declarative Nix policy evidence, and explicit release-blocking
blocked-missing-provenanceentries where audited pins/checksums/provenance are still missing.Linux artifact scope
Covered Linux release/artifact surfaces:
linux-pyinstallerlinux-tarballappimagedebrpmopensuse-rpmarch-pkgbuildslackware-txzdocker-deb-helperdocker-rpm-helpernix-flakenixos-packageOut of scope for this PR:
What changed
Added
scripts/f4_linter_linux_provisioning.pyIntegrated Linux manifest generation into
scripts/provision_f4_linters.pyf4-linux-tools.json--mode dry-runremains safe and non-installing--mode verify-onlyremains non-installing--mode provisionfails closed when Linux policy contains release-blocking missing-provenance entriesUpdated
scripts/f4_linter_packaging.pyAdded
tests/packaging/test_f4_linter_linux_provisioning.pyManifest verification hardening
The Linux manifest verifier validates content against the canonical Linux policy matrix.
It rejects:
full_required_tool_countrelease_blockingmismatchselected_toolstools[].tool_idrelease_blockingdriftPolicy behavior
Package-manager artifacts:
cargo-clippyis represented as a Rust toolchain component.blocked-missing-provenance.Self-contained Linux artifacts:
linux-pyinstaller,linux-tarball, andappimageget deterministic artifact-managed tools layout and manifest paths.Docker helper artifacts:
docker-deb-helperinherits DEB policy.docker-rpm-helperinherits RPM policy.Nix artifacts:
nix-flakeandnixos-packageuse declarativenix-derivationpolicy.Explicit non-scope
This PR does not:
Validation
Passed locally / by agent report:
Observed results:
Safety checks:
Next work
A follow-up PR should add audited version pins, checksums, source provenance, and approved install/bundle implementations for currently blocked external Full-required Linux tools.
Summary by CodeRabbit
New Features
Bug Fixes
Tests