How to limit altering proposals after they are posted?

Some time ago, I was searching for something in older proposals and found one where the link to the full proposal was not working.

I want to open discussion about the fact that many (if not most) proposals submitted to open gov are usually very brief and have “full proposal” links in the text. Most of the time, these links are open Google Docs that can be modified and changed without voters’ knowledge.

Imagine someone posting a proposal and then changing stuff in it while it’s open for voting or after it was approved. There is no easy way to verify whether the external document was altered. In some cases, the links can stop working, or the owner can limit their visibility or delete them, making it harder to check them over time.

Since the treasury is distributing a lot of money, it would make sense to have the option to review older proposals with certainty that the document you are reading is the same document that was submitted on the first day of posting the proposal. For the sake of transparency, that’s how it should work. What we like to say - Less trust, more truth? :smile:

I’m curious about the opinions of others; how can this be solved? Do you think this is an issue that needs to be tackled? What can be done?

Maybe a common agreement could work, like submitting formats that cannot be changed. Maybe Subsquare or Polkassembly can implement some solutions. Or perhaps this can be a task for UX bounty? Anyway, I’m curious about your opinions.

9 Likes

Maybe, Provide hashing of the original document in the body of the proposal as requisite?

4 Likes

The fellowship approves its rank retention proposals through a vote on a hash.
The same process could be used here; additionally to the spending call it can remark the hash of the proposal.
It would also be possible to store the proposal in the preimages pallet or something along those lines.

Relying on UI front ends is possibly problematic if they are recipients of grants themselves but would probably be easier short-term. Also they should eventually enforce the convention that OpenGov settles on.

We could even create a new treasury spending call that takes a memo hash that is mandatory.

2 Likes

The referenda pallet already supports to set metadata of a referendum. This could be used to store the hash of the document. It also sends an event to follow any changes.

5 Likes

Yeah, it definitely needs tackled. It’s hardly acceptable in a ‘trustless’ ecosystem for proposers to have the one main document as to their accountability under their own control to be altered or removed at will.

IPFS uses content based addressing - which means that a given address is a hash and the content it links to cannot be changed.
You can, of course, store another version under a different hash.

Pinning to IPFS is not as obvious as making a Google doc, but can (if my info is still valid) be done for free by signing up to a service like Pinata - so not much more overhead for the user than signing up to ‘Google’, whoever that is.

Pinning through one free provider is reasonably reliable but doesn’t actually guarantee that the content will stay up for ever, though it would be not technically complex or expensive for treasury to fund auto-pinning of every proposal text.

Also, Crust network is a gateway to IPFS so normalising IPFS for proposals would leave us the option in future to build tools, working on a Polkadot parachian to easily integrate into subsquare, polkassembly, etc.

3 Likes

Also, there is a topic here on where to store the documents of the proposals, as many people I think uses Gdrive to upload the proposal.

Food for though, even more relevant in the turbulent world of today.

1 Like

I seem to have got a rep for bashing web2 services for (for example) the fact that they ultimately control the content you store on them and, yeah, we should get away from that.

But seems to me the far more important problem in this case is that on Google/ Gdrive (but in reality almost anywhere else too), that proposer has the power to alter, hide or permission access to the content - the ability to erase or manipulate evidence is a big plus for dishonest, grifty or spammy proposers.

2 Likes

I agree we should definitely enforce the hash of the actual proposal to be in the metadata of the referendum. We should put it in https://opengov.watch (@alice_und_bob) and start making noise about it

1 Like

I also chatted with Nino from UX Bounty, and he said they are already working on something. I shared this forum post with him, maybe the comments above will somehow help them decide what to do next. Thanks to everyone who shared their opinion, I hope this issue will be tackled in the near future.

1 Like

The problem is the metadata hash isn’t worth much when documents just disappear. You need to actually store the document somewhere.

Also most of the time the proposal is a Google doc, not a persisted file.

If you want to enforce it, there needs to be a persistent storage where files are submitted to and only then you can submit the ref on-chain. E.g. have a storage chain and require a valid pointer to a file on the storage chain

Metadata hash ensures integrity, persistent decentralized storage ensures availability.

Two different problems with 2 solutions: both complete the issue as a whole

2 Likes

Just want to bring attention to a proposal that even asks people to fill the form if they want to see the full proposal: PolkaWorld Ops and Maintenance proposal:2025.4 - 2026.3

