Skip to content

audit: enforce the deploy-repo / library-repo release-lifecycle split - #74

Merged
thedavidmeister merged 4 commits into
mainfrom
2026-07-30-issue-53-lifecycle-split
Jul 31, 2026
Merged

audit: enforce the deploy-repo / library-repo release-lifecycle split#74
thedavidmeister merged 4 commits into
mainfrom
2026-07-30-issue-53-lifecycle-split

Conversation

@thedavidmeister

@thedavidmeister thedavidmeister commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Closes #53

What

Adds the Release-lifecycle split Domain rule to skills/audit/SKILL.md: every rainlanguage Solidity repo is strictly a library repo (rainix-autopublish, next-version lifecycle, importable surface, no per-tag record) or a deploy repo (rainix-tag-release, frozen src/generated/<tag>/ record, [package].version moves only at release) — never both. Plus a one-sentence cross-reference from Hazard category 9, which reaches the same finding as a release-record hazard.

The check

Derive two facts independently, then flag disagreement:

  1. Nature — does the repo carry the frozen deploy record (src/generated/<tag>/*.pointers.sol tag dirs, Lib*Deploy*.sol pinning *_DEPLOYED_ADDRESS / *_DEPLOYED_CODEHASH)? Classify by the record, never the *.deploy name — pre-split rain.factory carried the record without the name; st0x.deploy carried the name while on the wrong lifecycle.
  2. Lifecycle — grep the uses: lines of .github/workflows/*.y*ml for rainix-autopublish.yaml vs rainix-tag-release.yaml. Filenames prove nothing: verified that rain.factory and rain.factory.deploy, on opposite lifecycles, both name their caller package-release.yaml.

Flags: deploy repo on the library lifecycle (HIGH — the permanently-red version == DEPLOY_TAG treadmill, with testDeployTag named as the canary and explicitly protected from being "fixed" by deletion); both reusables in one repo (HIGH); mismatches without the treadmill (LOW/MEDIUM, with an explicit routing note that a tag-release caller that deploys and freezes nothing escalates to the existing no-release-record HIGH instead). Non-finding: the record iff tag-release, surface-only iff autopublish — including either half of a completed split pair.

Placement and composition

  • Domain rule, placed directly after Deploy-pin completeness & release historicals — the deploy-rule family it extends. It cross-references Deterministic production deployments, Deploy-pin completeness & release historicals, and the @main shared-CI rule by name rather than restating any of them (named refs, not positional "the rule above", since siblings are inserting into this list concurrently).
  • Hazard cat. 9 gets the cross-reference sentence, mirroring how cat. 9 already points at the two existing deploy Domain rules. The issue suggested Hazard-surface / Process; dimension 0 reviews instruction docs, not workflows or repo shape, so hazard + Domain rule is where it composes.

Verified against live sources (not taken from the issue text)

Version lockstep

0.23.0 → 0.24.0 in .claude-plugin/plugin.json, .claude-plugin/marketplace.json, and the SKILL.md frontmatter. Both version-hygiene CI jobs replicated locally with jq before push: plugin==marketplace PASS; skills/ changed with bump vs base PASS (0.23.0 → 0.24.0).

QA

  • Discriminating tests: n/a — docs-only diff (skill prose + version lockstep); the repo's only CI is version-hygiene, replicated by hand with jq before push (job1 plugin==marketplace PASS; job2 bump-vs-base PASS, 0.23.0 → 0.24.0)
  • Mutations applied: n/a — no executable code in the diff; the prose analogue performed was a dimension-0 self-review of the added text, which caught and fixed a false claim ("both precedents were repos not named .deploy" — st0x.deploy IS so named), two fragile positional cross-references ("the two rules above" → named rule refs, load-bearing while nine sibling PRs insert into the same list), and a severity self-contradiction ("never this LOW" beside a LOW/MEDIUM rating)
  • Oracle: live sources independent of the issue text — rainlanguage/rainix .github/workflows/ listing (both reusables exist), merged rainix#280/#282 bodies (lifecycle semantics, treadmill measurement, manual-deploy decoupling), rain.factory + rain.factory.deploy package-release.yaml contents fetched from GitHub (opposite lifecycles, identical caller filename — why the check greps uses: lines), open rain.factory#46 (the split shape and the live both-lifecycles repo)
  • Category check: issue asks (a) deploy-repo-on-library-lifecycle HIGH with the version == DEPLOY_TAG canary — covered, canary named and protected from deletion-as-fix; (b) both-reusables HIGH — covered; (c) lower-severity lifecycle/nature mismatches — covered, with escalation routing to the existing no-release-record HIGH; (d) the non-finding — covered, incl. completed split pairs; (e) why-audit-not-CI — covered in the rule's closing paragraph; (f) placement in Hazard-surface / Process — placed as a Domain rule + Hazard cat. 9 cross-ref, with the Process half deliberately not taken (dimension 0 reviews instruction docs, not workflows; reasoning in the body above)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added audit guidance for separating library and deployment release lifecycles.
    • Added validation rules for repository naming, frozen deployment records, and reusable workflow selection.
    • Expanded deployment reproducibility checks to cover release-lifecycle mismatches.
  • Chores

    • Updated the audit plugin and marketplace versions from 0.26.0 to 0.27.0.

New Domain rule: every repo is a library repo (rainix-autopublish,
next-version lifecycle, no per-tag record) or a deploy repo
(rainix-tag-release, frozen src/generated/<tag>/ record, version moves
only at release) — never both. Derive nature (frozen record present?)
and lifecycle (which reusable the workflows' uses: lines call)
independently; flag a deploy repo on the library lifecycle (HIGH — the
permanently-red version == DEPLOY_TAG treadmill), both reusables in one
repo (HIGH), and lifecycle/nature mismatches without the treadmill
(LOW/MEDIUM). Composes with the existing Deterministic-production-
deployments and Deploy-pin-completeness Domain rules by reference;
Hazard cat. 9 cross-references it as a release-record hazard.

Closes #53.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@thedavidmeister thedavidmeister self-assigned this Jul 30, 2026
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@thedavidmeister, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 54 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4196bcac-2428-4e09-96b1-ef9955bbb517

📥 Commits

Reviewing files that changed from the base of the PR and between e87a190 and abb6418.

📒 Files selected for processing (1)
  • skills/audit/SKILL.md

Walkthrough

Changes

The audit skill now checks library and deploy repository release lifecycles, frozen deployment artifacts, workflow usage, and version synchronization. Plugin manifests and the skill version are updated to 0.27.0.

Audit lifecycle changes

Layer / File(s) Summary
Release lifecycle audit rules
skills/audit/SKILL.md
The skill classifies .deploy repositories, checks deployment artifacts and workflows, and reports lifecycle mismatches and version or deploy-tag desynchronization as deployment hazards.
Plugin version alignment
.claude-plugin/marketplace.json, .claude-plugin/plugin.json, skills/audit/SKILL.md
The plugin manifests and audit skill version change from 0.26.0 to 0.27.0.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

  • rainlanguage/claude-audit-skills#53 — Directly covers deploy/library lifecycle audit checks and related hazard guidance.

Possibly related PRs

Suggested labels: ai:reject

Suggested reviewers: claude

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: enforcing separate release lifecycles for deploy and library repositories.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 2026-07-30-issue-53-lifecycle-split

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@thedavidmeister

Copy link
Copy Markdown
Contributor Author

QA record for c6c833d:

Version-hygiene CI replicated locally with jq before push (both jobs):

plugin=0.24.0 market=0.24.0 frontmatter=0.24.0
job1 PASS                        # plugin.json == marketplace.json
job2 PASS (0.23.0 -> 0.24.0)     # skills/ changed => version bumped vs base

The frontmatter version: is not CI-gated; set by hand to the same 0.24.0.

Fact-check of the rule's claims against live sources (independent of the issue text):

Dimension-0 self-review of the added text caught before push: a false claim (st0x.deploy IS named .deploy — reworded to "the name proves nothing in either direction"); two positional cross-references replaced with named rule refs (siblings are inserting into the same Domain-rules list concurrently, so "the two rules above" can silently re-bind); a severity self-contradiction in the mismatch bullet.

Composition, not duplication: the rule references Deterministic production deployments, Deploy-pin completeness & release historicals, and the @main shared-CI rule by name for the artifacts and severities they already own; the only new content is the nature/lifecycle classifier, the mismatch flags, and the split fix. Hazard cat. 9 gets a one-sentence cross-ref, mirroring its existing pointers at the two deploy Domain rules.

…fied first — nature and lifecycle audit conformance to it (human ruling)
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Classification inverted on the human's ruling (234b0d4): the skill identifies each repo's DECLARED kind FIRST from the .deploy naming convention — the name is the org's canonical statement of which lifecycle the repo is on — and nature (frozen record) and lifecycle (uses: lines) are then audited as evidence of conformance TO that declaration, any disagreement flagged. The prior text treated the name as proving nothing; the counterexamples it cited (pre-split rain.factory, st0x.deploy on autopublish) are now correctly framed as the drift the rule catches, not reasons to distrust the name. Non-finding re-keyed to all-three-agree. Lifecycle content itself verified current against today's rain.deploy soldeer-gate behaviour and rainix#282's manual-dispatch split.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@skills/audit/SKILL.md`:
- Around line 186-195: Update the lifecycle-detection guidance in the
“Lifecycle” section to parse workflow YAML and inspect active job uses values,
matching only the canonical rainix-autopublish and rainix-tag-release references
at `@main`. Do not classify repositories from raw filename substrings; treat
malformed or ambiguous workflow YAML as requiring verification rather than as a
lifecycle match.
🪄 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 Plus

Run ID: e7fe1e9c-0829-4ffc-bd05-f8f7c7ca890e

📥 Commits

Reviewing files that changed from the base of the PR and between 8330bb8 and e87a190.

📒 Files selected for processing (3)
  • .claude-plugin/marketplace.json
  • .claude-plugin/plugin.json
  • skills/audit/SKILL.md

Comment thread skills/audit/SKILL.md
…hing canonical refs, fail closed on ambiguous YAML
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Reviewed abb6418: ready — lifecycle split with the .deploy name as the declared kind first (human ruling), parsed canonical uses: refs fail-closed per CodeRabbit's thread (addressed and resolved), treadmill HIGH with canary protected, 0.27.0.

@thedavidmeister
thedavidmeister merged commit 51c79e4 into main Jul 31, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Audit check: enforce the deploy-repo / library-repo release split (no repo on both lifecycles)

1 participant