Active Tense vs Passive Tense

Starting this Category off by migrating this conversation here. Really hoping we can have more of these convos out in the open here, so others can weigh in, and future folks can see our decision log / history!

3 Likes

This should definitely be turned into a standard.

Where and how should we capture standards like this? Definitely in the documentation, as per @zet.box

But also - should things like this be formal IIPS? So people can easily reference them in the future?

And should we have different types of IIPS → some for protocol changes, some for standard semantics, etc?

1 Like

Here’s how I’d think through this and what I suggest (there are trade-offs). Happy to refine further based on constraints (cost, human resources, trust assumptions, usability, governance, complexity).

Making it complex is easy (we just add stuff) so I will start it that way so it can be simplified to the optimal flow.

Key desiderata for saving “protocol / governance / discussion”

There’s no one perfect solution, but if I were designing for robustness, here’s what I’d consider “best in practice” for Intuition use case:

  • Immutability — once recorded, it should not be easy to silently change or remove content.
  • Verifiability — someone should be able to check “this record came from that discussion at that time.”
  • Decentralization — survive organizational changes or hosting failures.
  • Discoverability — easy to locate relevant records, reference them, see context (not just raw blobs).
  • Access control — some records might be internal or sensitive, so we might want encryption or restricted access.
  • Practical overhead — not too onerous for community members to capture and verify.

Process to record protocol decisions and preserve provenance

Given we already have a forum (Discourse) and a discussion (Discord, calls, emails, slack, etc.), here’s a workflow I’d propose:

  1. Capture primary artifact

    • After a decision is made (e.g. in Discord, voice call, etc.), designate someone (scribe) to publish a decision summary / minutes as a forum post here (e.g. in a “protocol changes” category).

    • Include in that post: date, participants, full context (link back to original chat, thread, or screenshot attachments if needed). Optionally, embed the screenshot(s) or raw transcript excerpt(s) inside the post (for human readability).

  2. Store the full content in IPFS / Arweave / decentralized storage

    • Publish the full decision document (could be the forum post export, markdown, PDF, or JSON) into IPFS / Arweave.

    • Ensure pinning / redundancy (so it doesn’t disappear). Possibly leverage a pinning service or community nodes.

    • Optionally, use content management that links the IPFS content hash in the forum post metadata (so the forum post says “IPFS CID: …”).

  3. Create an Intuition Triple (claim) that points to the content

    • Make an on-chain Triple (a claim) whose URI points to the IPFS CID (or contains the CID in metadata). Triples/Atoms in Intuition are intended for storing URIs and relationships. This gives you an on-chain, signed, verifiable pointer to the canonical content.
  4. Sign the Triple with a governance identity (Atom)

    • Use an authoritative Intuition Atom (an identity controlled by your governance org or multisig) to sign the Triple so observers know who attested to the decision.
  5. Record transaction hash & registry

    • Save the Intuition transaction hash (tx) in your decisions registry (on the forum, in a git repo, and/or in the JSON you published). The registry entry should include: forum post link, IPFS CID, Intuition Triple/tx hash, signer identity, and a human summary.
  6. Optional: additional external anchoring

    • If you want extra redundancy/trust (public, harder to censor), also anchor the CID or the Intuition tx hash into another large L1 (Bitcoin / Ethereum via OpenTimestamps or a minimal tx). This is optional but increases confidence for adversarial threat models.
  7. Provide verification tooling

    • Publish or embed a small verification app that: fetches the IPFS content, computes its digest, fetches the Intuition Triple, checks the URI/CID matches and verifies the signature / tx presence. This makes audits one-click for community members.

Technical sketch (high level)

Here’s a draft of a possible Canonical JSON schema for the decision artifact:

