Skip to content

feat(contract)!: describe a multiple choice proposal by a document, a url or both (PV15) - #5895

Merged
QuantumExplorer merged 1 commit into
v5.1-devfrom
claude/decision-proposal-description-url
Nov 12, 2026
Merged

QuantumExplorer merged 1 commit into
v5.1-devfrom
claude/decision-proposal-description-url

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Basic explanation

What this does: A multiple choice proposal says what is being decided in one of two places, or both: a moderated document hosted on Platform, as since #5851, or its url.

Value: People will describe a proposal either the Platform way, in a document an elected team can take down, or in a system of their own. #5851 required the first. This admits the second without weakening the first.

Risks: A description at a url is outside the chain. Nothing reads or moderates it, and whoever serves it can change it after choices were entered. That is the point of the option, and the protocol guide says so. The proposal itself still holds no description text: at most a 512 byte url, which it could already hold.

Issue being fixed or feature implemented

#5851 made multipleChoiceProposal point at a description document: descriptionId, descriptionContractId and descriptionDocumentType, all required, the document one its host's elected moderation team can remove. A proposer who hosts the description elsewhere had no way to create a proposal.

What was done?

In the decision proposals contract (registered from protocol version 15, unreleased):

  • descriptionId, descriptionContractId and descriptionDocumentType are no longer required, but they go together: a proposal gives all three or none. One or two of them without the rest is refused (the descriptionDocumentNamedWhole rule below).
  • The alternative is the proposal's existing optional url (format: uri, at most 512 bytes). No property is added.
  • Two propertyConstraints rules hold a proposal, on create and on every edit:
"propertyConstraints": {
  "describedByADocumentOrAUrl": {
    "anyOf": [{ "present": "descriptionId" }, { "present": "url" }]
  },
  "descriptionDocumentNamedWhole": {
    "in": [
      { "countPresent": ["descriptionId", "descriptionContractId", "descriptionDocumentType"] },
      [0, 3]
    ]
  }
}
  • The reference on descriptionId is unchanged. A proposal that points at a document is checked exactly as before.
Before: { title, descriptionId, descriptionContractId, descriptionDocumentType, url?, open }
  the three description properties are required

After:  { title, descriptionId?, descriptionContractId?, descriptionDocumentType?, url?, open }
  a url alone:                                   accepted, nothing on chain is checked
  a description document alone:                  accepted, checked as before
  both:                                          accepted, the document checked as before
  neither:                                       DocumentPropertyConstraintViolatedError (describedByADocumentOrAUrl)
  a document named in part (an id with no
    contract or no type, or the reverse):        DocumentPropertyConstraintViolatedError (descriptionDocumentNamedWhole)

Also:

  • decision-proposals-contract: constants for the two rule names; the Rust and JS schema tests follow.
  • docs/protocol/decision-proposals.md and the contract README: the two places, the two rules, and what a url does not give.
  • Protocol version 15 note 33 says the reference is used for a description hosted on Platform, and that a proposal may give a url instead.
  • The contract schema changes, so the ten nullifier_batch_guard roots, the activation root and the system DecisionProposals line of the stored contract fixture are recomputed. No other fixture line changes.

Choices a reviewer may want to question

  • The existing url is reused. It meant "where the proposal is discussed". It is now the description when no document is given, and the discussion link when one is. A separate descriptionUrl would keep the two meanings apart at the cost of one more property.
  • At least one, both allowed. A document together with a link is harmless, so the rule is not "exactly one".

How Has This Been Tested?

  • cargo test -p drive-abci --lib -- multiple_choice_proposal decision_proposal dynamic_document_reference stored_non_document_reference nullifier_batch_guard::should_preserve_single_entry should_preserve_activation_state create_genesis_state perform_events_on_first_block should_pin commit_reveal contest: 316 pass. New: should_take_the_description_from_a_document_a_url_or_both, which creates a proposal with a url alone (and enters a choice for it), with both, with neither, and with a document named in part, with and without a url.
  • cargo test -p dpp --lib -- data_contract consensus (3330 pass) and --test stored_contract_compatibility (3 pass).
  • cargo test -p decision-proposals-contract -p platform-version.
  • cargo clippy on dpp, drive-abci, platform-version and decision-proposals-contract with --tests: clean.
  • The JS spec of the contract package is updated and syntax-checked; it was not run locally.

In-place changes to shipped generations