After clucking on “full proposal”: View the full PolkaWorld proposal

This is getting ridiculous

1 Like

Yeah, i was thinking the other day about this: let’s give a fix for this.

Two questions:

The referenda pallet already supports to set metadata of a referendum. This could be used to store the hash of the document. It also sends an event to follow any changes.

Can this be used to providing a solution ? Can someone from the technical side scope the problem and - looks like - outline a solution ?

Is the RFP a way to provide some funding for the gig?

Let’s see if with a bit of coordination we can give a solution to this problem.

I actually tried using the referendum metadata feature for past referenda. Technically, yes, the referenda pallet supports setting metadata. However, I ran into a limitation: Polkadot JS UI seems hardcoded to interpret every preimage as a call, which makes it pretty much unusable when the metadata is not a call, but just a reference. I might be wrong, but it seems that the UI is useless for showing referendum metadata, which could be a hash of a PDF.

It’d be great if Polkassembly or Subsquare could explore this, maybe allowing users to upload a PDF, generate the hash client-side, and then attach that hash as referendum metadata. Ideally, it could be abstracted so the user doesn’t even see the hashing.

1 Like

The field being big enough for an average URL or other identifiers would also be nice. For the governance of Kreivo DAOs we use the ref metadata to store ids of matrix rooms, each ref has its own room where the first post becomes the ref context and any other messages become the discussion.
I wish this could become the standard, matrix is not just element, rooms are a decentralized storage and would keep track of the updates not only to the ref context and discussions but also can store attachments and other data.

I think it’s a great discussion and highlights a fundamental gap: we definitely need certainty about proposal content, both now and historically.

What I’m mulling over is: why aren’t we leveraging git [1] more directly for the proposal lifecycle itself?

Platforms like Polkassembly/Subsquare are fantastic governance dashboards, syncing off-chain data between each other (to offer a singular view) and hosting discussion after a proposal is submitted. But they don’t inherently solve the problem of the proposal’s source document(s) being mutable or disappearing, they’re focused primarily on tracking events post-submission. Furthermore, the essence of the proposals, the data, is locked in databases that are only accessible via the APIs the platforms provide.

So then, what if the “source of truth” for a proposal was a specific git commit hash of a common open-gov git (not github) repo?

This hash represents the exact state of the proposal files (proposal.md, parameters, etc.) at the moment it’s finalized for voting & signed by the submitter. You then reference this hash in the on-chain metadata, and this hash isn’t a floating identifier, but one that is linked to a common repository, that is independently verifiable from the presentation layers (no need for trust). Subsequent edits are immediately visible and easily auditable[2], without having to rely on the platforms actually activating the feature or ensuring their database remains functional to view historical edits… Also, if these platforms are down, what then, who is currently backing up things and checking the proposal content and the content of the linked documents [3] ?

This repo being used frequently, the risk of data vanishing from it is low, as backing it up is also convenient and extremely cheap if it’s just text data. A policy of “no external links” would then seal the deal completely. I know very well that this would also make data collection and syncing orders of magnitude easier than today where we mostly resort to hitting multiple APIs in a loop, and then from scratch again to catch all the deltas since the last back fill.

This would shift the focus to managing the proposal content with robust versioning and verifiable persistence before it even hits the chain or Polkassembly/Subsquare dashboards. Of course a UI to make submissions easy would be crucial so non-devs can apply too without having to know what rebasing means, but that’s a solvable challenge if the backend is robust: git fits the bill imho.

Doesn’t a git-centric workflow combined with decentralized storage refs (commit hash + set_metadata as Basti suggests) in the metadata offer a more robust & resilient end to end “less trust, more truth” foundation here?

From experience, always bet on text[4] has been a good rule of thumb. It’s cheap to backup and doesn’t require any big infrastructure for archival & upkeep: tens of thousands of proposals could be stored in 10 MB. Depending whom you ask, additional benefits could be: no random pictures meant to persuade rather than inform, easy parsing by LLMs, etc…

Google docs, PDFs, links to forms are certainly convenient for the proposer, not the community. A git based approach is not without a small inconvenience tax, but what price do we want to put on truth?


  1. Git - Wikipedia ↩︎

  2. Checking that the hash matches the data is difficult, error-prone and should be automated so voters know they vote on the right thing and not a moving target ↩︎

  3. I know who :wink: ↩︎

  4. Graydon’s article ↩︎

3 Likes

