Skip to content

[Governance 1/4] Introduce pallet-multi-collective#2805

Open
l0r1s wants to merge 4 commits into
governance-umbrellafrom
governance-multi-collective
Open

[Governance 1/4] Introduce pallet-multi-collective#2805
l0r1s wants to merge 4 commits into
governance-umbrellafrom
governance-multi-collective

Conversation

@l0r1s

@l0r1s l0r1s commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Part of #2804.

Adds pallet-multi-collective, a generic membership pallet for storing multiple named collectives under a runtime-defined CollectiveId.

This is a building block for governance membership only. It does not add voting, proposing, or runtime governance behavior by itself.

What Changed

  • Added pallet-multi-collective.
  • Added configurable collective definitions with name, min members, max members, and optional term duration.
  • Added membership extrinsics: add_member, remove_member, swap_member, set_members, and force_rotate.
  • Added OnMembersChanged and term-rotation hooks for downstream consumers.
  • Added integrity checks for invalid collective configuration.
  • Added benchmarks, generated weights, README documentation, mock runtime support, and unit tests.

Detailed Reference

See pallets/multi-collective/README.md for the full design reference. It covers the membership storage model, extrinsic behavior, origin configuration, member-change hooks, rotating terms, integrity checks, migration notes, and an example runtime configuration.

Reviewers may want to focus on the boundary behavior: swap_member preserves member count atomically, set_members rejects duplicate input instead of silently deduplicating, and rotating collectives keep their previous membership if the runtime-supplied rotation cannot satisfy the configured minimum size.

Behavioral Impact

No live runtime behavior changes in this PR. The pallet is added to the codebase but is not wired into the Subtensor runtime until the governance wiring PR.

Migration / Spec Version

The pallet defines storage, but this PR does not add it to the runtime. No live storage migration or spec-version bump is required here.

Testing

Suggested local verification:

cargo test -p pallet-multi-collective

@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

🛡️ AI Review — Skeptic (security review)

VERDICT: SAFE

BASELINE scrutiny: l0r1s has write permission, an older account, substantial prefetched contribution history, no Gittensor allowlist hit, and matching in-PR authorship; branch governance-multi-collective -> governance-umbrella.