None. No versioned method is edited. The change is the document schema of the decision proposals contract, which is registered from protocol version 15 (unreleased) and exists on no released network, plus test pins, a fixture line and documentation.

Breaking Changes

The decision proposals contract's multipleChoiceProposal schema changes at protocol version 15, before its first release: the three description properties become optional as a group (all three or none) and two propertyConstraints rules are added. Protocol version 14 and earlier are unchanged.

Checklist:

  • I have performed a self-review of my own code
  • My Rust, FFI, WASM, Swift or Kotlin changes follow the coding conventions
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed
  • If I added or changed GroveDB structure, I described it in the area's structure.rs, regenerated grovedb-structure.json, and checked the structure viewer link posted on this pull request
  • If I added or changed a system contract's document schemas, I checked the contract viewer link posted on this pull request

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

🤖 Generated with Claude Code

PR Hygiene · b0ead30

  • Bots — thepastaclaw not yet — /skip-bots proceeds without the ones not yet reported
  • Self-review — post /self-reviewed
  • Build running
  • Approvals — you own every area touched; none needed

When every merge requirement is met, the PR Hygiene check passes. Reviewer limits do not block merging; other required GitHub checks and protections still apply.

… url or both (PV15)

A multiple choice proposal had to point at a description document hosted on
Platform. People will also host a description themselves, so the proposal now
says what is being decided in one of two places, or both: a moderated document
an elected team can take down, checked as before, or its `url`, which nothing
on chain reads or moderates.

- `descriptionId`, `descriptionContractId` and `descriptionDocumentType` are no
  longer required. Two `propertyConstraints` rules hold a proposal on create
  and on every edit: `describedByADocumentOrAUrl` (at least one of the two)
  and `descriptionDocumentNamedWhole` (the three properties naming a document
  are all given or none).
- The reference on `descriptionId` is unchanged: a proposal that points at a
  document still needs one its host's elected team can remove.
- A proposal described at a url alone is accepted and takes choices; one with
  neither, or with a document named in part, is refused with
  `DocumentPropertyConstraintViolatedError`.

The contract schema changes, so the ten nullifier_batch_guard roots, the
activation root and the stored contract fixture line of the decision proposals
contract are recomputed. Protocol version 15 is unreleased; protocol version
14 and earlier are unchanged.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 12 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

Commits

Reviewing files that changed from the base of the PR and between b21cd2a and b0ead30.

Files selected for processing: 11

  • docs/protocol/decision-proposals.md
  • packages/decision-proposals-contract/README.md
  • packages/decision-proposals-contract/schema/v1/decision-proposals-contract-documents.json
  • packages/decision-proposals-contract/src/lib.rs
  • packages/decision-proposals-contract/src/v1/mod.rs
  • packages/decision-proposals-contract/test/unit/decisionProposalsContract.spec.js
  • packages/rs-dpp/tests/fixtures/stored_contracts/stored.jsonl
  • packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v3/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/shielded/nullifier_batch_guard.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/masternode_vote/multiple_choice_proposal_tests.rs
  • packages/rs-platform-version/src/version/v15.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@github-actions github-actions Bot added this to the v5.1.0 milestone Nov 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📜 System contracts

This pull request adds or changes system contract document schemas. The contract viewer diagrams each one, and a comparison marks what is added, changed and removed, with the update rule each change meets.

Compared b21cd2a6e1 with b0ead30e03. Updated at 2026-11-12T16:48:11.389Z

@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Waiting for bot review — thepastaclaw not yet. Wait for the missing reviews, or a writer can post /skip-bots to proceed without them; blocking findings still need addressing.
Full checklist in the description.

@github-actions github-actions Bot added the waiting-bots Waiting for the review bots to report on this head label Nov 12, 2026
@thepastaclaw

Copy link
Copy Markdown
Collaborator

🕓 Review not started yet because the new head is waiting for the 30-minute push debounce.

  • Request normal review — click when the PR is ready for review.
  • Request priority review — click to move this review to the front of the queue.

Commit b0ead30. Normal review starts when eligible; priority review starts as soon as a slot is available.

@QuantumExplorer
QuantumExplorer merged commit 906ddd5 into v5.1-dev Nov 12, 2026
22 of 24 checks passed
@QuantumExplorer
QuantumExplorer deleted the claude/decision-proposal-description-url branch November 12, 2026 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-bots Waiting for the review bots to report on this head

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants