DomainsProposal domains.proposal@1

Generated at from openvibe-contracts v0.419.0 and openvibe-sdk v0.161.0.

Version
1.0.0
Owner
domains
Visibility
public
Status
active
Compatibility
backward
Schema
https://openvibe.network/contracts/domains/proposal.v1.json

A change to a person's DNS on OpenVibe.Domains (plan 2026-10-28 §5.1): nothing an agent, a bulk edit or the person's own edit asks for touches DNS until the person approves it. A proposal holds the record diff, why, what could break, and its rollback; approving it applies the changes in order through the provider's API with the person's connected credential (a Network project secret, ADR-056, never part of this document). A change whose record moved since the proposal was made is refused as stale; rolling back applies the inverse changes.

Fields

FieldTypeRequiredDescriptionConstraints
idstringyes
  • pattern ^dpr_[0-9A-HJKMNP-TV-Z]{26}$
domainstringyes
  • minLength 3
  • maxLength 253
providerenumyes
  • one of "cloudflare", "porkbun", "namecheap", "spaceship"
connection_idstringyes
  • pattern ^dcn_[0-9A-HJKMNP-TV-Z]{26}$
titlestringyes
  • minLength 1
  • maxLength 160
whystring | null
  • maxLength 1000
riskstring | nullWhat could break, in plain words.
  • maxLength 1000
statusenumyes
  • one of "pending", "applying", "applied", "declined", "failed", "rolled_back", "expired"
changesarray of objectyes
  • minItems 1
  • maxItems 50
  • items: no other fields
changes[].openumyes
  • one of "create", "update", "delete"
changes[].record_idstring | nullThe provider's record id (update, delete; a create's after it is applied).
  • maxLength 64
changes[].beforeone of
changes[].afterone of
changes[].typeenumA registrar change: the domain's nameservers at the registry. op is update only; before and after are the lists.
  • one of "NS"
created_bystringyes
  • pattern ^(user|agent|service):
  • maxLength 120
created_atstringyes
  • format date-time
decided_atstring | null
  • format date-time
applied_atstring | null
  • format date-time
rolled_back_atstring | null
  • format date-time
expires_atstring | null
  • format date-time
errorstring | null
  • maxLength 400