I’d still vote and invite people consider Matrix :wink: Worth mentioning that events in rooms are stored in a directed acyclic graph not much different from git. Git seems like a good idea but it won’t be very friendly and practical to integrate with for apps, likely leading to commits to the repo be performed by the apps instead of the users. With Matrix we will get similar and many more benefits(e.g. discussions, moderation) still keeping things decentralized, any specific needs not covered by the default event types could also be defined as a custom protocol(e.g. apps doing data aggregations, etc.).

I’d be happy to define the Matrix based architecture as a protocol everyone can implement and since it’s something we already need for DAOs, we can also create the tools/libraries to make integration in existing products easy.

1 Like

Completely agree with the issue outlined here, and I’ve been running into it repeatedly during recent proposal due diligence work. Deleted or silently edited proposal docs make it almost impossible to reconstruct intent or verify what was originally submitted - a transparency gap that undermines our OpenGov processes.

@Karim — I really, really like your Git idea. The commit-hash-as-truth model is powerful, and the “no external links” policy especially to centralized storages is exactly the kind of norm shift we need. Versioning, integrity, traceability, all spot on. But we also need to be realistic about proposer experience. For non-technical users (which is a big chunk of OpenGov participants), Git-based workflows are intimidating at best and exclusionary at worst. I would say a lot of proposers would be overwhelmed or flat-out blocked by not knowing how to rebase, let alone reference a commit hash in on-chain metadata correctly.

We could say DVs, OpenGov.Watch, W3F, or others could hand-hold proposers through the process and that might work and is working for high-value proposals, but it becomes a real bottleneck for onboarding new ecosystem contributors or scaling day-to-day participation.

Therefore I think the Git model would be a serious hurdle for most proposers, and the UX tax is just too high for something that needs to become a default standard.

That said, I agree that we can get most of the benefit with far less complexity using decentralized storage and simple client-side tools.

A simpler path: IPFS + metadata hash

I assume we already have decentralized storage rails available in the ecosystem:

  • IPFS (already used informally)
  • Crust Network
  • StorageHub (in development)
  • Filecoin integrations via ecosystem tooling

A better default might be:

  1. Proposer uploads their .pdf or .md file to IPFS or Crust.
  2. System returns the CID.
  3. That CID is included in the referendum submission via set_metadata as proposed by Basti
  4. UIs like Polkassembly/Subsquare render the content directly or verify the hash.

This gives us:

  • Immutable reference to the actual proposal content.
  • On-chain anchoring of the proposal state at submission time.
  • No dependency on mutable third-party links.
  • No Git complexity.

Add a basic front-end tool that handles the upload + CID generation and even autofills the metadata string, and you’ve got something enforceable, scalable, and user-friendly.

However, Git can still play a role, as a mirror archive, as a backend for ecosystems like OpenGov.Watch, or even for deeper tracking of proposal diffs but the core submission and audit path should be as low-friction as possible, especially for new contributors.

3 Likes

That’s brilliant @olanod. It solves a lot of the issues around decentralizing proposal content and discussions, and also opens up a bunch of useful possibilities.

One of the main security concerns is how decentralized the Matrix servers really are, especially when it comes to supporting custom protocols and handling event retention. Even in the worst case improves the current situation and the cumbersome and limited git and IPFS alternatives suggested. That said, you can always back things up in cold storage like IPFS, assuming there’s reliable pinning. Worth noting that if content isn’t pinned in IPFS, it’s basically gone. The same logic applies to Matrix—there has to be some value layer to ensure persistence and reliability.

The Matrix approach with authenticated DAGs by namespace, granular access control / authenticated posting by the originator, and custom event types looks like a solid solution overall.

Another thing to think about is moderation—striking a balance between blocking spam and avoiding censorship. Who gets to moderate, and how can decisions be audited in a permissionless way?

It’s a really valuable perspective, and you both raise great points. I have read the links you shared and played a little bit around with the idea locally, so here are my 2 WNDs. Please note though that I might still have some unknown unknowns with regards to the Matrix protocol, so I won’t take offense if you tell me that I’m wrong on this or that thing.

To go back to the specific problem we started with: how to immutably and verifiably tie the exact content of a proposal (as finalized by the proposer) to the on-chain submission and keep it around long enough, I think it’s helpful to focus on these core requirements. My understanding of the issue so far is that we need:

  1. A permanent pointer to a specific content state.
  2. Cryptographic proof the proposer signed off on that specific state.
  3. Confidence the content remains available and easily retrievable over time.

