From 52671031884eea6881e647a9753714c35464e7a8 Mon Sep 17 00:00:00 2001 From: Daniel Swid Date: Thu, 25 Jun 2026 12:01:31 -0700 Subject: [PATCH 1/2] feat(Policy Manifest): methodology library updates * introduce policy manifest schema, spec, and taxonomy * add POLICY_MANIFEST_PRD.md to rfcs directory Refs: Story: #6031 Reviewed-by: na Test-scope: n Signed-off-by: Daniel Swid --- Methodology Library/MANIFEST_SPEC.md | 274 ++++++++++ Methodology Library/TAG_TAXONOMY.md | 221 ++++++++ Methodology Library/policy.schema.json | 390 ++++++++++++++ rfcs/POLICY_MANIFEST_PRD.md | 690 +++++++++++++++++++++++++ 4 files changed, 1575 insertions(+) create mode 100644 Methodology Library/MANIFEST_SPEC.md create mode 100644 Methodology Library/TAG_TAXONOMY.md create mode 100644 Methodology Library/policy.schema.json create mode 100644 rfcs/POLICY_MANIFEST_PRD.md diff --git a/Methodology Library/MANIFEST_SPEC.md b/Methodology Library/MANIFEST_SPEC.md new file mode 100644 index 0000000000..c9f38ee66d --- /dev/null +++ b/Methodology Library/MANIFEST_SPEC.md @@ -0,0 +1,274 @@ +# Guardian Policy Manifest Specification + +> **Audience**: policy contributors and methodology authors adding or updating a policy in the Guardian Methodology Library. +> **Full PRD**: see [POLICY_MANIFEST_PRD.md](./POLICY_MANIFEST_PRD.md). +> **Schema**: [policy.schema.json](./policy.schema.json) + +--- + +## Quick start — minimal valid `policy.yml` + +Drop this file alongside your `.policy` bundle. Fill in the required fields; all others are optional. + +```yaml +id: my-policy-slug # kebab-case, globally unique, stable +name: My Policy Name # human-readable display name +version: "1.0.0" # semver of this Guardian implementation +description: > + One-to-three sentences explaining what this policy does and + which upstream methodology it implements. +policy_type: standard-implementation # see policy_type guide below +status: active # draft | candidate | active | deprecated | superseded +license: Apache-2.0 # SPDX identifier +category: carbon-offsets # see category enum below +authors: + - name: Your Organization +tags: + - your-tag + - another-tag +``` + +That is the complete minimum. Everything else is optional but strongly encouraged for published policies. + +--- + +## Field reference + +### Required fields + +| Field | Type | Description | Example | +|-------|------|-------------|---------| +| `id` | string | Kebab-case unique slug. Must be stable across versions — never change once published. | `verra-vm0007-redd-plus` | +| `name` | string | Human-readable display name (3–120 chars). | `Verra VM0007 REDD+ Methodology Framework` | +| `version` | string | Semver of this Guardian implementation. See [versioning](#versioning-convention). | `3.0.0` | +| `description` | string | 1–3 sentence plain-English summary (20–600 chars). | | +| `policy_type` | enum | See [policy_type guide](#policy_type-guide). | `standard-implementation` | +| `status` | enum | `draft` \| `candidate` \| `active` \| `deprecated` \| `superseded` | `active` | +| `license` | string | SPDX license identifier. | `Apache-2.0` | +| `category` | enum | `carbon-offsets` \| `emission-reporting` \| `supply-chain` \| `biodiversity` \| `payments` \| `other` | `carbon-offsets` | +| `authors` | array | One or more `{name, url?, type?, github?}` objects. | See below | +| `tags` | array | Lowercase-hyphenated strings. See [TAG_TAXONOMY.md](./TAG_TAXONOMY.md). | `[verra, redd-plus, forest]` | + +### Optional fields (strongly recommended for active policies) + +| Field | Type | Description | Example | +|-------|------|-------------|---------| +| `standard_body` | string | Standards organization owning the upstream methodology. | `Verra` | +| `methodology_id` | string | Upstream methodology identifier. | `VM0007` | +| `methodology_version` | string | Upstream version verbatim. | `7.0` | +| `token_type` | string | Token symbol minted by this policy. | `VCU` | +| `token_standard` | enum | `fungible` \| `HIP-412-NFT` \| `none` | `fungible` | +| `registry_status` | enum | `none` \| `pending` \| `validated` \| `revoked` | `validated` | +| `registry_body` | string | Registry that validated (when `registry_status: validated`). | `Verra` | +| `registry_reference` | string | Formal registry reference number. | `VCS-1234` | +| `registry_accepted_date` | string | ISO 8601 date of registry acceptance. | `2024-03-15` | +| `ipfs_timestamp` | string | IPFS timestamp of the most recent mainnet publication (testnet if not yet on mainnet). Full history lives in `publications.json`. | `"1707207286.119377003"` | +| `sdg_alignment` | array | UN SDG numbers 1–17. | `[13, 15]` | +| `sector` | string | `energy` \| `transport` \| `waste` \| `land-use` \| `industrial` \| `agriculture` \| `water` \| `other` | `land-use` | +| `guardian_version_min` | string | Minimum Guardian platform version required. | `2.20.0` | +| `roles` | array | Role name strings defined in the workflow. | `["Standard Registry", "Project Proponent", "VVB"]` | +| `dependencies` | array | `{id, version_min?}` — other Guardian module IDs required. | | +| `supersedes` | string \| null | ID of the policy this replaces. | `gold-standard-mecd-v1` | +| `superseded_by` | string \| null | ID of policy that replaces this one. | | +| `resources` | array | External links. See [resources array](#resources-array). | | +| `contributors` | array | `{name, github?}` contributors beyond primary authors. | | +| `maintainers` | array | `{name, email?, url?}` current maintainers. | | +| `thumbnail` | string | Relative path to thumbnail image. See [thumbnails](#thumbnail-conventions). | `assets/thumbnail.png` | +| `homepage` | string | Upstream methodology or project homepage URL. | | +| `support` | string | Support URL or email address. | | + +--- + +## `policy_type` guide + +| Value | Use when... | Examples | +|-------|-------------|---------| +| `standard-implementation` | The policy faithfully implements a published methodology from a recognized standards body (Verra, Gold Standard, CDM, etc.). The methodology_id and standard_body fields should always be populated. | VM0007 REDD+, GS MECD, CDM AMS-III.BA | +| `novel-methodology` | The policy implements a new methodology not yet (or not fully) covered by an external standard, or a hybrid/extension of existing methodologies. May or may not have a registry_status. | EUDR Pre-Check, MMCM combined methodology, LIP | +| `mrv-template` | A reusable skeleton or scaffolding policy for a class of MRV projects. Not a complete policy on its own — intended to be forked and parameterized. | DOVU MMCM, generic dMRV templates | +| `proof-of-concept` | An exploratory or demonstration policy, not intended for production use. Typically found in Hackathon/ or Work In Progress/. | Hackathon submissions | +| `toolkit` | A set of schemas, modules, or utilities that support policy development but do not constitute a stand-alone policy workflow. | Modules/, reusable schema packs | + +--- + +## Status lifecycle + +Policies move through the following states: + +``` + ┌─────────┐ + initial commit │ │ + ─────────────────► │ draft │ + │ │ + └────┬────┘ + │ ready for review + ▼ + ┌────────────┐ + │ │ + │ candidate │ + │ │ + └──────┬─────┘ + │ passes review / live on testnet + ▼ + ┌──────────┐ + ┌──────────────│ │──────────────────────────┐ + │ issues │ active │ newer version published │ + │ found │ │ │ + ▼ └──────────┘ ▼ + ┌────────────┐ ┌────────────────┐ + │ │ │ │ + │ deprecated │ │ superseded │ + │ │ │ │ + └────────────┘ └────────────────┘ +``` + +- **draft** — work in progress; schema may be incomplete. +- **candidate** — implementation complete and under review; suitable for testnet use. +- **active** — production-ready; approved for mainnet publication. +- **deprecated** — no longer recommended; kept for reference. Set `superseded_by` if a replacement exists. +- **superseded** — explicitly replaced by another policy. Set `superseded_by` to the new policy's `id`. + +When a policy moves to `superseded`, set `superseded_by` in the old manifest and `supersedes` in the new one. + +--- + +## Versioning convention + +Two version fields serve different purposes: + +| Field | Tracks | Example | +|-------|--------|---------| +| `version` | The Guardian **implementation** — policy file, schemas, workflow logic, bug fixes | `3.0.0` | +| `methodology_version` | The **upstream methodology** version as published by the standards body | `7.0` | + +Increment `version` using standard semver rules: +- **Patch** (`x.y.Z`): bug fixes, documentation, minor schema corrections. +- **Minor** (`x.Y.0`): new roles, new optional fields, workflow improvements that are backward-compatible. +- **Major** (`X.0.0`): breaking schema changes, workflow redesign, major methodology version bump. + +`methodology_version` is copied verbatim from the upstream standard (e.g., `"7.0"` for VM0007 v7, `"2.0"` for MECD v2.0). It does not follow semver; it mirrors whatever the standard body publishes. + +--- + +## Publication records + +Publication history is split across two files with different ownership: + +| File | Who writes it | How | +|---|---|---| +| `policy.yml` (`ipfs_timestamp`) | Policy author | Manually — paste the most recent mainnet timestamp (or testnet if not yet on mainnet) | +| `publications.json` | The `record-publication` script | Automatically — run once after each Guardian publish action | + +### `ipfs_timestamp` in `policy.yml` + +A single convenience field for the most recent mainnet publication — used by Guardian's one-click import. Update it whenever a new mainnet version is published. + +```yaml +# Most recent mainnet IPFS timestamp. Full history in publications.json. +ipfs_timestamp: "1707207286.119377003" +``` + +For testnet-only policies, use the testnet timestamp. The absence of a mainnet entry in `publications.json` is itself a visible signal in the catalog (no "Live on mainnet" badge). + +### `publications.json` — the full history + +After publishing in Guardian, run: + +```bash +node scripts/record-publication.js \ + --policy verra-vm0007-redd-plus \ + --network mainnet \ + --version 3.0.0 \ + --ipfs-timestamp 1707207286.119377003 \ + --topic-id 0.0.5678901 +``` + +The script appends one record to `publications.json` in the policy folder. **Never edit `publications.json` by hand.** + +The file is validated against `publications.schema.json`. See `Verra/Verified Carbon Standard (VCS)/VM0007/publications.json` for a worked example with multiple network entries across three versions. + +--- + +## Resources array + +Link to external references that help users understand or verify the policy: + +```yaml +resources: + - type: methodology + label: "Verra VM0007 REDD+ Methodology Framework" + url: "https://verra.org/methodologies/vm0007-redd-methodology-framework-redd-mf/" + - type: demo-guide + label: "Guardian Demo Guide — Verra REDD+" + url: "https://docs.hedera.com/guardian/guardian/demo-guide/carbon-offsets/verra-redd+-demo-guide" + - type: research + label: "Berkeley Cookstove Overcrediting Study (2023)" + url: "https://assets.researchsquare.com/files/rs-2606020/v1/c2e6a772-b013-49f9-9fc4-8d7d82d4bebc.pdf" +``` + +Allowed `type` values: `methodology`, `regulation`, `research`, `demo-guide`, `api-docs`, `tool`, `dataset`, `other`. + +--- + +## Thumbnail conventions + +- Place the thumbnail in an `assets/` subdirectory next to `policy.yml`. +- Reference it as a relative path: `thumbnail: assets/thumbnail.png` +- Recommended dimensions: **400 × 300 px** (4:3 ratio). +- Accepted formats: PNG (preferred) or JPEG. +- Maximum file size: 200 KB. +- If `thumbnail` is omitted, the catalog falls back to a generated icon based on `category` and `policy_type`. + +--- + +## Tag guidance + +See [TAG_TAXONOMY.md](./TAG_TAXONOMY.md) for the full canonical tag list and naming rules. + +Key rules: +- All tags must be lowercase and hyphenated: `redd-plus`, not `REDD+` or `redd_plus`. +- Include at least one standard-body tag if `standard_body` is set. +- Include at least one thematic tag. +- Include a geographic tag if the policy is region-specific. + +--- + +## Validation + +### Validate locally with AJV + +Install the AJV CLI (requires Node.js 18+): + +```bash +npm install -g ajv-cli ajv-formats +``` + +Validate a single `policy.yml`: + +```bash +# Convert YAML to JSON first (requires js-yaml or yq) +yq -o=json . path/to/policy.yml > /tmp/policy.json + +# Validate against the schema +ajv validate \ + --spec=draft2020 \ + -c ajv-formats \ + -s "Methodology Library/policy.schema.json" \ + -d /tmp/policy.json +``` + +### Validate all manifests at once + +```bash +find "Methodology Library" -name "policy.yml" | while read f; do + yq -o=json . "$f" > /tmp/policy.json + echo -n "$f: " + ajv validate --spec=draft2020 -c ajv-formats \ + -s "Methodology Library/policy.schema.json" \ + -d /tmp/policy.json 2>&1 | tail -1 +done +``` + +### CI + +A GitHub Actions workflow (`.github/workflows/validate-manifests.yml`) runs this check on every PR that touches a `policy.yml` file. Failures block merge. Tag warnings (unrecognized tags from `TAG_TAXONOMY.md`) are reported as annotations but do not block merge. diff --git a/Methodology Library/TAG_TAXONOMY.md b/Methodology Library/TAG_TAXONOMY.md new file mode 100644 index 0000000000..8873a858cf --- /dev/null +++ b/Methodology Library/TAG_TAXONOMY.md @@ -0,0 +1,221 @@ +# Tag Taxonomy — Guardian Methodology Library + +This document provides guidance for choosing `tags` values in `policy.yml` manifests. Tags drive search and filtering in the catalog UI and any tooling built on top of the manifest index. + +--- + +## Naming convention + +Tags must be **lowercase and hyphenated** — no spaces, no uppercase, no underscores, no dots. + +``` +# Good +forest, redd-plus, dynamic-baseline, latin-america + +# Bad +Forest, REDD+, dynamic_baseline, Latin America +``` + +Tags are validated against the `pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$"` regex in `policy.schema.json`. Any tag that does not match this pattern will fail schema validation and block CI. + +--- + +## CI behaviour + +- **Unrecognized tags** (i.e., tags not listed in this document) trigger a **warning** in CI but do **not** fail the build. +- Schema-invalid tags (wrong format) **do** fail CI. +- The intent is to keep the taxonomy open and evolving without blocking contributors. Warnings surface in the PR check output so reviewers can decide whether a new tag should be canonicalized. + +--- + +## Proposing a new canonical tag + +1. Open a PR adding your tag to the relevant section of this file with a one-line description. +2. Link the PR to the policy that first uses the tag. +3. Maintainers will merge if the tag is broadly useful (likely to appear in 3+ policies), not redundant with an existing tag, and follows the naming convention. + +You do not need to wait for approval to use a tag — use it in your `policy.yml` and let CI warn. Canonicalization is a catalog quality concern, not a contribution blocker. + +--- + +## Canonical tag categories + +### Standard bodies + +Tags that identify the issuing standards organization. Use the organization's commonly recognized short name. + +| Tag | Description | +|-----|-------------| +| `verra` | Verra (Verified Carbon Standard / VCS program) | +| `gold-standard` | Gold Standard Foundation | +| `cdm` | UNFCCC Clean Development Mechanism | +| `unfccc` | United Nations Framework Convention on Climate Change (non-CDM) | +| `gcc` | Global Carbon Council | +| `climate-action-reserve` | Climate Action Reserve (CAR) | +| `iso-14064` | ISO 14064 series (GHG quantification and reporting) | +| `gs` | Alias for `gold-standard` — prefer the full form | +| `ieta` | International Emissions Trading Association | +| `car` | Alias for `climate-action-reserve` — prefer the full form | +| `irec` | International Renewable Energy Certificate standard | + +--- + +### Thematic / project activity + +Tags describing what the project activity does or the environmental asset type. + +| Tag | Description | +|-----|-------------| +| `forest` | Forest-based projects generally | +| `redd-plus` | REDD+ (Reducing Emissions from Deforestation and Forest Degradation) | +| `cookstoves` | Clean cooking / improved cookstove projects | +| `agriculture` | Agricultural activities (crop, livestock, soil) | +| `landfill` | Landfill gas capture and destruction | +| `renewable-energy` | Renewable electricity generation | +| `water` | Safe drinking water, water treatment | +| `transport` | Transport-sector emission reductions | +| `plastic` | Plastic waste recovery and recycling | +| `mangrove` | Mangrove conservation and restoration | +| `rice` | Methane reduction from rice cultivation | +| `biochar` | Biochar production and soil application | +| `soil-carbon` | Soil carbon sequestration (broader than biochar) | +| `clean-energy` | Clean energy access (broader than renewable-energy) | +| `e-waste` | Electronic waste recovery and recycling | +| `end-of-life-vehicles` | End-of-life vehicle recycling | +| `biodiversity` | Biodiversity co-benefits or primary focus | +| `blue-carbon` | Ocean/coastal carbon (mangrove, seagrass, salt marsh) | +| `agroforestry` | Combined agriculture and forestry activities | +| `living-income` | Farmer living-income price frameworks | +| `fair-trade` | Fair-trade aligned supply-chain policies | +| `social-impact` | Primary focus on social outcomes | +| `farmer-payments` | Direct farmer payment mechanisms | + +--- + +### Technical / methodological approach + +Tags describing the MRV approach, technical mechanisms, or Guardian-specific patterns. + +| Tag | Description | +|-----|-------------| +| `dynamic-baseline` | Uses a dynamic (rather than fixed) baseline calculation | +| `additionality` | Explicit additionality test or tool embedded in the workflow | +| `mrv` | General MRV / monitoring-reporting-verification emphasis | +| `monitoring` | Continuous or device-level monitoring (use alongside mrv) | +| `nfc` | Near-field communication data capture | +| `deforestation` | Deforestation avoidance or detection | +| `afforestation` | Planting trees on previously non-forested land | +| `reforestation` | Replanting trees after deforestation | +| `revegetation` | Vegetation restoration (broader category) | +| `suppressed-demand` | Suppressed demand baseline methodology | +| `geospatial` | Polygon / GIS / satellite-data driven workflows | +| `metered-monitoring` | Device-level metered data collection | +| `paris-aligned` | Explicit alignment with Paris Agreement accounting | +| `ndc-aligned` | Aligned with national Nationally Determined Contributions | +| `mrv-template` | Reusable MRV scaffolding (policy_type: mrv-template) | + +--- + +### Geographic + +Tags identifying the primary geographic focus. Use the broadest applicable tag; add a more specific one if relevant. + +| Tag | Description | +|-----|-------------| +| `global` | No specific geographic restriction | +| `africa` | Sub-Saharan Africa or African continent broadly | +| `east-africa` | East Africa specifically | +| `west-africa` | West Africa specifically | +| `asia` | Asia broadly | +| `south-asia` | South Asia (India, Pakistan, Bangladesh, etc.) | +| `southeast-asia` | Southeast Asia | +| `latin-america` | Latin America and the Caribbean | +| `europe` | European Union and/or broader Europe | +| `north-america` | United States, Canada, Mexico | +| `oceania` | Australia, New Zealand, Pacific Islands | + +--- + +### Programme / origin + +Tags describing how the policy entered the library or the initiative it belongs to. + +| Tag | Description | +|-----|-------------| +| `hackathon` | Created as part of a Guardian hackathon | +| `bounty` | Created as part of a Guardian methodology bounty program | +| `template` | Intended as a reusable starting-point template | +| `community` | Community-contributed (not backed by a standards org) | +| `dovu` | Contributed by or in partnership with DOVU | +| `tymlez` | Contributed by or in partnership with Tymlez | +| `atec` | Contributed by or in partnership with ATEC | +| `envision` | Contributed by or in partnership with Envision Blockchain | +| `supply-chain` | Alias for use as a thematic marker in supply-chain policies | + +--- + +### Output type / token + +Tags describing what the policy mints or certifies. + +| Tag | Description | +|-----|-------------| +| `carbon-credit` | Generic carbon credit output | +| `cer` | Certified Emission Reduction (CDM) | +| `vcu` | Verified Carbon Unit (Verra VCS) | +| `ver` | Verified Emission Reduction (Gold Standard) | +| `nft` | NFT output (use `HIP-412-NFT` in token_standard — this tag adds searchability) | +| `token` | General token output | +| `certificate` | Non-token certificate or credential issuance | +| `eudr` | EU Deforestation Regulation compliance output | + +--- + +## Examples + +A few sample tag lists to illustrate good practice: + +```yaml +# Verra REDD+ — forest, standard-aligned +tags: + - verra + - redd-plus + - forest + - deforestation + - dynamic-baseline + - land-use + +# Gold Standard cookstoves — geographic + thematic +tags: + - gold-standard + - cookstoves + - clean-energy + - africa + - metered-monitoring + - paris-aligned + +# Community MRV template — origin + activity +tags: + - dovu + - agriculture + - soil-carbon + - mrv-template + - template + +# EUDR supply chain — regulation-driven +tags: + - eudr + - deforestation + - supply-chain + - geospatial + - forest + - europe +``` + +--- + +## Version history + +| Date | Change | +|------|--------| +| 2026-06-11 | Initial taxonomy established | diff --git a/Methodology Library/policy.schema.json b/Methodology Library/policy.schema.json new file mode 100644 index 0000000000..4b1176aa9f --- /dev/null +++ b/Methodology Library/policy.schema.json @@ -0,0 +1,390 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://guardian.hedera.com/schemas/policy-manifest/v1.0.0/policy.schema.json", + "title": "Guardian Policy Manifest", + "description": "JSON Schema for validating policy.yml sidecar manifest files in the Guardian Methodology Library.", + "type": "object", + + "required": [ + "id", + "name", + "version", + "description", + "policy_type", + "status", + "license", + "category", + "authors", + "tags" + ], + + "additionalProperties": false, + + "properties": { + + "id": { + "type": "string", + "description": "Globally unique kebab-case slug for this policy. Must be stable across versions.", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "examples": ["verra-vm0007-redd-plus", "gold-standard-mecd-v2"] + }, + + "name": { + "type": "string", + "description": "Human-readable display name shown in the catalog.", + "minLength": 3, + "maxLength": 120, + "examples": ["Verra VM0007 REDD+ Methodology Framework"] + }, + + "version": { + "type": "string", + "description": "Semantic version of this Guardian policy implementation (not the upstream methodology version).", + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", + "examples": ["3.0.0", "1.0.0-rc.1"] + }, + + "description": { + "type": "string", + "description": "One-to-three sentence plain-English summary of what this policy does.", + "minLength": 20, + "maxLength": 600 + }, + + "policy_type": { + "type": "string", + "description": "Classification of the policy's relationship to upstream standards.", + "enum": [ + "standard-implementation", + "novel-methodology", + "mrv-template", + "proof-of-concept", + "toolkit" + ] + }, + + "status": { + "type": "string", + "description": "Lifecycle state of this Guardian implementation.", + "enum": [ + "draft", + "candidate", + "active", + "deprecated", + "superseded" + ] + }, + + "license": { + "type": "string", + "description": "SPDX license identifier (e.g. Apache-2.0, MIT, CC-BY-4.0).", + "minLength": 2, + "examples": ["Apache-2.0", "MIT", "CC-BY-4.0"] + }, + + "category": { + "type": "string", + "description": "Broad domain this policy belongs to.", + "enum": [ + "carbon-offsets", + "emission-reporting", + "supply-chain", + "biodiversity", + "payments", + "other" + ] + }, + + "authors": { + "type": "array", + "description": "Organizations or individuals primarily responsible for this Guardian implementation.", + "minItems": 1, + "items": { + "type": "object", + "required": ["name"], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "Display name of the author.", + "minLength": 1 + }, + "url": { + "type": "string", + "format": "uri", + "description": "Author's website or profile URL." + }, + "type": { + "type": "string", + "description": "Author classification.", + "enum": ["organization", "individual", "community"] + }, + "github": { + "type": "string", + "description": "GitHub username or org handle (without @).", + "pattern": "^[a-zA-Z0-9]([a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$" + } + } + } + }, + + "tags": { + "type": "array", + "description": "Lowercase-hyphenated discovery tags. See TAG_TAXONOMY.md for guidance.", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "description": "A single lowercase-hyphenated tag." + } + }, + + "standard_body": { + "type": "string", + "description": "Name of the standards organization that owns the upstream methodology (e.g. Verra, Gold Standard). Omit for community-developed policies.", + "examples": ["Verra", "Gold Standard", "UNFCCC CDM", "ISO"] + }, + + "methodology_id": { + "type": "string", + "description": "Upstream methodology identifier as used by the standard body (e.g. VM0007, MECD, AMS-III.BA).", + "examples": ["VM0007", "MECD", "AMS-III.BA"] + }, + + "methodology_version": { + "type": "string", + "description": "Version of the upstream methodology this policy implements, verbatim as published by the standard body.", + "examples": ["7.0", "2.0", "3.1"] + }, + + "token_type": { + "type": "string", + "description": "Symbol or name of the token minted by this policy (e.g. VCU, VER, CER, EUDRT).", + "examples": ["VCU", "VER", "CER", "EUDRT", "LIT", "CRT"] + }, + + "token_standard": { + "type": "string", + "description": "Hedera token standard used.", + "enum": [ + "fungible", + "HIP-412-NFT", + "none" + ] + }, + + "registry_status": { + "type": "string", + "description": "Status of this policy/project with the external registry body.", + "enum": [ + "none", + "pending", + "validated", + "revoked" + ] + }, + + "registry_body": { + "type": "string", + "description": "Name of the registry body that validated this policy (only meaningful when registry_status is validated).", + "examples": ["Verra", "Gold Standard", "Gold Standard Foundation"] + }, + + "registry_reference": { + "type": "string", + "description": "Formal reference number assigned by the registry (e.g. a VCS project ID).", + "examples": ["VCS-1234", "GS-5678"] + }, + + "registry_accepted_date": { + "type": "string", + "description": "ISO 8601 date on which the registry formally accepted or validated this policy.", + "format": "date", + "examples": ["2024-03-15"] + }, + + "ipfs_timestamp": { + "type": "string", + "description": "IPFS timestamp of the most recent mainnet publication (or testnet if not yet on mainnet), as returned by Guardian's publish API. Full publication history — all networks and versions — is recorded in publications.json by the record-publication script; never edit that file by hand.", + "pattern": "^[0-9]+\\.[0-9]+$", + "examples": ["1707207286.119377003"] + }, + + "sdg_alignment": { + "type": "array", + "description": "UN Sustainable Development Goal numbers (1-17) that this policy directly supports.", + "uniqueItems": true, + "items": { + "type": "integer", + "minimum": 1, + "maximum": 17 + }, + "examples": [[13, 15], [3, 7, 13]] + }, + + "sector": { + "type": "string", + "description": "Primary economic sector of the underlying project activity.", + "enum": [ + "energy", + "transport", + "waste", + "land-use", + "industrial", + "agriculture", + "water", + "other" + ] + }, + + "guardian_version_min": { + "type": "string", + "description": "Minimum Guardian platform version required to run this policy.", + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-.+)?$", + "examples": ["2.20.0", "2.25.0"] + }, + + "roles": { + "type": "array", + "description": "Named roles defined in the policy workflow.", + "items": { + "type": "string", + "minLength": 1 + }, + "examples": [["Standard Registry", "Project Proponent", "VVB"]] + }, + + "dependencies": { + "type": "array", + "description": "Other Guardian modules or tool IDs this policy depends on.", + "items": { + "type": "object", + "required": ["id"], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "description": "ID of the dependency module (must match that module's id field).", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" + }, + "version_min": { + "type": "string", + "description": "Minimum version of the dependency required." + } + } + } + }, + + "supersedes": { + "type": ["string", "null"], + "description": "ID of the policy this manifest replaces. Null or omit if this is the first version.", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "examples": ["gold-standard-mecd-v1"] + }, + + "superseded_by": { + "type": ["string", "null"], + "description": "ID of the policy that replaces this one (set when status becomes superseded).", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" + }, + + "resources": { + "type": "array", + "description": "External references relevant to this policy (methodology docs, regulatory texts, research papers).", + "items": { + "type": "object", + "required": ["type", "label"], + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "description": "Category of the resource.", + "enum": [ + "methodology", + "regulation", + "research", + "demo-guide", + "api-docs", + "tool", + "dataset", + "other" + ] + }, + "label": { + "type": "string", + "description": "Human-readable link label.", + "minLength": 1 + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL to the resource (optional if the resource is described by label alone)." + } + } + } + }, + + "contributors": { + "type": "array", + "description": "Individuals or organizations who contributed to this implementation but are not primary authors.", + "items": { + "type": "object", + "required": ["name"], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "minLength": 1 + }, + "github": { + "type": "string", + "pattern": "^[a-zA-Z0-9]([a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$" + } + } + } + }, + + "maintainers": { + "type": "array", + "description": "Current maintainers responsible for keeping this policy up to date.", + "items": { + "type": "object", + "required": ["name"], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "minLength": 1 + }, + "email": { + "type": "string", + "format": "email" + }, + "url": { + "type": "string", + "format": "uri" + } + } + } + }, + + "thumbnail": { + "type": "string", + "description": "Relative path to a thumbnail image (from the policy.yml file location). Recommended: 400x300 PNG/JPEG.", + "examples": ["assets/thumbnail.png", "thumbnail.jpg"] + }, + + "homepage": { + "type": "string", + "format": "uri", + "description": "Canonical URL for the upstream methodology or project homepage." + }, + + "support": { + "type": "string", + "description": "URL (GitHub issues, forum) or email address for policy support.", + "examples": ["https://github.com/hashgraph/guardian/issues", "support@example.com"] + } + } +} diff --git a/rfcs/POLICY_MANIFEST_PRD.md b/rfcs/POLICY_MANIFEST_PRD.md new file mode 100644 index 0000000000..1860cec2ab --- /dev/null +++ b/rfcs/POLICY_MANIFEST_PRD.md @@ -0,0 +1,690 @@ +# Product Requirements Document: Guardian Policy Manifest (`policy.yml`) + +| Field | Value | +|-------|-------| +| **Status** | Draft — for stakeholder review | +| **Author** | Guardian Platform Team | +| **Date** | 2026-06-11 | +| **Version** | 0.1 | +| **Related docs** | [MANIFEST_SPEC.md](./MANIFEST_SPEC.md), [policy.schema.json](./policy.schema.json), [TAG_TAXONOMY.md](./TAG_TAXONOMY.md) | + +--- + +## Table of Contents + +1. [Executive Summary](#1-executive-summary) +2. [Problem Statement](#2-problem-statement) +3. [Goals and Non-Goals](#3-goals-and-non-goals) +4. [User Personas](#4-user-personas) +5. [Proposed Solution](#5-proposed-solution) +6. [Full Field Specification](#6-full-field-specification) +7. [policy_type Taxonomy](#7-policy_type-taxonomy) +8. [Status and Registry Status Lifecycles](#8-status-and-registry-status-lifecycles) +9. [Tag Taxonomy Guidance](#9-tag-taxonomy-guidance) +10. [Versioning Convention](#10-versioning-convention) +11. [Thumbnail Specification](#11-thumbnail-specification) +12. [Publications Array](#12-publications-array) +13. [Success Metrics](#13-success-metrics) +14. [Phased Rollout](#14-phased-rollout) +15. [Open Questions and Decisions Needed](#15-open-questions-and-decisions-needed) + +--- + +## 1. Executive Summary + +The Guardian Methodology Library currently contains more than 90 policy folders containing `.policy` bundles, README files, and assorted supporting documents. None of this content is machine-readable in a structured way. Discovering, filtering, and comparing policies requires manually reading Markdown files or relying on institutional knowledge. + +This PRD proposes introducing a `policy.yml` sidecar manifest as a first-class interface to every policy in the library. The manifest captures structured metadata — identity, versioning, policy type, token type, publication records, SDG alignment, tags, and more — in a format that can be validated, indexed, queried, and rendered without parsing free-form prose. + +--- + +## 2. Problem Statement + +### 2.1 Current state + +| Pain point | Detail | +|-----------|--------| +| **No machine-readable metadata** | Policy identity, authorship, versioning, and methodology lineage exist only in README prose. No programmatic access is possible without LLM-assisted parsing. | +| **No filtering or discovery** | A developer or policy buyer who wants "all active Verra REDD+ policies on mainnet" has no query path. They must read every folder. | +| **Inconsistent documentation** | Some policies have detailed READMEs with workflow diagrams and IPFS timestamps; others have one paragraph. There is no enforcement of a minimum information set. | +| **No lineage tracking** | When a policy supersedes an earlier version (e.g., MECD v2.0 supersedes v1.2), that relationship is buried in prose. Tools cannot follow the supersession chain. | +| **Publication records are ad-hoc** | IPFS timestamps and Hedera topic IDs appear in various formats across READMEs — sometimes in tables, sometimes inline. Multi-network awareness (testnet vs mainnet) is inconsistent. | +| **No SDG or sector indexing** | There is no way to ask "show me all policies that contribute to SDG 13 in the energy sector" without manual reading. | +| **No validation gate** | A contributor can add a policy with any structure. There is no CI check enforcing a minimum metadata contract. | + +### 2.2 Why this matters now + +The Guardian ecosystem is maturing. The Methodology Library is being used by: +- Registry bodies evaluating Guardian as a compliance infrastructure. +- Developers building policy catalogs, comparison tools, and carbon marketplaces on top of Guardian. +- New contributors who need clear onboarding signals. +- The Guardian team itself, for prioritizing documentation and support effort. + +Without structured metadata, every downstream use case requires bespoke scraping or manual curation. The cost of that compounds as the library grows past 100 policies. + +--- + +## 3. Goals and Non-Goals + +### Goals + +- Establish a single, validated, machine-readable metadata contract for every policy in the library. +- Enable filtering, search, and catalog rendering without parsing prose. +- Track policy lineage (supersession chains), publication history (multi-network), and registry validation status. +- Provide a contributor-facing spec that is lightweight enough that a new contributor can fill out a manifest in under 30 minutes. +- Enforce a minimum metadata floor via JSON Schema validation in CI. +- Create the foundation for a library mini-site (Phase 3) and Guardian platform integration (Phase 4) without requiring those phases to be completed first. + +### Non-Goals + +- Replacing the README. The manifest is a sidecar; prose documentation remains important and is not deprecated. +- Enforcing a closed tag set. Tags are guidance-driven, not a hard closed enum (see Section 9). +- Automating policy import/export into Guardian. The manifest is a metadata layer, not a deployment mechanism. +- Defining the schema of the `.policy` file itself. The manifest describes the policy; it does not replace the policy bundle format. +- Providing a UI in this phase. The manifest is infrastructure; a catalog UI is Phase 3. + +--- + +## 4. User Personas + +### 4.1 Ravi — Methodology Expert and Prospective Contributor + +**Who**: A data scientist or environmental researcher at an international NGO with deep expertise in monitoring frameworks for smallholder agriculture. Comfortable with data pipelines and familiar with standards like Gold Standard and Verra. Has been experimenting with blockchain-adjacent tools and arrives at Guardian with genuine intent to contribute a methodology that isn't well served by anything currently in the library. + +**Goals**: +- Understand where his work would fit relative to the existing library. +- Find a legible starting point — what the minimum bar looks like and what a complete entry looks like. +- Contribute without reinventing the documentation structure from scratch. +- Know his work will be discoverable and won't look equivalent to a weekend hackathon entry. + +**Pain points today**: +- No template to follow; README structure is invented from scratch each time. +- No validation to confirm important fields haven't been missed. +- The library reads like an unmaintained inbox rather than a curated platform — a qualified expert recalibrates their estimate of how much effort adoption will take and quietly deprioritises it. + +**How `policy.yml` helps**: A structured file with required/optional fields, inline comments, and `policy_type` classification gives Ravi a legible on-ramp. The `novel-methodology` type explicitly positions his work as a first-class category, not a deficit state relative to registry-validated entries. + +--- + +### 4.2 Maya — Sustainability Manager, Food & Beverage + +**Who**: ESG lead at a mid-size food company with a complex agricultural supply chain, under increasing pressure from buyers and regulators to prove traceability claims. Technically literate but not a developer. Moves fast, judges platforms quickly, and has learned to trust her instincts about whether something is production-ready or still a science project. + +**Goals**: +- Identify whether any production-grade Guardian policies exist for her supply chain use case. +- See at a glance who built them, whether they are live on mainnet, and whether a recognised body has validated them. +- Make a go/no-go recommendation to her team without needing a developer to translate. + +**Pain points today**: +- Must open dozens of README files to find anything relevant — no filtering by sector or status. +- No trust signal distinguishes a production implementation from a hackathon prototype. +- When she can't find that signal quickly, she doesn't dig deeper. She hands it to a consultant. + +**How `policy.yml` helps**: Catalog tooling (Phase 3) renders filterable cards from manifest data. `status`, `registry_status`, mainnet publication indicators, and `standard_body` are immediately visible without opening a README — Maya gets her signal in under three minutes. + +--- + +### 4.3 Priya — Programme Officer, Standards Registry + +**Who**: A programme officer at Gold Standard or Verra whose remit includes monitoring the digital ecosystem around their published methodologies. She didn't build Guardian and doesn't operate it day-to-day, but she periodically needs to know which Guardian implementations claim to be based on their standards, at which version, and whether anyone is using a `validated` signal without going through the proper endorsement process. + +**Goals**: +- Find all Guardian policies claiming to implement their methodologies, with version information. +- Verify that `methodology_id`, `methodology_version`, and `standard_body` fields are accurate. +- Identify who to contact about implementations that misrepresent the methodology version or status. +- Track which implementations have been through the formal validation process. + +**Pain points today**: +- No way to query "all Guardian policies implementing MECD at any version" — requires manually reading every folder. +- Registry status is not recorded at all; there is no distinction between a community demo and a formally endorsed implementation. +- She hears Guardian mentioned in a partner conversation, searches the library, finds three policies claiming to implement their methodology, can't tell which are accurate or current, and makes a note to follow up manually — which never happens. + +**How `policy.yml` helps**: Fields `standard_body`, `methodology_id`, `methodology_version`, `registry_status`, `registry_body`, and `registry_reference` give Priya a structured, queryable view of all policies claiming to implement her standard. The `registry_status: validated` field is the formal signal she controls — and the schema makes clear who set it and when. + +--- + +### 4.4 Omar — Engineer, Carbon Marketplace + +**Who**: A software engineer at a carbon marketplace or ESG data platform tasked with building a "browse Guardian policies" feature for their product. He is comfortable with APIs and JSON but has no deep Guardian expertise. He needs a stable, queryable index he can depend on — consistent IDs, machine-readable status, IPFS timestamps he can pass directly to an import API. + +**Goals**: +- Index all policies without scraping Markdown. +- Filter by category, sector, token type, network, and status programmatically. +- Follow supersession chains to show users when a policy has been replaced. +- Retrieve IPFS timestamps and Hedera topic IDs reliably for downstream import flows. + +**Pain points today**: +- Zero machine-readable data — every integration requires custom parsing of inconsistent prose. +- IPFS timestamps appear in different formats across READMEs; some policies have none at all. +- No canonical policy ID — names vary across files, issues, and forum posts. +- He builds a scraper, ships it, and it silently breaks the next time someone adds a policy in an unexpected format. He files it as tech debt and deprioritises Guardian integrations. + +**How `policy.yml` helps**: A JSON Schema-validated YAML file with a stable `id` field, consistent field shapes, and a generated `catalog.json` provides the stable contract Omar needs. Supersession chains, network-aware publication records, and semver versioning are all machine-readable without parsing prose. + +--- + +## 5. Proposed Solution + +### 5.1 Overview + +Introduce a `policy.yml` sidecar manifest file in every policy folder. The file lives alongside the `.policy` bundle and README. It is: + +- **YAML** for human readability and inline comments. +- **Validated** against `policy.schema.json` (JSON Schema draft 2020-12) in CI. +- **Stable** — the `id` field is a permanent slug that never changes once a policy is published. +- **Additive** — only a small core of fields is required; all others are opt-in. +- **Versioned** — the schema itself is versioned via the `$id` URI. + +### 5.2 File placement + +``` +Methodology Library/ + Verra/ + Verified Carbon Standard (VCS)/ + VM0007/ + policy.yml ← manifest (this PRD) + readme.md ← existing prose docs (unchanged) + Policies/ + Verra VM0007 (3.0.0 - groups).policy + Gold Standard/ + Metered Energy Cooking/ + MECD v2.0/ + policy.yml + readme.md + MECD-v2.0.policy +``` + +### 5.3 Relationship to other files + +| File | Role | Changed by this PRD? | +|------|------|----------------------| +| `policy.yml` | Machine-readable manifest (author-maintained) | New | +| `publications.json` | Append-only publication log (script-maintained) | New per policy folder | +| `README.md` | Human-readable prose documentation | No — unchanged | +| `*.policy` | Guardian policy bundle (import artifact) | No | +| `policy.schema.json` | JSON Schema for `policy.yml` validation | New (library root) | +| `publications.schema.json` | JSON Schema for `publications.json` validation | New (library root) | +| `TAG_TAXONOMY.md` | Tag naming guidance | New (library root) | +| `MANIFEST_SPEC.md` | Contributor-facing spec | New (library root) | + +--- + +## 6. Full Field Specification + +### 6.1 Required fields + +| Field | Type | Pattern / Enum | Description | Example | +|-------|------|---------------|-------------|---------| +| `id` | string | `^[a-z0-9]+(?:-[a-z0-9]+)*$` | Globally unique kebab-case slug. Permanent — never changed after first publish. | `verra-vm0007-redd-plus` | +| `name` | string | 3–120 chars | Human-readable display name. | `Verra VM0007 REDD+ Methodology Framework` | +| `version` | string | semver regex | Semver of this Guardian implementation. | `3.0.0` | +| `description` | string | 20–600 chars | 1–3 sentence plain-English summary. | | +| `policy_type` | enum | See Section 7 | Classification relative to upstream standards. | `standard-implementation` | +| `status` | enum | `draft\|candidate\|active\|deprecated\|superseded` | Implementation lifecycle state. | `active` | +| `license` | string | SPDX identifier | Open source license. | `Apache-2.0` | +| `category` | enum | `carbon-offsets\|emission-reporting\|supply-chain\|biodiversity\|payments\|other` | Primary domain. | `carbon-offsets` | +| `authors` | array | See 6.3 | Primary authors/organizations. | `[{name: Envision Blockchain}]` | +| `tags` | array | `^[a-z0-9]+(?:-[a-z0-9]+)*$` each | Discovery tags. | `[verra, redd-plus, forest]` | + +### 6.2 Optional fields + +| Field | Type | Pattern / Enum | Description | Example | +|-------|------|---------------|-------------|---------| +| `standard_body` | string | — | Standards organization owning the upstream methodology. | `Verra` | +| `methodology_id` | string | — | Upstream methodology identifier. | `VM0007` | +| `methodology_version` | string | — | Upstream version verbatim as published. | `7.0` | +| `token_type` | string | — | Token symbol minted by this policy. | `VCU` | +| `token_standard` | enum | `fungible\|HIP-412-NFT\|none` | Hedera token standard. | `fungible` | +| `registry_status` | enum | `none\|pending\|validated\|revoked` | Status with external registry. | `validated` | +| `registry_body` | string | — | Registry that validated. | `Verra` | +| `registry_reference` | string | — | Formal registry reference number. | `VCS-1234` | +| `registry_accepted_date` | string | ISO 8601 date | Date of registry acceptance. | `2024-03-15` | +| `ipfs_timestamp` | string | `^[0-9]+\.[0-9]+$` | Most recent mainnet IPFS timestamp (testnet if not yet on mainnet). Full history in `publications.json`. | `"1707207286.119377003"` | +| `sdg_alignment` | array | integers 1–17 | UN SDG numbers supported. | `[13, 15]` | +| `sector` | enum | `energy\|transport\|waste\|land-use\|industrial\|agriculture\|water\|other` | Primary economic sector. | `land-use` | +| `guardian_version_min` | string | semver | Minimum Guardian platform version. | `2.20.0` | +| `roles` | array | strings | Named workflow roles. | `["Standard Registry", "VVB"]` | +| `dependencies` | array | See 6.5 | Required Guardian modules. | | +| `supersedes` | string\|null | kebab-case | ID of policy this replaces. | `gold-standard-mecd-v1` | +| `superseded_by` | string\|null | kebab-case | ID of policy that replaces this. | | +| `resources` | array | See 6.6 | External reference links. | | +| `contributors` | array | See 6.7 | Non-author contributors. | | +| `maintainers` | array | See 6.8 | Current maintainers. | | +| `thumbnail` | string | relative path | Path to thumbnail image. | `assets/thumbnail.png` | +| `homepage` | string | URI | Upstream methodology homepage. | | +| `support` | string | URI or email | Support URL or email. | | + +### 6.3 authors / contributors / maintainers objects + +``` +authors / contributors: + name: string required display name + url: string optional website or profile URL + type: string optional "organization" | "individual" | "community" + github: string optional GitHub handle (without @) + +maintainers: + name: string required + email: string optional email address + url: string optional website URL +``` + +### 6.4 ipfs_timestamp + +A nanosecond-precision Unix epoch string returned by Guardian's publish API. Stored as a quoted string to preserve decimal precision. Points to the most recent mainnet publication; use the testnet timestamp if the policy has not yet reached mainnet. Full multi-network history is in `publications.json` — see Section 12. + +### 6.5 dependencies array items + +``` +id: string required kebab-case ID matching the dependency's own id field +version_min: string optional minimum semver of the dependency +``` + +### 6.6 resources array items + +``` +type: string required "methodology"|"regulation"|"research"|"demo-guide"|"api-docs"|"tool"|"dataset"|"other" +label: string required human-readable link label +url: string optional URI (omit if resource has no URL) +``` + +### 6.7 sdg_alignment + +Array of integers between 1 and 17 inclusive, with unique values. Maps to the 17 UN Sustainable Development Goals. + +### 6.8 tags + +Array of unique strings, each matching `^[a-z0-9]+(?:-[a-z0-9]+)*$`. No maximum count is enforced by the schema, but 3–10 tags is typical. See TAG_TAXONOMY.md for canonical values. + +--- + +## 7. `policy_type` Taxonomy + +The `policy_type` field classifies the policy's fundamental relationship to upstream standards. It affects how the catalog presents the policy and which fields are most meaningful. + +| Value | Description | Required companion fields | Example policies | +|-------|-------------|--------------------------|-----------------| +| `standard-implementation` | Faithfully implements a methodology published and maintained by a recognized external standards body. The implementation may extend or digitize the methodology but does not fundamentally deviate from it. | `standard_body`, `methodology_id`, `methodology_version` strongly recommended | VM0007, MECD v2.0, CDM AMS-III.BA | +| `novel-methodology` | Implements a new or hybrid methodology that is not (fully) covered by any single external standard, or that originated within the Guardian ecosystem. May seek registry validation in future. | None required but `registry_status: none\|pending` typical | EUDR Pre-Check, MMCM (combined CDM), Living Income Price | +| `mrv-template` | A reusable template or scaffolding for a class of MRV projects. Not a complete policy on its own — designed to be forked, parameterized, and specialized by downstream implementors. | None strictly required; `methodology_id` may be present | DOVU generic dMRV template, MMCM | +| `proof-of-concept` | Exploratory or demonstration policy. Typically created during hackathons or bounty programs. Not intended for production use. | None | Hackathon submissions, Work In Progress entries | +| `toolkit` | A collection of schemas, modules, or Guardian configuration utilities that support policy development but are not stand-alone policy workflows. | None | Modules/ entries, reusable schema packs | + +### Disambiguation notes + +- A policy that implements CDM AMS-III.BA and adds novel Guardian-specific automation is still `standard-implementation` — the novel automation is an implementation detail, not a methodology deviation. +- A policy that _combines_ AMS-III.BA and AMS-III.AJ into a new blended approach for a new project type (e.g., MMCM's ELV recycling) is `novel-methodology` or `mrv-template` depending on whether it is production-ready. +- `proof-of-concept` and `toolkit` policies are excluded from registry status tracking — `registry_status` may be omitted. + +--- + +## 8. Status and Registry Status Lifecycles + +### 8.1 `status` — Implementation lifecycle + +This tracks the state of the Guardian implementation itself. + +``` + ┌─────────────────────────────────────────────────────┐ + │ STATUS LIFECYCLE │ + └─────────────────────────────────────────────────────┘ + + [contributor opens PR] [review passes / testnet publish] + │ │ + ▼ ▼ + ┌─────────┐ ready for review ┌────────────┐ approved + mainnet-ready + │ draft │ ──────────────────► │ candidate │ ──────────────────────────► ┌────────┐ + └─────────┘ └────────────┘ │ active │ + └───┬────┘ + │ + ┌──────────────────────────────┤ + │ │ + known issues / newer version published + no longer maintained (supersedes: ) + │ │ + ▼ ▼ + ┌────────────┐ ┌───────────────┐ + │ deprecated │ │ superseded │ + └────────────┘ └───────────────┘ +``` + +State transition rules: +- Only `active` policies should have mainnet `publications` entries. +- `deprecated` means the policy still functions but is not recommended for new projects. +- `superseded` means a direct replacement exists. Set `superseded_by` to the replacement's `id`. +- `draft` and `candidate` are testnet-only states. + +### 8.2 `registry_status` — External registry validation + +This tracks whether the underlying methodology/project has been formally validated by an external registry body (e.g., Verra, Gold Standard). It is independent of `status`. + +``` + ┌──────────────────────────────────────────────────────────────────────┐ + │ REGISTRY_STATUS LIFECYCLE │ + └──────────────────────────────────────────────────────────────────────┘ + + [community/novel method] [submitted to registry] [registry approves] + │ │ │ + ▼ ▼ ▼ + ┌──────┐ application ┌─────────┐ validation ┌───────────┐ + │ none │ ───────────────► │ pending │ ─────────────► │ validated │ + └──────┘ └─────────┘ └─────┬─────┘ + │ + methodology withdrawn / + compliance failure + │ + ▼ + ┌─────────┐ + │ revoked │ + └─────────┘ +``` + +Notes: +- `registry_status` is most meaningful for `standard-implementation` and `novel-methodology` policy types. +- For `mrv-template`, `proof-of-concept`, and `toolkit` types, omit `registry_status` or set to `none`. +- `validated` implies `registry_body` should be populated. +- `revoked` does not necessarily mean the Guardian implementation is broken; it means the upstream registry has withdrawn validation. The Guardian `status` should be updated to `deprecated` or `superseded` accordingly. + +--- + +## 9. Tag Taxonomy Guidance + +Tags drive catalog filtering and search. The full taxonomy lives in [TAG_TAXONOMY.md](./TAG_TAXONOMY.md). Key principles: + +### Naming convention +All tags must be lowercase and hyphenated: `redd-plus`, `land-use`, `south-asia`. No uppercase, no underscores, no dots, no spaces. + +### Enforcement model +Tags are validated for _format_ by the JSON Schema (any malformed tag fails CI). Tags are validated for _content_ by a separate lint step that compares against TAG_TAXONOMY.md: +- **Unknown tags** → warning annotation in PR, does not block merge. +- **Malformed tags** → schema validation failure, blocks merge. + +### Required coverage +A complete manifest should include at least: +1. One **standard-body** tag (if `standard_body` is set). +2. One **thematic** tag describing the activity type. +3. One **geographic** tag if the policy is region-specific. +4. Optionally, one **programme/origin** tag for community or hackathon submissions. + +### Proposing canonical tags +Tags not yet in the taxonomy can be used freely. To canonicalize a tag, open a PR adding it to TAG_TAXONOMY.md with a description. Maintainers merge if the tag is useful across 3+ policies and not redundant. + +--- + +## 10. Versioning Convention + +### Two version fields + +``` +version semver of the Guardian implementation +methodology_version upstream version as published by the standard body +``` + +These fields track different things and must not be conflated. + +### `version` — Guardian implementation semver + +Follows standard [semver](https://semver.org/): + +| Increment | When | +|-----------|------| +| Patch `x.y.Z` | Bug fixes, documentation corrections, minor schema field additions that don't change validation logic | +| Minor `x.Y.0` | New roles, new optional fields, workflow additions that are backward-compatible with existing `.policy` imports | +| Major `X.0.0` | Breaking schema changes, workflow redesign, or implementation of a new major version of the upstream methodology | + +### `methodology_version` — upstream verbatim + +This is copied literally from the standard body's published document. It follows whatever versioning scheme the standards body uses (e.g., `7.0` for Verra VM0007 version 7.0, `2.0` for MECD v2.0). It is a string, not a semver. + +### Version and lineage example + +``` +gold-standard-mecd-v1 (version: "1.2.0", methodology_version: "1.2") + │ + │ supersedes: gold-standard-mecd-v1 + ▼ +gold-standard-mecd-v2 (version: "2.0.0", methodology_version: "2.0") +``` + +When releasing v2, set: +- New manifest: `version: "2.0.0"`, `supersedes: "gold-standard-mecd-v1"` +- Old manifest: `status: superseded`, `superseded_by: "gold-standard-mecd-v2"` + +--- + +## 11. Thumbnail Specification + +### Purpose + +Thumbnails are used by catalog UIs to give policies a visual identity at a glance — useful for grid/card layouts. + +### File conventions + +| Aspect | Requirement | +|--------|-------------| +| Location | `assets/` subdirectory adjacent to `policy.yml` | +| Path format | Relative: `assets/thumbnail.png` | +| Recommended dimensions | 400 × 300 px (4:3 ratio) | +| Accepted formats | PNG (preferred), JPEG | +| Maximum file size | 200 KB | +| Background | Transparent (PNG) or white/light neutral | +| Minimum dimensions | 200 × 150 px | + +### Fallback logic + +If `thumbnail` is omitted from the manifest, the catalog falls back in order: +1. `assets/thumbnail.png` (convention path — checked automatically). +2. `assets/thumbnail.jpg` (JPEG convention). +3. Generated icon based on `category` and `policy_type` (rendered server-side). + +Fallback (3) is always available, so thumbnails are never strictly required. + +### Recommendations + +- For standard implementations, use the standard body's logo or a representative diagram (check IP rights — most standards bodies permit non-commercial use with attribution). +- For community/novel policies, a simple icon representing the activity type (cookstoves, forest, supply chain) is effective. +- Do not include text in the thumbnail — it will not render well at small sizes. + +--- + +## 12. Publication Records + +### Design: two-file split + +Publication history is split across two files with different ownership and update cadences: + +| File | Owned by | Updated how | Contents | +|------|----------|-------------|----------| +| `policy.yml` (`ipfs_timestamp`) | Policy author | Manually | Single convenience timestamp — most recent mainnet (or testnet if not yet on mainnet) | +| `publications.json` | `record-publication` script | Automatically | Full append-only log of every network × version publication event | + +This separation exists because **the IPFS timestamp is generated by Guardian at publish time** — the contributor cannot know it before publishing. Asking contributors to manually maintain a structured YAML array inside `policy.yml` after every publish action is error-prone and will not be done consistently. The script removes the manual step entirely. + +### `ipfs_timestamp` in `policy.yml` + +A single string field. Update it by hand whenever a new mainnet version is published (copy-paste from the Guardian publish confirmation screen). For testnet-only policies, use the testnet timestamp. + +```yaml +# Most recent mainnet IPFS timestamp. Full history in publications.json. +ipfs_timestamp: "1707207286.119377003" +``` + +### `publications.json` — the append-only log + +Validated against `publications.schema.json`. Written exclusively by `scripts/record-publication.js`. Never edited by hand. + +**Structure:** + +```json +{ + "policy_id": "verra-vm0007-redd-plus", + "entries": [ + { + "network": "testnet", + "version": "1.1.0", + "ipfs_timestamp": "1707207018.434778003", + "published_by": "Envision Blockchain", + "recorded_at": "2024-02-06T10:00:00Z", + "notes": "Initial demonstration" + }, + { + "network": "mainnet", + "version": "3.0.0", + "ipfs_timestamp": "1707207286.119377003", + "hedera_topic_id": "0.0.5678901", + "published_by": "Envision Blockchain", + "recorded_at": "2024-02-06T14:00:00Z" + } + ] +} +``` + +**Recording a new publication:** + +```bash +node scripts/record-publication.js \ + --policy verra-vm0007-redd-plus \ + --network mainnet \ + --version 3.0.0 \ + --ipfs-timestamp 1707207286.119377003 \ + --topic-id 0.0.5678901 +``` + +The script appends one entry and commits the file. The contributor also updates `ipfs_timestamp` in `policy.yml` if this is a mainnet publication. + +### Testnet-only signal + +A policy whose `publications.json` contains no mainnet entry has never been published to production. Catalog tooling surfaces this as the absence of a "Live on mainnet" badge — the missing entry is itself an informative signal, not a gap. + +### ipfs_timestamp format + +Nanosecond-precision Unix epoch string as returned by Guardian's publish API. Stored as a quoted YAML/JSON string — not a number — to preserve decimal precision: `"1707207149.487956003"`, not `1707207149.487956003`. + +### File placement example + +``` +Verra/Verified Carbon Standard (VCS)/VM0007/ + policy.yml ← ipfs_timestamp: "1707207286.119377003" (author-maintained) + publications.json ← full 4-entry history across 3 versions (script-maintained) + readme.md + Policies/ + Verra VM0007 (3.0.0 - groups).policy +``` + +--- + +## 13. Success Metrics + +### Phase 1 — Schema and examples + +| Metric | Target | +|--------|--------| +| JSON Schema validates without errors | Pass on day 1 | +| 5 sample `policy.yml` files pass schema validation | Pass on day 1 | +| MANIFEST_SPEC.md accessible to contributor in < 10 min review | Qualitative — validated by contributor feedback | + +### Phase 2 — Backfill and tooling + +| Metric | Target | +|--------|--------| +| Percentage of library policies with a valid `policy.yml` | ≥ 80% within 90 days of Phase 2 launch | +| CI check running on all PRs that touch `policy.yml` | Pass/fail signal on 100% of relevant PRs | +| Mean time to fill out a manifest (new contributor) | ≤ 30 minutes (measured via contributor survey) | +| Schema validation error rate on submitted manifests | < 5% after first 30 days | + +### Phase 3 — Mini-site + +| Metric | Target | +|--------|--------| +| Catalog pages indexed by search engines | ≥ 90% of active policies within 60 days | +| Filter usage (category, sector, SDG, network) | ≥ 40% of catalog sessions use at least one filter | +| Time-to-find a specific policy (user test) | < 2 minutes for a non-expert user | + +### Phase 4 — Guardian integration + +| Metric | Target | +|--------|--------| +| Policies importable via manifest reference (vs file upload) | Available for all policies with a mainnet publication entry | +| Developer adoption of manifest-first import | ≥ 50% of new policy imports use manifest reference within 6 months | + +--- + +## 14. Phased Rollout + +### Phase 1 — Schema and examples + +**Scope**: Infrastructure only. No policy backfill required. + +Deliverables: +- `policy.schema.json` — JSON Schema draft 2020-12 at library root. +- `MANIFEST_SPEC.md` — contributor-facing field reference. +- `TAG_TAXONOMY.md` — tag naming guidance. +- `POLICY_MANIFEST_PRD.md` — this document. +- Five sample `policy.yml` files (VM0007, MECD v2.0, EUDR Pre-Check, DOVU MMCM, Living Income Price). + +Success criteria: All five sample files pass `ajv validate` against the schema. + +--- + +### Phase 2 — Backfill and tooling + +**Scope**: Systematically add `policy.yml` to all existing policies and add CI validation. + +Deliverables: +- GitHub Actions workflow: `.github/workflows/validate-manifests.yml` + - Triggers on PR touching any `policy.yml`. + - Runs schema validation; fails PR if invalid. + - Runs tag lint; annotates PR if unknown tags present. +- Backfill all existing policies via a dedicated initiative (issues created per policy folder). +- Contribute script: `tools/scaffold-manifest.js` — interactive CLI to generate a starter `policy.yml` from prompts. +- Documentation: update contributing guide to reference manifest requirement for new policies. + +Success criteria: ≥ 80% of existing policies have valid manifests; CI green on all new PRs. + +--- + +### Phase 3 — Mini-site + +**Scope**: Consumer-facing catalog UI driven by manifest data. + +Deliverables: +- Static site generator (e.g., Astro or Next.js static export) that: + - Traverses the library and indexes all valid `policy.yml` files. + - Renders a filterable card grid (filter by category, sector, SDG, token type, network, status). + - Renders individual policy detail pages with full manifest data and links to README. + - Embeds publications table with IPFS timestamps and Hedera topic links. +- Hosted at `https://methodologies.hedera.com` (or Guardian docs subdomain). +- Search (static — lunr.js or pagefind). + +Success criteria: Catalog publicly accessible; 3+ filters working; all active policies rendered. + +--- + +### Phase 4 — Guardian platform integration + +**Scope**: Surfacing manifest data inside the Guardian application itself. + +Deliverables: +- Guardian API endpoint: `GET /api/v1/policies/manifest/{id}` — returns parsed manifest JSON. +- Policy import dialog enhanced to accept: (a) file upload (existing), (b) IPFS timestamp (existing), (c) manifest `id` lookup against the catalog index (new). +- Guardian policy list view enhanced with category/sector/SDG badges sourced from manifest. +- Webhook / event: `manifest.updated` — emitted when a `policy.yml` changes in the library, enabling Guardian instances to refresh their local catalog cache. + +Success criteria: Policy import by manifest ID works end-to-end on testnet; Guardian UI surfaces category and SDG badges. + +--- + +## 15. Open Questions and Decisions Needed + +| # | Question | Options | Owner | Priority | +|---|----------|---------|-------|----------| +| 1 | **ID stability**: Can `id` ever be changed after first publish? | (a) Never — tombstone the old id. (b) Allowed with a deprecated alias. | Platform team | High | +| 2 | **Schema versioning**: How do we version the schema itself as fields are added? | (a) `$id` URI includes version; old schemas stay. (b) Single schema with optional additions. | Platform team | High | +| 3 | **Methodology version format**: Should `methodology_version` be validated by pattern or free string? | (a) Free string (current — simplest). (b) Pattern per standard body. | Platform team | Medium | +| 4 | **registry_status ownership**: Who is authorized to set `registry_status: validated`? | (a) Anyone (honor system). (b) Only maintainers (via CODEOWNERS). (c) Registry body sign-off via GPG. | Governance | High | +| 5 | **Thumbnail IP**: Do we need a formal IP policy for thumbnails using standards body logos? | (a) Require original artwork only. (b) Allow with attribution. | Legal | Medium | +| 6 | **Closed vs open tag set**: Should we eventually move to a closed tag enum in the schema? | (a) Keep open (warning-only). (b) Harden to error after Phase 2. | Platform team | Low | +| 7 | **ipfs_timestamp as string vs number**: YAML parsers can truncate float precision. Is quoting convention sufficient? | (a) String (current). (b) Add schema `type: string` with note. | Platform team | Medium | +| 8 | **Guardian version compatibility matrix**: Should `guardian_version_min` be checked programmatically? | (a) Documentation only. (b) CI reads Guardian release tags and warns. | Tooling team | Low | +| 9 | **Internationalization**: Should `description` and `name` support i18n keys or localized variants? | (a) English-only (current). (b) `description_i18n: {fr: "...", es: "..."}` optional fields. | Platform team | Low | +| 10 | **Manifest signing**: Should published manifests be cryptographically signed? | (a) No — trust the Git history. (b) Yes — GPG sign merged manifests. (c) Hedera DID signature in manifest. | Governance | Medium | From 1b31e7aa5b2ea92f936ed77b0850f362ae7ad0c5 Mon Sep 17 00:00:00 2001 From: Daniel Swid Date: Fri, 26 Jun 2026 14:14:36 -0700 Subject: [PATCH 2/2] feat(Policy Manifest): Address PR comments, improve organization * moved prd to rfc folder and updated community standards * added examples to policy manifest schema * renamed ipfs timestamp to hedera timestamp * updated category types to match those found in the library at present * add conditional note to other category and policy type enum Refs: Story: #6031 Reviewed-by: pyatakov Test-scope: n Signed-off-by: Daniel Swid Signed-off-by: Daniel Swid --- Methodology Library/MANIFEST_SPEC.md | 23 +++-- Methodology Library/policy.schema.json | 91 +++++++++++++++---- docs/SUMMARY.md | 2 + docs/guardian/community-standards/README.md | 10 ++ .../rfcs}/POLICY_MANIFEST_PRD.md | 61 +++++++------ .../community-standards/rfcs/README.md | 7 ++ 6 files changed, 142 insertions(+), 52 deletions(-) rename {rfcs => docs/guardian/community-standards/rfcs}/POLICY_MANIFEST_PRD.md (90%) create mode 100644 docs/guardian/community-standards/rfcs/README.md diff --git a/Methodology Library/MANIFEST_SPEC.md b/Methodology Library/MANIFEST_SPEC.md index c9f38ee66d..b929e2c053 100644 --- a/Methodology Library/MANIFEST_SPEC.md +++ b/Methodology Library/MANIFEST_SPEC.md @@ -1,7 +1,7 @@ # Guardian Policy Manifest Specification > **Audience**: policy contributors and methodology authors adding or updating a policy in the Guardian Methodology Library. -> **Full PRD**: see [POLICY_MANIFEST_PRD.md](./POLICY_MANIFEST_PRD.md). +> [See PRD for additional context](../docs/guardian/community-standards/rfcs/POLICY_MANIFEST_PRD.md). > **Schema**: [policy.schema.json](./policy.schema.json) --- @@ -20,7 +20,7 @@ description: > policy_type: standard-implementation # see policy_type guide below status: active # draft | candidate | active | deprecated | superseded license: Apache-2.0 # SPDX identifier -category: carbon-offsets # see category enum below +category: carbon-credits # see category enum below authors: - name: Your Organization tags: @@ -45,7 +45,7 @@ That is the complete minimum. Everything else is optional but strongly encourage | `policy_type` | enum | See [policy_type guide](#policy_type-guide). | `standard-implementation` | | `status` | enum | `draft` \| `candidate` \| `active` \| `deprecated` \| `superseded` | `active` | | `license` | string | SPDX license identifier. | `Apache-2.0` | -| `category` | enum | `carbon-offsets` \| `emission-reporting` \| `supply-chain` \| `biodiversity` \| `payments` \| `other` | `carbon-offsets` | +| `category` | enum | `carbon-credits` \| `emission-reporting` \| `renewable-energy` \| `supply-chain` \| `sustainable-agriculture` \| `water` \| `biodiversity` \| `waste` \| `other` | `carbon-credits` | | `authors` | array | One or more `{name, url?, type?, github?}` objects. | See below | | `tags` | array | Lowercase-hyphenated strings. See [TAG_TAXONOMY.md](./TAG_TAXONOMY.md). | `[verra, redd-plus, forest]` | @@ -53,6 +53,8 @@ That is the complete minimum. Everything else is optional but strongly encourage | Field | Type | Description | Example | |-------|------|-------------|---------| +| `category_note` | string | **Required when `category: other`.** Short label for the actual category — used to identify candidates for future enum promotion. | `parametric insurance` | +| `policy_type_note` | string | **Required when `policy_type: other`.** Short label for the actual policy type — used to identify candidates for future enum promotion. | `registry bridge` | | `standard_body` | string | Standards organization owning the upstream methodology. | `Verra` | | `methodology_id` | string | Upstream methodology identifier. | `VM0007` | | `methodology_version` | string | Upstream version verbatim. | `7.0` | @@ -62,7 +64,7 @@ That is the complete minimum. Everything else is optional but strongly encourage | `registry_body` | string | Registry that validated (when `registry_status: validated`). | `Verra` | | `registry_reference` | string | Formal registry reference number. | `VCS-1234` | | `registry_accepted_date` | string | ISO 8601 date of registry acceptance. | `2024-03-15` | -| `ipfs_timestamp` | string | IPFS timestamp of the most recent mainnet publication (testnet if not yet on mainnet). Full history lives in `publications.json`. | `"1707207286.119377003"` | +| `hedera_timestamp` | string | Hedera consensus timestamp of the most recent mainnet publication (testnet if not yet on mainnet). Full history lives in `publications.json`. | `"1707207286.119377003"` | | `sdg_alignment` | array | UN SDG numbers 1–17. | `[13, 15]` | | `sector` | string | `energy` \| `transport` \| `waste` \| `land-use` \| `industrial` \| `agriculture` \| `water` \| `other` | `land-use` | | `guardian_version_min` | string | Minimum Guardian platform version required. | `2.20.0` | @@ -71,7 +73,7 @@ That is the complete minimum. Everything else is optional but strongly encourage | `supersedes` | string \| null | ID of the policy this replaces. | `gold-standard-mecd-v1` | | `superseded_by` | string \| null | ID of policy that replaces this one. | | | `resources` | array | External links. See [resources array](#resources-array). | | -| `contributors` | array | `{name, github?}` contributors beyond primary authors. | | +| `contributors` | array | `{name, url?, type?, github?}` contributors beyond primary authors. | | | `maintainers` | array | `{name, email?, url?}` current maintainers. | | | `thumbnail` | string | Relative path to thumbnail image. See [thumbnails](#thumbnail-conventions). | `assets/thumbnail.png` | | `homepage` | string | Upstream methodology or project homepage URL. | | @@ -88,6 +90,7 @@ That is the complete minimum. Everything else is optional but strongly encourage | `mrv-template` | A reusable skeleton or scaffolding policy for a class of MRV projects. Not a complete policy on its own — intended to be forked and parameterized. | DOVU MMCM, generic dMRV templates | | `proof-of-concept` | An exploratory or demonstration policy, not intended for production use. Typically found in Hackathon/ or Work In Progress/. | Hackathon submissions | | `toolkit` | A set of schemas, modules, or utilities that support policy development but do not constitute a stand-alone policy workflow. | Modules/, reusable schema packs | +| `other` | Does not fit any of the above. `policy_type_note` is required — describe the actual type in plain English. | | --- @@ -156,16 +159,16 @@ Publication history is split across two files with different ownership: | File | Who writes it | How | |---|---|---| -| `policy.yml` (`ipfs_timestamp`) | Policy author | Manually — paste the most recent mainnet timestamp (or testnet if not yet on mainnet) | +| `policy.yml` (`hedera_timestamp`) | Policy author | Manually — paste the most recent mainnet timestamp (or testnet if not yet on mainnet) | | `publications.json` | The `record-publication` script | Automatically — run once after each Guardian publish action | -### `ipfs_timestamp` in `policy.yml` +### `hedera_timestamp` in `policy.yml` A single convenience field for the most recent mainnet publication — used by Guardian's one-click import. Update it whenever a new mainnet version is published. ```yaml -# Most recent mainnet IPFS timestamp. Full history in publications.json. -ipfs_timestamp: "1707207286.119377003" +# Most recent Hedera consensus timestamp. Full history in publications.json. +hedera_timestamp: "1707207286.119377003" ``` For testnet-only policies, use the testnet timestamp. The absence of a mainnet entry in `publications.json` is itself a visible signal in the catalog (no "Live on mainnet" badge). @@ -179,7 +182,7 @@ node scripts/record-publication.js \ --policy verra-vm0007-redd-plus \ --network mainnet \ --version 3.0.0 \ - --ipfs-timestamp 1707207286.119377003 \ + --hedera-timestamp 1707207286.119377003 \ --topic-id 0.0.5678901 ``` diff --git a/Methodology Library/policy.schema.json b/Methodology Library/policy.schema.json index 4b1176aa9f..82a06dd393 100644 --- a/Methodology Library/policy.schema.json +++ b/Methodology Library/policy.schema.json @@ -59,10 +59,18 @@ "novel-methodology", "mrv-template", "proof-of-concept", - "toolkit" + "toolkit", + "other" ] }, + "policy_type_note": { + "type": "string", + "description": "Required when policy_type is 'other'. A short plain-English label for the actual policy type. Used to identify candidates for future enum promotion.", + "minLength": 1, + "examples": ["registry bridge", "compliance reporting tool", "data oracle"] + }, + "status": { "type": "string", "description": "Lifecycle state of this Guardian implementation.", @@ -86,15 +94,25 @@ "type": "string", "description": "Broad domain this policy belongs to.", "enum": [ - "carbon-offsets", + "carbon-credits", "emission-reporting", + "renewable-energy", "supply-chain", + "sustainable-agriculture", + "water", "biodiversity", - "payments", + "waste", "other" ] }, + "category_note": { + "type": "string", + "description": "Required when category is 'other'. A short plain-English label for the actual category. Used to identify candidates for future enum promotion.", + "minLength": 1, + "examples": ["parametric insurance", "product passport", "water rights trading"] + }, + "authors": { "type": "array", "description": "Organizations or individuals primarily responsible for this Guardian implementation.", @@ -125,7 +143,8 @@ "pattern": "^[a-zA-Z0-9]([a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$" } } - } + }, + "examples": [[{"name": "Knowhere", "type": "organization", "url": "https://guardian.hedera.com/knowhere"}]] }, "tags": { @@ -137,7 +156,8 @@ "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", "description": "A single lowercase-hyphenated tag." - } + }, + "examples": [["verra", "redd-plus", "forest"]] }, "standard_body": { @@ -204,9 +224,9 @@ "examples": ["2024-03-15"] }, - "ipfs_timestamp": { + "hedera_timestamp": { "type": "string", - "description": "IPFS timestamp of the most recent mainnet publication (or testnet if not yet on mainnet), as returned by Guardian's publish API. Full publication history — all networks and versions — is recorded in publications.json by the record-publication script; never edit that file by hand.", + "description": "Hedera consensus timestamp of the most recent mainnet publication (or testnet if not yet on mainnet), as returned by Guardian's publish API. This is the timestamp of the Hedera message that carries the IPFS CID. Full publication history — all networks and versions — is recorded in publications.json by the record-publication script; never edit that file by hand.", "pattern": "^[0-9]+\\.[0-9]+$", "examples": ["1707207286.119377003"] }, @@ -214,6 +234,7 @@ "sdg_alignment": { "type": "array", "description": "UN Sustainable Development Goal numbers (1-17) that this policy directly supports.", + "minItems": 1, "uniqueItems": true, "items": { "type": "integer", @@ -248,6 +269,7 @@ "roles": { "type": "array", "description": "Named roles defined in the policy workflow.", + "uniqueItems": true, "items": { "type": "string", "minLength": 1 @@ -273,20 +295,22 @@ "description": "Minimum version of the dependency required." } } - } + }, + "examples": [[{"id": "guardian-schema-pack", "version_min": "1.0.0"}]] }, "supersedes": { - "type": ["string", "null"], - "description": "ID of the policy this manifest replaces. Null or omit if this is the first version.", + "type": "string", + "description": "ID of the policy this manifest replaces. Omit if this is the first version.", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", "examples": ["gold-standard-mecd-v1"] }, "superseded_by": { - "type": ["string", "null"], + "type": "string", "description": "ID of the policy that replaces this one (set when status becomes superseded).", - "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "examples": ["gold-standard-mecd-v2"] }, "resources": { @@ -322,7 +346,8 @@ "description": "URL to the resource (optional if the resource is described by label alone)." } } - } + }, + "examples": [[{"type": "methodology", "label": "Verra VM0007 REDD+ Methodology Framework", "url": "https://verra.org/methodologies/vm0007-redd-methodology-framework-redd-mf/"}]] }, "contributors": { @@ -337,12 +362,23 @@ "type": "string", "minLength": 1 }, + "url": { + "type": "string", + "format": "uri", + "description": "Contributor's website or profile URL." + }, + "type": { + "type": "string", + "description": "Contributor classification.", + "enum": ["organization", "individual", "community"] + }, "github": { "type": "string", "pattern": "^[a-zA-Z0-9]([a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$" } } - } + }, + "examples": [[{"name": "Rocket Raccoon", "type": "individual", "github": "rocket-raccoon"}]] }, "maintainers": { @@ -366,12 +402,14 @@ "format": "uri" } } - } + }, + "examples": [[{"name": "Groot", "email": "groot@hashgraph.com", "url": "https://guardian.hedera.com/knowhere"}]] }, "thumbnail": { "type": "string", "description": "Relative path to a thumbnail image (from the policy.yml file location). Recommended: 400x300 PNG/JPEG.", + "pattern": "^(?!/).*\\.(png|jpg|jpeg)$", "examples": ["assets/thumbnail.png", "thumbnail.jpg"] }, @@ -386,5 +424,26 @@ "description": "URL (GitHub issues, forum) or email address for policy support.", "examples": ["https://github.com/hashgraph/guardian/issues", "support@example.com"] } - } + }, + + "allOf": [ + { + "if": { + "properties": { "category": { "const": "other" } }, + "required": ["category"] + }, + "then": { + "required": ["category_note"] + } + }, + { + "if": { + "properties": { "policy_type": { "const": "other" } }, + "required": ["policy_type"] + }, + "then": { + "required": ["policy_type_note"] + } + } + ] } diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 6164863142..5261e7bdfc 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -1052,6 +1052,8 @@ * [Task Template](guardian/community-standards/documentation-standards/page-templates/task-template.md) * [Reference Template](guardian/community-standards/documentation-standards/page-templates/reference-template.md) * [Guide Template](guardian/community-standards/documentation-standards/page-templates/guide-template.md) + * [RFCs](guardian/community-standards/rfcs/README.md) + * [Policy Manifest (policy.yml)](guardian/community-standards/rfcs/POLICY_MANIFEST_PRD.md) ## Methodology Digitization diff --git a/docs/guardian/community-standards/README.md b/docs/guardian/community-standards/README.md index 0665c68ee3..80763b4bc7 100644 --- a/docs/guardian/community-standards/README.md +++ b/docs/guardian/community-standards/README.md @@ -1,2 +1,12 @@ # Community Standards +Community Standards define the shared agreements that keep the Guardian ecosystem consistent, trustworthy, and legible to contributors at every level — from new policy authors to platform engineers. + +They exist because an open-source project grows fastest when contributors can orient themselves quickly. A well-defined policy standard, a predictable documentation structure, and a visible record of platform decisions reduce the cost of contribution and raise the quality floor across the board. + +### What's here + +* **Guardian Policy Standards (GPS)** — requirements for policies to be accepted into the Methodology Library, covering science-based claims, verifiability, and documentation completeness. +* **Guardian System Standards (GSS)** — engineering standards for Guardian platform components. +* **Documentation Standards** — how to write and structure pages in this documentation site, including page type definitions and templates. +* **RFCs** — design documents capturing ideas and decisions made during platform development, kept here for record keeping. diff --git a/rfcs/POLICY_MANIFEST_PRD.md b/docs/guardian/community-standards/rfcs/POLICY_MANIFEST_PRD.md similarity index 90% rename from rfcs/POLICY_MANIFEST_PRD.md rename to docs/guardian/community-standards/rfcs/POLICY_MANIFEST_PRD.md index 1860cec2ab..0c718cc39d 100644 --- a/rfcs/POLICY_MANIFEST_PRD.md +++ b/docs/guardian/community-standards/rfcs/POLICY_MANIFEST_PRD.md @@ -1,12 +1,18 @@ +--- +description: PRD for the policy.yml sidecar manifest — structured, machine-readable metadata for every policy in the Guardian Methodology Library. +tags: + - rfc +--- + # Product Requirements Document: Guardian Policy Manifest (`policy.yml`) | Field | Value | |-------|-------| | **Status** | Draft — for stakeholder review | -| **Author** | Guardian Platform Team | +| **Author** | Guardian Platform Team, Hashgraph | | **Date** | 2026-06-11 | | **Version** | 0.1 | -| **Related docs** | [MANIFEST_SPEC.md](./MANIFEST_SPEC.md), [policy.schema.json](./policy.schema.json), [TAG_TAXONOMY.md](./TAG_TAXONOMY.md) | +| **Related docs** | MANIFEST_SPEC.md, policy.schema.json, TAG_TAXONOMY.md — see Methodology Library/ at repo root | --- @@ -222,7 +228,7 @@ Methodology Library/ | `policy_type` | enum | See Section 7 | Classification relative to upstream standards. | `standard-implementation` | | `status` | enum | `draft\|candidate\|active\|deprecated\|superseded` | Implementation lifecycle state. | `active` | | `license` | string | SPDX identifier | Open source license. | `Apache-2.0` | -| `category` | enum | `carbon-offsets\|emission-reporting\|supply-chain\|biodiversity\|payments\|other` | Primary domain. | `carbon-offsets` | +| `category` | enum | `carbon-credits\|emission-reporting\|renewable-energy\|supply-chain\|sustainable-agriculture\|water\|biodiversity\|waste\|other` | Primary domain. | `carbon-credits` | | `authors` | array | See 6.3 | Primary authors/organizations. | `[{name: Envision Blockchain}]` | | `tags` | array | `^[a-z0-9]+(?:-[a-z0-9]+)*$` each | Discovery tags. | `[verra, redd-plus, forest]` | @@ -230,6 +236,8 @@ Methodology Library/ | Field | Type | Pattern / Enum | Description | Example | |-------|------|---------------|-------------|---------| +| `category_note` | string | — | Required when `category` is `other`. Short label describing the actual category — used to identify candidates for future enum promotion. | `parametric insurance` | +| `policy_type_note` | string | — | Required when `policy_type` is `other`. Short label describing the actual policy type — used to identify candidates for future enum promotion. | `registry bridge` | | `standard_body` | string | — | Standards organization owning the upstream methodology. | `Verra` | | `methodology_id` | string | — | Upstream methodology identifier. | `VM0007` | | `methodology_version` | string | — | Upstream version verbatim as published. | `7.0` | @@ -239,14 +247,14 @@ Methodology Library/ | `registry_body` | string | — | Registry that validated. | `Verra` | | `registry_reference` | string | — | Formal registry reference number. | `VCS-1234` | | `registry_accepted_date` | string | ISO 8601 date | Date of registry acceptance. | `2024-03-15` | -| `ipfs_timestamp` | string | `^[0-9]+\.[0-9]+$` | Most recent mainnet IPFS timestamp (testnet if not yet on mainnet). Full history in `publications.json`. | `"1707207286.119377003"` | +| `hedera_timestamp` | string | `^[0-9]+\.[0-9]+$` | Hedera consensus timestamp of the most recent mainnet publication (testnet if not yet on mainnet). Full history in `publications.json`. | `"1707207286.119377003"` | | `sdg_alignment` | array | integers 1–17 | UN SDG numbers supported. | `[13, 15]` | | `sector` | enum | `energy\|transport\|waste\|land-use\|industrial\|agriculture\|water\|other` | Primary economic sector. | `land-use` | | `guardian_version_min` | string | semver | Minimum Guardian platform version. | `2.20.0` | | `roles` | array | strings | Named workflow roles. | `["Standard Registry", "VVB"]` | | `dependencies` | array | See 6.5 | Required Guardian modules. | | -| `supersedes` | string\|null | kebab-case | ID of policy this replaces. | `gold-standard-mecd-v1` | -| `superseded_by` | string\|null | kebab-case | ID of policy that replaces this. | | +| `supersedes` | string | kebab-case | ID of policy this replaces. Omit if this is the first version. | `gold-standard-mecd-v1` | +| `superseded_by` | string | kebab-case | ID of policy that replaces this. Omit until superseded. | `gold-standard-mecd-v2` | | `resources` | array | See 6.6 | External reference links. | | | `contributors` | array | See 6.7 | Non-author contributors. | | | `maintainers` | array | See 6.8 | Current maintainers. | | @@ -269,9 +277,9 @@ maintainers: url: string optional website URL ``` -### 6.4 ipfs_timestamp +### 6.4 hedera_timestamp -A nanosecond-precision Unix epoch string returned by Guardian's publish API. Stored as a quoted string to preserve decimal precision. Points to the most recent mainnet publication; use the testnet timestamp if the policy has not yet reached mainnet. Full multi-network history is in `publications.json` — see Section 12. +A nanosecond-precision Hedera consensus timestamp returned by Guardian's publish API. Stored as a quoted string to preserve decimal precision. This is the timestamp of the Hedera message that carries the IPFS CID. Points to the most recent mainnet publication; use the testnet timestamp if the policy has not yet reached mainnet. Full multi-network history is in `publications.json` — see Section 12. ### 6.5 dependencies array items @@ -309,6 +317,7 @@ The `policy_type` field classifies the policy's fundamental relationship to upst | `mrv-template` | A reusable template or scaffolding for a class of MRV projects. Not a complete policy on its own — designed to be forked, parameterized, and specialized by downstream implementors. | None strictly required; `methodology_id` may be present | DOVU generic dMRV template, MMCM | | `proof-of-concept` | Exploratory or demonstration policy. Typically created during hackathons or bounty programs. Not intended for production use. | None | Hackathon submissions, Work In Progress entries | | `toolkit` | A collection of schemas, modules, or Guardian configuration utilities that support policy development but are not stand-alone policy workflows. | None | Modules/ entries, reusable schema packs | +| `other` | Does not fit any of the above types. `policy_type_note` is required — describe the actual type in plain English. | `policy_type_note` required | | ### Disambiguation notes @@ -389,7 +398,7 @@ Notes: ## 9. Tag Taxonomy Guidance -Tags drive catalog filtering and search. The full taxonomy lives in [TAG_TAXONOMY.md](./TAG_TAXONOMY.md). Key principles: +Tags drive catalog filtering and search. The full taxonomy lives in TAG_TAXONOMY.md. Key principles: ### Naming convention All tags must be lowercase and hyphenated: `redd-plus`, `land-use`, `south-asia`. No uppercase, no underscores, no dots, no spaces. @@ -495,18 +504,18 @@ Publication history is split across two files with different ownership and updat | File | Owned by | Updated how | Contents | |------|----------|-------------|----------| -| `policy.yml` (`ipfs_timestamp`) | Policy author | Manually | Single convenience timestamp — most recent mainnet (or testnet if not yet on mainnet) | +| `policy.yml` (`hedera_timestamp`) | Policy author | Manually | Single convenience timestamp — most recent mainnet (or testnet if not yet on mainnet) | | `publications.json` | `record-publication` script | Automatically | Full append-only log of every network × version publication event | -This separation exists because **the IPFS timestamp is generated by Guardian at publish time** — the contributor cannot know it before publishing. Asking contributors to manually maintain a structured YAML array inside `policy.yml` after every publish action is error-prone and will not be done consistently. The script removes the manual step entirely. +This separation exists because **the Hedera timestamp is generated by Guardian at publish time** — the contributor cannot know it before publishing. Asking contributors to manually maintain a structured YAML array inside `policy.yml` after every publish action is error-prone and will not be done consistently. The script removes the manual step entirely. -### `ipfs_timestamp` in `policy.yml` +### `hedera_timestamp` in `policy.yml` A single string field. Update it by hand whenever a new mainnet version is published (copy-paste from the Guardian publish confirmation screen). For testnet-only policies, use the testnet timestamp. ```yaml -# Most recent mainnet IPFS timestamp. Full history in publications.json. -ipfs_timestamp: "1707207286.119377003" +# Most recent Hedera consensus timestamp. Full history in publications.json. +hedera_timestamp: "1707207286.119377003" ``` ### `publications.json` — the append-only log @@ -522,17 +531,17 @@ Validated against `publications.schema.json`. Written exclusively by `scripts/re { "network": "testnet", "version": "1.1.0", - "ipfs_timestamp": "1707207018.434778003", - "published_by": "Envision Blockchain", + "hedera_timestamp": "1707207018.434778003", + "published_by": "Knowhere", "recorded_at": "2024-02-06T10:00:00Z", "notes": "Initial demonstration" }, { "network": "mainnet", "version": "3.0.0", - "ipfs_timestamp": "1707207286.119377003", + "hedera_timestamp": "1707207286.119377003", "hedera_topic_id": "0.0.5678901", - "published_by": "Envision Blockchain", + "published_by": "Knowhere", "recorded_at": "2024-02-06T14:00:00Z" } ] @@ -546,26 +555,26 @@ node scripts/record-publication.js \ --policy verra-vm0007-redd-plus \ --network mainnet \ --version 3.0.0 \ - --ipfs-timestamp 1707207286.119377003 \ + --hedera-timestamp 1707207286.119377003 \ --topic-id 0.0.5678901 ``` -The script appends one entry and commits the file. The contributor also updates `ipfs_timestamp` in `policy.yml` if this is a mainnet publication. +The script appends one entry and commits the file. The contributor also updates `hedera_timestamp` in `policy.yml` if this is a mainnet publication. ### Testnet-only signal A policy whose `publications.json` contains no mainnet entry has never been published to production. Catalog tooling surfaces this as the absence of a "Live on mainnet" badge — the missing entry is itself an informative signal, not a gap. -### ipfs_timestamp format +### hedera_timestamp format -Nanosecond-precision Unix epoch string as returned by Guardian's publish API. Stored as a quoted YAML/JSON string — not a number — to preserve decimal precision: `"1707207149.487956003"`, not `1707207149.487956003`. +Nanosecond-precision Hedera consensus timestamp as returned by Guardian's publish API. Stored as a quoted YAML/JSON string — not a number — to preserve decimal precision: `"1707207149.487956003"`, not `1707207149.487956003`. ### File placement example ``` Verra/Verified Carbon Standard (VCS)/VM0007/ - policy.yml ← ipfs_timestamp: "1707207286.119377003" (author-maintained) - publications.json ← full 4-entry history across 3 versions (script-maintained) + policy.yml ← hedera_timestamp: "1707207286.119377003" (author-maintained) + publications.json ← full 4-entry history across 3 versions (script-maintained) readme.md Policies/ Verra VM0007 (3.0.0 - groups).policy @@ -653,7 +662,7 @@ Deliverables: - Renders a filterable card grid (filter by category, sector, SDG, token type, network, status). - Renders individual policy detail pages with full manifest data and links to README. - Embeds publications table with IPFS timestamps and Hedera topic links. -- Hosted at `https://methodologies.hedera.com` (or Guardian docs subdomain). +- Hosted at a Guardian docs subdomain (TBD). - Search (static — lunr.js or pagefind). Success criteria: Catalog publicly accessible; 3+ filters working; all active policies rendered. @@ -684,7 +693,7 @@ Success criteria: Policy import by manifest ID works end-to-end on testnet; Guar | 4 | **registry_status ownership**: Who is authorized to set `registry_status: validated`? | (a) Anyone (honor system). (b) Only maintainers (via CODEOWNERS). (c) Registry body sign-off via GPG. | Governance | High | | 5 | **Thumbnail IP**: Do we need a formal IP policy for thumbnails using standards body logos? | (a) Require original artwork only. (b) Allow with attribution. | Legal | Medium | | 6 | **Closed vs open tag set**: Should we eventually move to a closed tag enum in the schema? | (a) Keep open (warning-only). (b) Harden to error after Phase 2. | Platform team | Low | -| 7 | **ipfs_timestamp as string vs number**: YAML parsers can truncate float precision. Is quoting convention sufficient? | (a) String (current). (b) Add schema `type: string` with note. | Platform team | Medium | +| 7 | **hedera_timestamp as string vs number**: YAML parsers can truncate float precision. Is quoting convention sufficient? | (a) String (current). (b) Add schema `type: string` with note. | Platform team | Medium | | 8 | **Guardian version compatibility matrix**: Should `guardian_version_min` be checked programmatically? | (a) Documentation only. (b) CI reads Guardian release tags and warns. | Tooling team | Low | | 9 | **Internationalization**: Should `description` and `name` support i18n keys or localized variants? | (a) English-only (current). (b) `description_i18n: {fr: "...", es: "..."}` optional fields. | Platform team | Low | | 10 | **Manifest signing**: Should published manifests be cryptographically signed? | (a) No — trust the Git history. (b) Yes — GPG sign merged manifests. (c) Hedera DID signature in manifest. | Governance | Medium | diff --git a/docs/guardian/community-standards/rfcs/README.md b/docs/guardian/community-standards/rfcs/README.md new file mode 100644 index 0000000000..4b437f7de1 --- /dev/null +++ b/docs/guardian/community-standards/rfcs/README.md @@ -0,0 +1,7 @@ +--- +description: Design documents for the Guardian platform, kept here for record keeping. +--- + +# RFCs + +This folder contains product and design documents that capture ideas and context for decisions made during Guardian platform development. They are kept here as a record of intent and reasoning behind significant features.