{
  "schema": "intuition-protocol-decision-v1",
  "id": "protocol/decision/<YYYYMMDD>-<short-id>",
  "title": "Human readable title",
  "date": "2025-10-14T15:23:00Z",
  "proposer": {
    "name": "Billy",
    "atom": "did:intuition:0xABC123..." 
  },
  "participants": [
    "did:intuition:0x000000...",
    "did:intuition:0x000000..."
  ],
  "summary": "One-paragraph human summary of the decision.",
  "body": "Full canonicalized body of the decision in Markdown or plain text. If you include attachments, list them in `attachments` with their CIDs.",
  "attachments": [
    {
      "filename": "discord-screenshot-1.png",
      "description": "Relevant chat screenshot",
      "cid": "bafy... (ipfs CIDv1)"
    }
  ],
  "source_links": [
    "https://discordapp.com/channels/.../message/...",
    "https://atlas.discourse.group/t/..."
  ],
  "ipfs_cid": "bafy... (the IPFS CID of this canonical JSON)",
  "digest": {
    "algorithm": "sha-256",
    "hex": "0123abcd... (lowercase hex of sha256 over canonicalized JSON bytes)"
  },
  "meta": {
    "category": "protocol-decision",
    "tags": ["governance", "hard-fork", "parameter-change"],
    "version": 1
  }
}

Here’s a draft of the automation bot flow (pseudo-code):

// Config
DISCOURSE = { apiUrl, apiKey, botUsername, categoryId }
IPFS = { apiUrl, authToken? }
INTUITION = { graphqlUrl, atomPrivateKey, signerAddress }
REGISTRY_REPO = { gitUrl, credentials } // optional

// Helper: canonicalizeJson(obj) => canonicalJsonBytes (RFC8785)
// Helper: sha256Hex(bytes)

// 1. Watch or receive webhook from Discourse for new posts in category
onNewDiscoursePost(post):
  if not isDecisionPost(post): return

  // 2. Gather canonical content
  artifact = {
    schema: "intuition-protocol-decision-v1",
    id: generateId(post),                 // e.g. protocol/decision/20251014-0001
    title: post.title,
    date: post.created_at_utc,
    proposer: { name: post.author, atom: lookupAtom(post.author) },
    participants: extractParticipants(post), // parse mentions, reactions, meeting notes
    summary: generateSummary(post),         // could be post excerpt or human-edited
    body: normalizeBody(post.content),      // strip Discourse markup / canonicalize attachments
    attachments: fetchAndAttachMedia(post),
    source_links: [post.url] + extractReferencedLinks(post),
    meta: { category: "protocol-decision", tags: post.tags }
  }

  // 3. Canonicalize and compute digest
  canonical_bytes = canonicalizeJson(artifact) // deterministic bytes
  digest_hex = sha256Hex(canonical_bytes)
  artifact.digest = { algorithm: "sha-256", hex: digest_hex }

  // 4. Upload to IPFS
  ipfs_result = ipfs.add(canonical_bytes) // returns CIDv1
  artifact.ipfs_cid = ipfs_result.cid
  // optionally re-upload attachments to IPFS and store their cids in artifact.attachments

  // 5. Update the canonical JSON with ipfs_cid, re-canonicalize and recompute digest OR
  //    (preferred) include digest of the canonical bytes before IPFS step, then IPFS returns CID of same bytes.
  //    Note: ensure the canonical bytes uploaded are exactly the bytes used to compute digest.

  // 6. Create Intuition Triple payload
  triple = {
    subject: "intuition://protocol/decision/" + artifact.id,
    predicate: "pointsTo",
    object: "ipfs://" + artifact.ipfs_cid,
    metadata: {
      digest: artifact.digest,
      title: artifact.title,
      proposer: artifact.proposer,
      source_forum: post.url,
      attachments: artifact.attachments
    }
  }

  // 7. Sign / submit triple
  signed = signTripleWithAtom(triple, INTUITION.atomPrivateKey)
  tx = submitTripleToIntuition(signed) // via GraphQL or SDK

  // 8. Pin the IPFS cid on pinning services (automated)
  pinningService.pin(artifact.ipfs_cid)

  // 9. Publish back to Discourse
  message = buildResultMessage(artifact.ipfs_cid, artifact.digest.hex, tx.hash)
  discourse.postReply(post.id, message)

  // 10. (optional) update git registry, create a record file
  registry.addDecisionRecord(artifact.id, { ipfs_cid, digest, tx_hash: tx.hash, forum_url: post.url })

end

Whatever process or flow you decide for, I can build an interface to catalog it or help in any way needed.