Comparing the Git-based approach with Matrix through these angles gives:

  • A Git commit hash fundamentally represents a snapshot of the entire proposal workspace (e.g., proposal.md, params.json) at a single point in time. This maps very directly to our need for “the final version” of a proposal. While Matrix event IDs are also immutable references to specific event data, representing the “final proposal state” might require interpreting a sequence of events (m.replaces need to be traversed to reconstruct the state) or defining custom event types that encapsulate the full state. It feels potentially less direct for simply pointing to the document, or am I missing something here? If you have a link to how you’re using it, it would be very helpful for me to get an idea.
  • Both approaches can achieve verifiability. With Git, the user signs the commit hash with their Polkadot key, creating an undeniable link between their on-chain identity and that specific Git state. With Matrix, the user signs events with their Matrix key (which could be easily linked to their Polkadot ID), and we could potentially store the final event ID + Polkadot signature on-chain. Both work, the Git hash might be slightly simpler conceptually (at least to me) as it represents the whole package.
  • Practicalities have to be kept in mind when considering accessibility for tooling. What I mean is that governance dashboards like Polkassembly/Subsquare need to fetch and display the proposal content to enable informed voting. Integrating a Git client call (fetch content at repo_url + commit_hash) seems potentially more straightforward for them than integrating a Matrix client specifically tailored to parse and render the “final proposal state” from potentially complex room history or custom events. Git is inherently built for retrieving historical file states. Matrix would need a GET https://matrix.to/#/<room_id_or_alias>/<event_id> + some elbow grease.
  • Both Git & Matrix rely on infrastructure for persistence. Git relies on the repo host (centralized like GitHub/GitLab, or potentially decentralized like Radicle, plus community clones) and just amounts to a bunch of files. Matrix relies on homeserver availability and federation, a more involved infrastructure than what Git would require. Arguably, standard Git repos with text content are extremely easy and cheap for anyone in the community to clone/mirror for redundancy.

Usability is a crucial topic and always top of mind for me, and let me clarify, as this response might stem from a slight misunderstanding of the workflow I’m proposing:

  1. Users don’t need to know about git: The core idea is not that proposers need to learn git commit, git push, etc. Instead, they would use a user-friendly web UI (like snapshot.box or similar), dissociated from the UI used to vote. I should have made this a bit more explicit with my rebase joke. How I see it, is that this submission UI looks like a document editor, handles all the Git operations (commit, push) behind the scenes, and culminates in the user performing one critical action:
    1. The UI presents the final commit hash (representing their finalized text) and asks the user to sign this hash using their Polkadot wallet. This is the vital step connecting their on-chain identity to the content, regardless of whether a backend service technically authored the Git commit itself.

So, while apps would interact with the Git repo, the user’s authority and intent are captured via the Polkadot signature of the content hash, not via Git GPG signing or direct command line use. This is roughly the same idea to hide underlying mechanics of how the blockchains operate yet still leverage their benefits. In essence: users don’t want to submit extrinsics, they want to get stuff done.

Now, Matrix clearly offers powerful features, especially for integrating discussion around the proposal (maybe the Matrix room could link to the canonical Git commit?). However, for the specific, narrow task of establishing an immutable, long lived, cost efficient & verifiable source of truth for the proposal document itself, the Git commit hash approach feels like a very direct, robust, and potentially easier to integrate solution.

Perhaps the most productive way forward is to explore the practicalities further? What if we scoped out the implementation effort required for:

  • Option A: Building a PoC of the Git-based UI and backend, demonstrating the user flow (editor → Git commit → Polkadot signature → on-chain reference).
  • Option B: Defining the Matrix protocol (custom events?) for storing proposal state and outlining the integration work needed for dashboards to consume it reliably, alongside what the user should do & build the solution out.
  • Option C: Data archival bounty (?), à la archive.org built on top of IPFS for governance data?

Comparing the estimated complexity, development time, and integration friction for existing platforms to adopt each approach might give us a much clearer picture of the true costs and benefits in the short to medium term. I’m happy to support wherever I can, although my bias is clearly for option A ^^

Regardless, I do believe that the effort won’t be wasted, and what we’ll end up with could be something quite cool. I must admit that I enjoyed being nerd-sniped by this topic. :+1:

3 Likes