hrefstringyes
  • pattern ^https://
  • format uri

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: create-txt
{
  "id": "dpr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3",
  "domain": "example.com",
  "provider": "cloudflare",
  "connection_id": "dcn_01J8Z3Q4R5S6T7V8W9X0Y1Z2A4",
  "title": "Add the TXT record that proves example.com is yours",
  "why": "Your mail provider asks for it.",
  "risk": "None: a TXT record changes no traffic.",
  "status": "pending",
  "changes": [
    {
      "op": "create",
      "record_id": null,
      "before": null,
      "after": {
        "type": "TXT",
        "name": "example.com",
        "content": "proof=abc123",
        "ttl": 1,
        "proxied": null,
        "priority": null,
        "comment": null
      }
    }
  ],
  "created_by": "user:usr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A5",
  "created_at": "2026-10-28T18:00:00.000Z",
  "decided_at": null,
  "applied_at": null,
  "rolled_back_at": null,
  "expires_at": "2026-11-04T18:00:00.000Z",
  "error": null,
  "href": "https://openvibe.domains/panel/proposals/dpr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3"
}
Valid: nameservers
{
  "id": "dpr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3",
  "domain": "example.com",
  "provider": "porkbun",
  "connection_id": "dcn_01J8Z3Q4R5S6T7V8W9X0Y1Z2A4",
  "title": "Point example.com at Cloudflare",
  "why": "Your mail provider asks for it.",
  "risk": "None: a TXT record changes no traffic.",
  "status": "pending",
  "changes": [
    {
      "op": "update",
      "type": "NS",
      "record_id": null,
      "before": [
        "curitiba.ns.porkbun.com",
        "fortaleza.ns.porkbun.com"
      ],
      "after": [
        "ada.ns.cloudflare.com",
        "bob.ns.cloudflare.com"
      ]
    }
  ],
  "created_by": "user:usr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A5",
  "created_at": "2026-10-28T18:00:00.000Z",
  "decided_at": null,
  "applied_at": null,
  "rolled_back_at": null,
  "expires_at": "2026-11-04T18:00:00.000Z",
  "error": null,
  "href": "https://openvibe.domains/panel/proposals/dpr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3"
}
Valid: update-applied
{
  "id": "dpr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3",
  "domain": "example.com",
  "provider": "cloudflare",
  "connection_id": "dcn_01J8Z3Q4R5S6T7V8W9X0Y1Z2A4",
  "title": "Add the TXT record that proves example.com is yours",
  "why": "Your mail provider asks for it.",
  "risk": "None: a TXT record changes no traffic.",
  "status": "applied",
  "changes": [
    {
      "op": "update",
      "record_id": "372e67954025e0ba6aaa6d586b9e0b59",
      "before": {
        "type": "A",
        "name": "www.example.com",
        "content": "192.0.2.1",
        "ttl": 1,
        "proxied": true,
        "priority": null,
        "comment": null
      },
      "after": {
        "type": "A",
        "name": "www.example.com",
        "content": "192.0.2.7",
        "ttl": 1,
        "proxied": true,
        "priority": null,
        "comment": null
      }
    }
  ],
  "created_by": "user:usr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A5",
  "created_at": "2026-10-28T18:00:00.000Z",
  "decided_at": "2026-10-28T18:01:59.000Z",
  "applied_at": "2026-10-28T18:02:00.000Z",
  "rolled_back_at": null,
  "expires_at": "2026-11-04T18:00:00.000Z",
  "error": null,
  "href": "https://openvibe.domains/panel/proposals/dpr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3"
}
Rejected: bad-op
{
  "id": "dpr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3",
  "domain": "example.com",
  "provider": "cloudflare",
  "connection_id": "dcn_01J8Z3Q4R5S6T7V8W9X0Y1Z2A4",
  "title": "Add the TXT record that proves example.com is yours",
  "why": "Your mail provider asks for it.",
  "risk": "None: a TXT record changes no traffic.",
  "status": "pending",
  "changes": [
    {
      "op": "replace_all",
      "record_id": null,
      "before": null,
      "after": null
    }
  ],
  "created_by": "user:usr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A5",
  "created_at": "2026-10-28T18:00:00.000Z",
  "decided_at": null,
  "applied_at": null,
  "rolled_back_at": null,
  "expires_at": "2026-11-04T18:00:00.000Z",
  "error": null,
  "href": "https://openvibe.domains/panel/proposals/dpr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3"
}
Rejected: token-in-proposal
{
  "id": "dpr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3",
  "domain": "example.com",
  "provider": "cloudflare",
  "connection_id": "dcn_01J8Z3Q4R5S6T7V8W9X0Y1Z2A4",
  "title": "Add the TXT record that proves example.com is yours",
  "why": "Your mail provider asks for it.",
  "risk": "None: a TXT record changes no traffic.",
  "status": "pending",
  "changes": [
    {
      "op": "create",
      "record_id": null,
      "before": null,
      "after": {
        "type": "TXT",
        "name": "example.com",
        "content": "proof=abc123",
        "ttl": 1,
        "proxied": null,
        "priority": null,
        "comment": null
      }
    }
  ],
  "created_by": "user:usr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A5",
  "created_at": "2026-10-28T18:00:00.000Z",
  "decided_at": null,
  "applied_at": null,
  "rolled_back_at": null,
  "expires_at": "2026-11-04T18:00:00.000Z",
  "error": null,
  "href": "https://openvibe.domains/panel/proposals/dpr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3",
  "api_token": "example-not-a-secret"
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('domains.proposal@1', value);   // { valid, errors: [{ path, message }] }