Static-only Skeptic review of the prefetched diff found no .github/ai-review/* or .github/copilot-instructions.md modifications. The current diff is scoped to adding pallet-multi-collective, wiring workspace metadata, and tests/weights; origin checks are present on the new extrinsics, membership storage is bounded, and the previously flagged crowdloan/workflow lines are no longer part of this PR diff after the branch/base update.

Findings

No findings.

Prior-comment reconciliation

  • 0b7f7e3e: no longer applies — The updated PR diff no longer includes pallets/crowdloan/src/lib.rs, so this prior crowdloan finalization concern is not part of the current PR review surface.
  • 8791a1e8: no longer applies — The updated PR diff no longer includes .github/workflows/try-runtime.yml, so this prior self-hosted runner/local-action concern is not part of the current PR review surface.

Conclusion

No malicious pattern or security vulnerability was identified in the current PR diff. Prior findings no longer apply to this review because the files they referenced are absent from the updated diff.


📜 Previous run (superseded)
Sev File Finding Status
HIGH pallets/crowdloan/src/lib.rs:629 Failing finalize can permanently lock crowdloan finalization ⏭️ No longer applies
The updated PR diff no longer includes pallets/crowdloan/src/lib.rs, so this prior crowdloan finalization concern is not part of the current PR review surface.
MEDIUM .github/workflows/try-runtime.yml:33 pull_request workflow loads a PR-mutable local action on self-hosted runners ⏭️ No longer applies
The updated PR diff no longer includes .github/workflows/try-runtime.yml, so this prior self-hosted runner/local-action concern is not part of the current PR review surface.

🔍 AI Review — Auditor (domain review)

VERDICT: 👍

Gittensor UNKNOWN; author has repo write permission and substantial prior Subtensor contribution history, so review is calibrated as established contributor work.

No blocking domain findings from static review. This PR introduces a standalone pallet-multi-collective and shared OnMembersChanged trait support without wiring the pallet into the live runtime, so no spec-version bump is required for this branch.

The overlapping PRs are expected stacked governance/workspace work rather than better duplicate implementations of this pallet. One PR-body cleanup remains: the Detailed Reference link text names pallets/multi-collective/README.md, but the URL currently points at pallets/signed-voting/README.md.

Findings

No findings.

Conclusion

Approve on domain review: the new membership extrinsics have explicit origins, bounded storage, generated weights, integrity/try-state checks, and broad unit coverage for sorted membership, bounds, hooks, and rotation behavior. I did not run tests because no finding required runtime confirmation.

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👍

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

Error::<T>::AlreadyFinalizing
);

crowdloan.finalized = true;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Failing finalize can permanently lock crowdloan finalization

finalize now writes crowdloan.finalized = true before dispatching the stored call, but the extrinsic is not wrapped in a transactional rollback and CurrentCrowdloanId::<T>::kill() only runs after a successful nested dispatch. If stored_call.dispatch(...) returns Err, the ? exits before cleanup: CurrentCrowdloanId remains set, the new AlreadyFinalizing guard blocks every future crowdloan finalization, and this crowdloan is marked finalized so withdraw/refund are also blocked. Wrap the fallible finalize branch in with_transaction and roll back on any nested dispatch error, and ensure the temporary CurrentCrowdloanId marker is cleared on every exit path.


- name: Run Try Runtime Checks
uses: "paritytech/try-runtime-gha@v0.1.0"
uses: ./.github/actions/try-runtime

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[MEDIUM] pull_request workflow loads a PR-mutable local action on self-hosted runners

This workflow checks out the PR and then executes ./.github/actions/try-runtime from that checkout on self-hosted runners. After this merges, a future PR can modify the local composite action and run arbitrary shell on those runners once CI is approved, without changing this workflow file. Nucleus approval and human .github scrutiny reduce the risk, but the steady-state workflow should load this helper from a trusted ref/reusable workflow or otherwise ensure the action body comes from the base branch, not the PR worktree.

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@l0r1s l0r1s mentioned this pull request Jul 1, 2026
@l0r1s l0r1s marked this pull request as ready for review July 1, 2026 14:01
@l0r1s l0r1s added the skip-cargo-audit This PR fails cargo audit but needs to be merged anyway label Jul 1, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

Error::<T>::AlreadyFinalizing
);

crowdloan.finalized = true;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[HIGH] Failing finalize can permanently lock crowdloan finalization

finalize writes crowdloan.finalized = true before the fallible preimage lookup and nested stored_call.dispatch(...), and CurrentCrowdloanId is only killed on the success path. FRAME dispatchables in this repo use explicit #[transactional] / with_transaction when earlier writes must roll back on error, so a missing preimage or failing nested call can leave this crowdloan marked finalized and/or leave CurrentCrowdloanId set. That blocks withdrawals/refunds/future finalization and can strand the funds. Move the state writes after all fallible work that can fail, explicitly clear the guard on every error path, or wrap the whole finalization body in a storage transaction that rolls back on Err.


- name: Run Try Runtime Checks
uses: "paritytech/try-runtime-gha@v0.1.0"
uses: ./.github/actions/try-runtime

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[MEDIUM] pull_request workflow loads a PR-mutable local action on self-hosted runners

This pull_request workflow now runs ./.github/actions/try-runtime from the checked-out PR contents on self-hosted fireactions-tryruntime* runners. The action contains arbitrary shell (curl, rustup, cargo build, try-runtime execution), so after this merges any future PR can alter that local action and have the modified shell run once a nucleus member approves CI. The approval gate lowers this from a direct secret-exfil path, but it is a persistent runner-execution footgun. Keep the workflow pinned to an immutable external action, or checkout the trusted base/default branch copy of the local action before invoking it.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: VULNERABLE

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-cargo-audit This PR fails cargo audit but needs to be merged anyway

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant