diff --git a/README.md b/README.md index 945e9db..31c635c 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ This repository contains the design specifications and implementation plans for - [m010 — Reputation Signal (v0 advisory)](mechanisms/m010-reputation-signal/) +- [m014 — Authority Validator Governance (PoA Transition)](mechanisms/m014-authority-validator-governance/) diff --git a/docs/MECHANISM_CONSUMERS.md b/docs/MECHANISM_CONSUMERS.md index abd7745..b6b73a4 100644 --- a/docs/MECHANISM_CONSUMERS.md +++ b/docs/MECHANISM_CONSUMERS.md @@ -18,3 +18,21 @@ This document maps **mechanism IDs** to known **consumers** (agents, digests, sc - Heartbeat replay runner: `scripts/replay-m010.mjs` (regen-heartbeat) - Heartbeat stub runner: `scripts/stub-run-signal-agent.mjs` (regen-heartbeat) - Heartbeat validator: `scripts/validate-signal-agent.mjs` (regen-heartbeat) + +## m014 — Authority Validator Governance +**Canonical spec** +- `mechanisms/m014-authority-validator-governance/SPEC.md` + +**Outputs** +- KPI JSON block schema: `mechanisms/m014-authority-validator-governance/schemas/m014_kpi.schema.json` +- Validator item schema: `mechanisms/m014-authority-validator-governance/schemas/m014_validator.schema.json` +- Performance score schema: `mechanisms/m014-authority-validator-governance/schemas/m014_performance.schema.json` + +**Datasets (deterministic)** +- Replay fixtures: `mechanisms/m014-authority-validator-governance/datasets/fixtures/v0_sample.json` +- Transition fixtures: `mechanisms/m014-authority-validator-governance/datasets/fixtures/v0_transition_sample.json` + +**Known consumers** +- AGENT-004: Validator Monitor (performance tracking, probation recommendations) +- Heartbeat character: `validator-monitor-agent` (regen-heartbeat, planned) +- M013 integration: validator fund balance feeds compensation computation diff --git a/mechanisms/m014-authority-validator-governance/README.md b/mechanisms/m014-authority-validator-governance/README.md new file mode 100644 index 0000000..91c1187 --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/README.md @@ -0,0 +1,31 @@ +# m014 — Authority Validator Governance (PoA Transition) + +m014 specifies the transition from Proof of Stake (capital-weighted security) to Proof of Authority (contribution-weighted governance), replacing passive staking rewards with fee-based compensation and mission-aligned validator selection. + +## What it outputs +- A composite **performance score** (0.0–1.0) per validator, based on uptime (0.4), governance participation (0.3), and ecosystem contribution (0.3). +- Validator lifecycle state tracking: CANDIDATE, APPROVED, ACTIVE, PROBATION, REMOVED, TERM_EXPIRED. +- KPI metrics: validator counts by status/category, average performance, compensation statistics. +- Compensation allocation: equal-share base from validator fund (M013) plus optional 10% performance bonus pool. + +## What it does not do (v0) +- No on-chain authority module deployment (specification only). +- No automatic validator removal — governance process required. +- Ecosystem contribution scoring relies on AGENT-004 advisory assessment. + +## How to reference +- Canonical spec: `mechanisms/m014-authority-validator-governance/SPEC.md` +- Validator lifecycle: SPEC.md section 6 (state machine, composition requirements) +- Performance scoring: SPEC.md section 5 (weighted factors, confidence, thresholds) +- Dependencies: M013 (validator fund), M012 (inflation disabled) + +## Replay datasets +See `datasets/` for deterministic fixtures used to generate non-zero KPI outputs without MCP. +- `v0_sample.json` — 5 validators across 3 categories with varied performance profiles +- `v0_transition_sample.json` — PoS-to-PoA transition scenarios with lifecycle state changes + +## Schemas +Canonical JSON schemas for m014 outputs live in `schemas/`. +- `m014_validator.schema.json` — validator lifecycle (address, category, status, term, performance) +- `m014_performance.schema.json` — performance score output (score, factors) +- `m014_kpi.schema.json` — KPI output with mechanism_id const "m014" diff --git a/mechanisms/m014-authority-validator-governance/SPEC.md b/mechanisms/m014-authority-validator-governance/SPEC.md new file mode 100644 index 0000000..2b57006 --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/SPEC.md @@ -0,0 +1,221 @@ +# m014 — Authority Validator Governance (SPEC) + +## 0. Header +- **ID:** m014 +- **Name:** Authority Validator Governance +- **Status:** draft (v0) +- **Owner:** (unset) +- **Last updated:** 2026-02-18 +- **Scope:** **v0** (mechanism specification for PoS-to-PoA transition with curated, compensated validator set) + +## 1. Problem +Regen Network's current Proof of Stake model creates three structural mismatches: +1. **Security vulnerability**: Cost to disrupt drops when token price drops. +2. **Misaligned incentives**: Passive holders receive equivalent rewards as active contributors. +3. **Value disconnection**: Security is funded by inflation that dilutes all holders. + +The validator set is currently unstable — sometimes dropping below 21 active validators — and all validators are operating at a loss. They participate for mission alignment, not profit. PoA replaces this with a curated, compensated validator set whose authority derives from demonstrated contribution to the network's ecological mission. + +## 2. Target actor and action +- **Actors:** Authority Validators (approved network operators), Validator Governance (body managing validator set at Layer 3), Token Holders ($REGEN holders voting on constitutional changes at Layer 4), Agent (AGENT-004 Validator Monitor). +- **Action being evaluated:** validator performance across uptime, governance participation, and ecosystem contribution, determining compensation and continued membership in the authority set. +- **Event source:** validator lifecycle transitions (application, approval, activation, probation, removal, term expiration) and periodic performance evaluations by AGENT-004. + +## 3. Signal definition +- **Signal name:** Validator Performance Score +- **Unit:** score (0.0 – 1.0) +- **Directionality:** higher = better +- **Granularity:** per validator address +- **Factors:** + - `uptime`: weight 0.4 — blocks signed / blocks expected + - `governance_participation`: weight 0.3 — votes cast / proposals available + - `ecosystem_contribution`: weight 0.3 — measured by AGENT-004 (code contributions, dMRV tool development, credit class participation, etc.) + +## 4. Evidence inputs + +| Input | Source | Fields | Validity rules | Anti-spoof assumptions | Refresh cadence | +|---|---|---|---|---|---| +| Block signing data | Regen Ledger validator set | `blocks_signed`, `blocks_expected` | blocks_expected > 0 | Chain consensus is authoritative | Per epoch / daily | +| Governance votes | Regen governance module | `votes_cast`, `proposals_available` | proposals_available >= votes_cast | On-chain vote records are tamper-proof | Per proposal / weekly | +| Ecosystem contribution | AGENT-004 evaluation | `contribution_score` (0.0–1.0) | Must be assessed within current term | AGENT-004 operates with oversight (Layer 2) | Monthly / quarterly | +| Validator application | Validator governance process | `address`, `category`, `application_data` | Category must be valid; application must be complete | Governance process verifies identity | On application | +| Term metadata | Authority module | `term_start`, `term_end`, `status` | term_end > term_start; status in valid set | Module state is authoritative | On state change | + +## 5. Scoring function + +### 5.1 Composite performance score +A weighted sum of three performance factors: + +``` +performance_score = (uptime * 0.4) + (governance_participation * 0.3) + (ecosystem_contribution * 0.3) +``` + +Where: +- `uptime` = blocks_signed / blocks_expected (0.0–1.0) +- `governance_participation` = votes_cast / proposals_available (0.0–1.0; defaults to 1.0 if no proposals) +- `ecosystem_contribution` = AGENT-004 assessed score (0.0–1.0) + +### 5.2 Confidence +Confidence is derived from data availability: +- All three factors available with sufficient data: confidence = 1.0 +- One factor missing or estimated: confidence = 0.67 +- Two factors missing: confidence = 0.33 +- No data: confidence = 0.0 + +### 5.3 Performance threshold +- Validators with `performance_score < 0.70` are flagged for review. +- Validators with `uptime < 0.995` (99.5%) are flagged for probation consideration. + +### 5.4 Compensation allocation +``` +base_compensation_per_validator = (validator_fund_balance * 0.90) / active_validator_count +performance_bonus_per_validator = (validator_fund_balance * 0.10) * (validator_score / total_scores) +total_compensation = base_compensation + performance_bonus +``` + +Where: +- `validator_fund_balance` is sourced from M013 fee routing. +- `0.90` = base pool (90% of fund). +- `0.10` = performance bonus pool (10% of fund). +- `total_scores` = sum of all active validators' composite performance scores. + +## 6. Validator lifecycle + +### 6.1 State machine +``` +States: {CANDIDATE, APPROVED, ACTIVE, PROBATION, REMOVED, TERM_EXPIRED} + +CANDIDATE -> APPROVED + trigger: validator_governance.approve(candidate_application) + guard: meets_composition_criteria, slot_available, no_active_conflicts + action: add to approved set, schedule activation + +APPROVED -> ACTIVE + trigger: node_operational AND bonded_minimum_stake + guard: infrastructure_verified (uptime test, key management audit) + action: add to active validator set, begin block production + +ACTIVE -> PROBATION + trigger: performance_below_threshold OR governance_concern_raised + guard: AGENT-004 performance report OR governance motion + action: issue warning, set probation_period(30 days), reduce compensation + +PROBATION -> ACTIVE + trigger: performance_restored AND probation_period_elapsed + guard: AGENT-004 confirms restoration + action: restore full compensation + +PROBATION -> REMOVED + trigger: probation_period_elapsed AND performance_not_restored + guard: validator_governance.confirm_removal() + action: remove from active set, unbond stake, archive performance record + +ACTIVE -> TERM_EXPIRED + trigger: term_end_date_reached + guard: none + action: initiate re-application or graceful exit + +TERM_EXPIRED -> CANDIDATE + trigger: validator.reapply() + action: enter re-evaluation process (streamlined for incumbents with good records) + +Terminal states: REMOVED (no further transitions without new application) +``` + +### 6.2 Validator composition +```yaml +authority_set: + target_size: 15-21 validators + composition: + infrastructure_builders: + minimum: 5 + criteria: + - active development of verification systems, dMRV tools, or registry infrastructure + - demonstrable code contributions to regen-ledger or ecosystem repos + - operational history >= 6 months + examples: "RND engineering team, KOI developers, dMRV tool builders" + + trusted_refi_partners: + minimum: 5 + criteria: + - established ReFi organization with public mission alignment + - active participation in Regen ecosystem (credit origination, marketplace activity, or governance) + - operational infrastructure meeting minimum uptime requirements (99.5%) + examples: "ReFiDAO, Toucan, Kolektivo, regional partners" + + ecological_data_stewards: + minimum: 5 + criteria: + - organizations attesting to ecological data quality + - active participation in credit class development or verification + - domain expertise in ecology, land management, or environmental science + examples: "Verification bodies, research institutions, land steward cooperatives" +``` + +## 7. Economic linkage +- **Source:** Validator fund from M013 (value-based fee routing). No inflationary fallback. +- **Model:** Fixed base + optional performance bonus. + - Base: equal_share — `validator_fund_balance / active_validator_count / period`. All active validators receive equal base compensation. + - Bonus: 10% of total validator fund, distributed proportional to composite performance score. +- **Term structure:** 12-month terms with quarterly compensation review. Early exit allowed with 30-day notice; forfeits current quarter bonus. +- **Compensation cap:** Total validator compensation must not exceed `validator_fund_balance`. No inflationary fallback. +- **Dependencies:** M013 (validator fund provides compensation), M012 (inflation disabled). + +## 8. On-chain vs off-chain boundary +- **On-chain:** Authority module (`x/authority`) stores `AuthorityValidator` (address, category, term_start, term_end, performance), `ValidatorApplication`, `PerformanceRecord`. Events: `EventValidatorApproved`, `EventValidatorRemoved`, `EventTermExpired`, `EventCompensationDistributed`. +- **Off-chain:** AGENT-004 computes ecosystem contribution scores, generates performance reports, and recommends governance actions. Performance scoring and KPI computation are off-chain advisory in v0. +- **Migration:** Gradual transition — PoS and PoA coexist during migration window: + - Phase 1: Reduce active set to qualified validators via governance. + - Phase 2: Enable authority module with curated set. + - Phase 3: Disable PoS inflation module. + +## 9. Attack model +- **Capture:** A single category dominating the validator set is prevented by the composition guarantee (minimum 5 per category). +- **Collusion:** Byzantine tolerance requires active_set > 3f + 1 where f = maximum tolerated Byzantine validators (standard Tendermint). With 15 validators, tolerates up to 4 Byzantine nodes. +- **Self-approval:** Existing validators cannot unilaterally approve new validators; requires governance process (Layer 3). +- **Entrenchment:** 12-month terms with mandatory re-application prevent indefinite incumbency. +- **Compensation gaming:** Performance metrics are multi-factor (uptime + governance + ecosystem), making single-dimension gaming ineffective. AGENT-004 provides independent evaluation. +- **Degradation:** If active set drops below `min_validators` (15), trigger emergency governance escalation (P0). + +## 10. Governance parameters + +| Parameter | Initial Value | Governance Authority | Rationale | +|-----------|--------------|---------------------|-----------| +| `max_validators` | 21 | Layer 4 (Constitutional) | Fundamental network structure | +| `min_validators` | 15 | Layer 4 | Security minimum | +| `term_length` | 12 months | Layer 3 (Human-in-Loop) | Significant governance decision | +| `min_uptime` | 99.5% | Layer 2 (Agentic + Oversight) | Operational parameter | +| `probation_period` | 30 days | Layer 2 | Operational parameter | +| `composition_ratios` | 5/5/5 minimum per category | Layer 3 | Structural governance decision | +| `performance_bonus_share` | 10% of validator fund | Layer 2 | Operational adjustment | + +## 11. Security invariants +1. **Composition Guarantee**: Active set must maintain minimum representation from each category (>= 5 per category). +2. **Byzantine Tolerance**: Active set > 3f + 1 where f = maximum tolerated Byzantine validators (standard Tendermint). +3. **No Self-Approval**: Existing validators cannot unilaterally approve new validators; requires governance process. +4. **Term Accountability**: No validator serves beyond term without re-approval. +5. **Compensation Cap**: Total validator compensation <= validator_fund balance; no inflationary fallback. +6. **Graceful Degradation**: If active set drops below `min_validators`, trigger emergency governance escalation (P0). + +## 12. Open questions (for WG resolution) + +> **OQ-M014-1**: Exact validator set size. The WG discusses 15-21. What is the right target, and should it be fixed or allowed to float within the range based on qualified applicants? + +> **OQ-M014-2**: Should a performance bonus exist, or should all validators receive equal compensation? Equal compensation is simpler and reduces gaming; performance bonuses incentivize operational excellence. + +> **OQ-M014-3**: How is "trusted partner" status determined during the initial transition? Who constitutes the seed set of authority validators? Is this bootstrapped by existing active validators who meet criteria, or selected by governance vote? + +> **OQ-M014-4**: PoA socialization timeline. Gregory noted PoA was first socialized ~18 months ago (mid-2024). What is the target activation date? The Economic Reboot Roadmap suggests Q3-Q4 2026 for pilot, 2027 for full migration. + +> **OQ-M014-5**: What happens to delegated REGEN when PoS is disabled? Staked tokens must be unbonded gracefully. The transition plan should include a mandatory unbonding period with clear communication. + +--- + +## Appendix A — Source anchors +- `phase-2/2.6-economic-reboot-mechanisms.md` + - "PROTOCOL SPECIFICATION: M014" (lines 370-532) + - "Authority Validator Governance" (purpose, design philosophy, validator composition, lifecycle, compensation, governance parameters, security invariants) +- `phase-1/1.4-governance-architecture.md` + - Governance layers (Layer 1-4 delegation model) +- `phase-2/2.4-agent-orchestration.md` + - "AGENT-004: Validator Monitor" (performance tracking, recommendation engine) diff --git a/mechanisms/m014-authority-validator-governance/datasets/README.md b/mechanisms/m014-authority-validator-governance/datasets/README.md new file mode 100644 index 0000000..0c7cb91 --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/datasets/README.md @@ -0,0 +1,26 @@ +# m014 datasets (replay fixtures) + +These fixtures are **deterministic inputs** for generating non-zero m014 KPI outputs **without MCP**. + +## Files +- `schema.json` — JSON schema for replay datasets +- `fixtures/v0_sample.json` — 5 active validators across 3 categories with varied performance profiles +- `fixtures/v0_transition_sample.json` — PoS-to-PoA transition snapshot with validators in all lifecycle states (active, probation, candidate, removed, term_expired) + +## How they are used +A replay runner (e.g., in `regen-heartbeat`) can read a fixture file and compute: +- `total_validators` = number of validators in the fixture +- `validators_by_status` = count per lifecycle state +- `validators_by_category` = count of active validators per composition category +- `avg_performance_score` = mean composite score across active validators +- `composition_valid` = whether each category has >= 5 active validators +- `byzantine_tolerance` = whether active set satisfies 3f + 1 + +The transition fixture (`v0_transition_sample.json`) additionally exercises: +- Mixed lifecycle states representing a mid-migration snapshot +- Probation with poor performance factors +- Removed validator with documented reason +- Term-expired validator awaiting re-application +- The `expected_outputs` field documents expected aggregate state + +These datasets are **specification-only** and do not imply enforcement or on-chain actions. diff --git a/mechanisms/m014-authority-validator-governance/datasets/fixtures/v0_sample.json b/mechanisms/m014-authority-validator-governance/datasets/fixtures/v0_sample.json new file mode 100644 index 0000000..d090094 --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/datasets/fixtures/v0_sample.json @@ -0,0 +1,74 @@ +{ + "mechanism_id": "m014", + "scope": "v0_replay", + "description": "5 active authority validators across 3 categories with varied performance profiles. Used for deterministic KPI computation without MCP.", + "as_of": "2026-06-01T12:00:00Z", + "validator_fund_balance": 50000, + "validators": [ + { + "address": "regenvaloper1alpha", + "moniker": "AlphaBuilder", + "category": "infrastructure_builders", + "status": "active", + "term_start": "2026-01-01T00:00:00Z", + "term_end": "2027-01-01T00:00:00Z", + "factors": { + "uptime": 0.999, + "governance_participation": 0.9, + "ecosystem_contribution": 0.85 + } + }, + { + "address": "regenvaloper1beta", + "moniker": "BetaReFi", + "category": "trusted_refi_partners", + "status": "active", + "term_start": "2026-01-01T00:00:00Z", + "term_end": "2027-01-01T00:00:00Z", + "factors": { + "uptime": 0.997, + "governance_participation": 0.8, + "ecosystem_contribution": 0.7 + } + }, + { + "address": "regenvaloper1gamma", + "moniker": "GammaSteward", + "category": "ecological_data_stewards", + "status": "active", + "term_start": "2026-01-01T00:00:00Z", + "term_end": "2027-01-01T00:00:00Z", + "factors": { + "uptime": 0.993, + "governance_participation": 0.6, + "ecosystem_contribution": 0.5 + } + }, + { + "address": "regenvaloper1delta", + "moniker": "DeltaOps", + "category": "infrastructure_builders", + "status": "active", + "term_start": "2026-01-01T00:00:00Z", + "term_end": "2027-01-01T00:00:00Z", + "factors": { + "uptime": 0.980, + "governance_participation": 0.4, + "ecosystem_contribution": 0.3 + } + }, + { + "address": "regenvaloper1epsilon", + "moniker": "EpsilonPartner", + "category": "trusted_refi_partners", + "status": "active", + "term_start": "2026-03-01T00:00:00Z", + "term_end": "2027-03-01T00:00:00Z", + "factors": { + "uptime": 0.996, + "governance_participation": null, + "ecosystem_contribution": 0.6 + } + } + ] +} diff --git a/mechanisms/m014-authority-validator-governance/datasets/fixtures/v0_transition_sample.json b/mechanisms/m014-authority-validator-governance/datasets/fixtures/v0_transition_sample.json new file mode 100644 index 0000000..36b4eb6 --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/datasets/fixtures/v0_transition_sample.json @@ -0,0 +1,154 @@ +{ + "mechanism_id": "m014", + "scope": "v0_transition_replay", + "description": "PoS-to-PoA transition scenarios: validators in various lifecycle states representing a mid-transition snapshot. Includes candidates, active validators, one on probation, one removed, and one with an expired term.", + "as_of": "2026-09-15T12:00:00Z", + "validator_fund_balance": 75000, + "validators": [ + { + "address": "regenvaloper1node01", + "moniker": "RND-Core", + "category": "infrastructure_builders", + "status": "active", + "term_start": "2026-03-01T00:00:00Z", + "term_end": "2027-03-01T00:00:00Z", + "factors": { + "uptime": 0.9995, + "governance_participation": 0.95, + "ecosystem_contribution": 0.9 + } + }, + { + "address": "regenvaloper1node02", + "moniker": "KOI-Infra", + "category": "infrastructure_builders", + "status": "active", + "term_start": "2026-03-01T00:00:00Z", + "term_end": "2027-03-01T00:00:00Z", + "factors": { + "uptime": 0.998, + "governance_participation": 0.85, + "ecosystem_contribution": 0.8 + } + }, + { + "address": "regenvaloper1node03", + "moniker": "ReFiDAO-Node", + "category": "trusted_refi_partners", + "status": "active", + "term_start": "2026-03-01T00:00:00Z", + "term_end": "2027-03-01T00:00:00Z", + "factors": { + "uptime": 0.996, + "governance_participation": 0.75, + "ecosystem_contribution": 0.65 + } + }, + { + "address": "regenvaloper1node04", + "moniker": "Toucan-Validator", + "category": "trusted_refi_partners", + "status": "active", + "term_start": "2026-03-01T00:00:00Z", + "term_end": "2027-03-01T00:00:00Z", + "factors": { + "uptime": 0.9975, + "governance_participation": 0.7, + "ecosystem_contribution": 0.55 + } + }, + { + "address": "regenvaloper1node05", + "moniker": "EcoVerify-Lab", + "category": "ecological_data_stewards", + "status": "active", + "term_start": "2026-03-01T00:00:00Z", + "term_end": "2027-03-01T00:00:00Z", + "factors": { + "uptime": 0.9985, + "governance_participation": 0.8, + "ecosystem_contribution": 0.75 + } + }, + { + "address": "regenvaloper1node06", + "moniker": "SoilWatch", + "category": "ecological_data_stewards", + "status": "active", + "term_start": "2026-03-01T00:00:00Z", + "term_end": "2027-03-01T00:00:00Z", + "factors": { + "uptime": 0.997, + "governance_participation": 0.6, + "ecosystem_contribution": 0.85 + } + }, + { + "address": "regenvaloper1node07", + "moniker": "FailingOps", + "category": "infrastructure_builders", + "status": "probation", + "term_start": "2026-03-01T00:00:00Z", + "term_end": "2027-03-01T00:00:00Z", + "probation_start": "2026-08-15T00:00:00Z", + "factors": { + "uptime": 0.970, + "governance_participation": 0.3, + "ecosystem_contribution": 0.2 + } + }, + { + "address": "regenvaloper1node08", + "moniker": "NewApplicant-dMRV", + "category": "ecological_data_stewards", + "status": "candidate", + "term_start": "2026-09-15T12:00:00Z", + "term_end": "2027-09-15T12:00:00Z", + "factors": { + "uptime": null, + "governance_participation": null, + "ecosystem_contribution": 0.7 + } + }, + { + "address": "regenvaloper1node09", + "moniker": "LegacyPoS-Removed", + "category": "trusted_refi_partners", + "status": "removed", + "term_start": "2026-03-01T00:00:00Z", + "term_end": "2027-03-01T00:00:00Z", + "removal_reason": "Failed to meet uptime requirements during transition; node offline for 72 hours.", + "factors": { + "uptime": 0.85, + "governance_participation": 0.1, + "ecosystem_contribution": 0.1 + } + }, + { + "address": "regenvaloper1node10", + "moniker": "Kolektivo-Expired", + "category": "trusted_refi_partners", + "status": "term_expired", + "term_start": "2025-09-01T00:00:00Z", + "term_end": "2026-09-01T00:00:00Z", + "factors": { + "uptime": 0.998, + "governance_participation": 0.9, + "ecosystem_contribution": 0.8 + } + } + ], + "expected_outputs": { + "description": "Transition snapshot: 6 active, 1 probation, 1 candidate, 1 removed, 1 term_expired. Composition not yet met (< 5 per category). Probation validator (node07) has poor performance.", + "active_validators": [ + "regenvaloper1node01 (infrastructure_builders)", + "regenvaloper1node02 (infrastructure_builders)", + "regenvaloper1node03 (trusted_refi_partners)", + "regenvaloper1node04 (trusted_refi_partners)", + "regenvaloper1node05 (ecological_data_stewards)", + "regenvaloper1node06 (ecological_data_stewards)" + ], + "composition_valid": false, + "notes": "During PoS-to-PoA transition, composition minimums (5 per category) are not yet met. This is expected during Phase 1 migration." + } +} diff --git a/mechanisms/m014-authority-validator-governance/datasets/schema.json b/mechanisms/m014-authority-validator-governance/datasets/schema.json new file mode 100644 index 0000000..721fc17 --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/datasets/schema.json @@ -0,0 +1,96 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "m014 replay dataset", + "type": "object", + "required": [ + "mechanism_id", + "scope", + "as_of", + "validators" + ], + "properties": { + "mechanism_id": { + "const": "m014" + }, + "scope": { + "type": "string" + }, + "description": { + "type": "string" + }, + "as_of": { + "type": "string", + "description": "ISO-8601 datetime", + "format": "date-time" + }, + "validators": { + "type": "array", + "items": { + "type": "object", + "required": [ + "address", + "moniker", + "category", + "status", + "term_start", + "term_end" + ], + "properties": { + "address": { + "type": "string" + }, + "moniker": { + "type": "string" + }, + "category": { + "type": "string", + "enum": [ + "infrastructure_builders", + "trusted_refi_partners", + "ecological_data_stewards" + ] + }, + "status": { + "type": "string", + "enum": [ + "candidate", + "approved", + "active", + "probation", + "removed", + "term_expired" + ] + }, + "term_start": { + "type": "string", + "format": "date-time" + }, + "term_end": { + "type": "string", + "format": "date-time" + }, + "factors": { + "type": "object", + "properties": { + "uptime": { "type": ["number", "null"] }, + "governance_participation": { "type": ["number", "null"] }, + "ecosystem_contribution": { "type": ["number", "null"] } + } + }, + "probation_start": { + "type": ["string", "null"], + "format": "date-time" + }, + "removal_reason": { + "type": ["string", "null"] + } + } + } + }, + "validator_fund_balance": { + "type": "number", + "minimum": 0.0, + "description": "Total validator fund from M013 for compensation computation" + } + } +} diff --git a/mechanisms/m014-authority-validator-governance/reference-impl/README.md b/mechanisms/m014-authority-validator-governance/reference-impl/README.md new file mode 100644 index 0000000..d5bbe29 --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/reference-impl/README.md @@ -0,0 +1,39 @@ +# m014 reference implementation (v0) + +This folder provides a **canonical computation** for m014 outputs so that different agents/runners +produce consistent numbers. + +## Inputs +### Score computation (`m014_score.js`) +- `validator` — `{ address }` identifying the validator +- `factors` — `{ uptime, governance_participation, ecosystem_contribution }` each 0.0–1.0 or null + +### KPI computation (`m014_kpi.js`) +- `as_of` (ISO-8601 string, Z-suffixed) +- `validators[]` where each validator includes: + - `address`, `moniker`, `category`, `status` + - `factors` — `{ uptime, governance_participation, ecosystem_contribution }` +- `validator_fund_balance` (optional) — total fund from M013 + +## Outputs +### Score block +- `performance_score` — composite weighted score (0.0–1.0): + - `uptime * 0.4 + governance_participation * 0.3 + ecosystem_contribution * 0.3` +- `confidence` — data availability confidence (1.0, 0.67, 0.33, or 0.0) +- `factors` — individual factor values +- `flags` — performance warnings (`below_performance_threshold`, `below_uptime_minimum`, `probation_recommended`) + +### KPI block +- `total_validators` — count across all statuses +- `validators_by_status` — breakdown by lifecycle state +- `validators_by_category` — active validators per composition category +- `avg_performance_score`, `min_performance_score`, `max_performance_score` +- `validators_below_threshold` — count with score < 0.70 +- `composition_valid` — boolean: each category has >= 5 active validators +- `byzantine_tolerance` — active count, max f, tolerance met +- `compensation` — base per validator and bonus pool (when fund balance provided) + +## Self-test +```bash +node mechanisms/m014-authority-validator-governance/reference-impl/m014_score.js +``` diff --git a/mechanisms/m014-authority-validator-governance/reference-impl/m014_kpi.js b/mechanisms/m014-authority-validator-governance/reference-impl/m014_kpi.js new file mode 100644 index 0000000..1b96159 --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/reference-impl/m014_kpi.js @@ -0,0 +1,117 @@ +import { computeM014Score } from "./m014_score.js"; + +/** + * m014 Authority Validator Governance — KPI Computation + * + * Computes aggregate KPI metrics for the authority validator set. + * + * @param {Object} opts + * @param {string} opts.as_of - ISO 8601 timestamp for evaluation point-in-time + * @param {Array} opts.validators - Array of validator objects with address, moniker, + * category, status, and factors (uptime, governance_participation, ecosystem_contribution) + * @param {number} [opts.validator_fund_balance] - Optional: total validator fund balance from M013 + * @returns {Object} KPI block conforming to m014_kpi.schema.json + */ +export function computeM014KPI({ as_of, validators, validator_fund_balance = null }) { + const vals = validators ?? []; + + // Count by status + const validators_by_status = { + candidate: 0, + approved: 0, + active: 0, + probation: 0, + removed: 0, + term_expired: 0 + }; + for (const v of vals) { + const st = v.status ?? "candidate"; + if (st in validators_by_status) validators_by_status[st]++; + } + + // Active validators only for category/performance analysis + const activeVals = vals.filter(v => v.status === "active" || v.status === "probation"); + + // Count active by category + const validators_by_category = { + infrastructure_builders: 0, + trusted_refi_partners: 0, + ecological_data_stewards: 0 + }; + for (const v of activeVals) { + const cat = v.category; + if (cat in validators_by_category) validators_by_category[cat]++; + } + + // Compute performance scores for active validators + const scores = []; + let belowThreshold = 0; + + for (const v of activeVals) { + const result = computeM014Score({ + validator: { address: v.address }, + factors: v.factors ?? {} + }); + scores.push(result.performance_score); + if (result.flags.includes("below_performance_threshold")) belowThreshold++; + } + + const avg_performance_score = scores.length + ? Number((scores.reduce((a, b) => a + b, 0) / scores.length).toFixed(4)) + : null; + + const min_performance_score = scores.length + ? Number(Math.min(...scores).toFixed(4)) + : null; + + const max_performance_score = scores.length + ? Number(Math.max(...scores).toFixed(4)) + : null; + + // Composition validity: each category must have >= 5 active validators + const composition_valid = + validators_by_category.infrastructure_builders >= 5 && + validators_by_category.trusted_refi_partners >= 5 && + validators_by_category.ecological_data_stewards >= 5; + + // Byzantine tolerance: active_count > 3f + 1 + // Include probation validators — they are still in the active set + const active_count = activeVals.length; + const max_byzantine_f = Math.floor((active_count - 1) / 3); + const tolerance_met = active_count > 0 && active_count >= 3 * max_byzantine_f + 1; + + // Compensation stats + let compensation = null; + if (validator_fund_balance != null && active_count > 0) { + const base_per_validator = Number(((validator_fund_balance * 0.90) / active_count).toFixed(2)); + const bonus_pool = Number((validator_fund_balance * 0.10).toFixed(2)); + compensation = { + validator_fund_balance, + base_per_validator, + bonus_pool + }; + } + + const kpi = { + mechanism_id: "m014", + scope: "v0", + as_of, + total_validators: vals.length, + validators_by_status, + validators_by_category, + avg_performance_score, + min_performance_score, + max_performance_score, + validators_below_threshold: belowThreshold, + composition_valid, + byzantine_tolerance: { + active_count, + max_byzantine_f, + tolerance_met + } + }; + + if (compensation) kpi.compensation = compensation; + + return kpi; +} diff --git a/mechanisms/m014-authority-validator-governance/reference-impl/m014_score.js b/mechanisms/m014-authority-validator-governance/reference-impl/m014_score.js new file mode 100644 index 0000000..b8096c1 --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/reference-impl/m014_score.js @@ -0,0 +1,152 @@ +/** + * m014 Authority Validator Governance — Performance Score + * + * Computes a composite performance score for a validator based on three + * weighted factors: + * - uptime: weight 0.4 (blocks_signed / blocks_expected) + * - governance_participation: weight 0.3 (votes_cast / proposals_available) + * - ecosystem_contribution: weight 0.3 (AGENT-004 assessed score, 0–1) + * + * Confidence is based on data availability: + * - 3 factors present → 1.0 + * - 2 factors present → 0.67 + * - 1 factor present → 0.33 + * - 0 factors → 0.0 + * + * See SPEC.md section 5 for full specification. + * + * @param {Object} opts + * @param {Object} opts.validator - { address } + * @param {Object} opts.factors - { uptime, governance_participation, ecosystem_contribution } + * Each factor is a number 0–1 or null/undefined if unavailable. + * @returns {{ address: string, performance_score: number, confidence: number, + * factors: Object, flags: string[] }} + */ +export function computeM014Score({ validator, factors }) { + const WEIGHTS = { + uptime: 0.4, + governance_participation: 0.3, + ecosystem_contribution: 0.3 + }; + + const FACTOR_KEYS = Object.keys(WEIGHTS); + const address = validator?.address ?? "unknown"; + + // Determine available factors + let availableCount = 0; + const resolvedFactors = {}; + + for (const key of FACTOR_KEYS) { + const val = factors?.[key]; + if (val != null && Number.isFinite(val)) { + resolvedFactors[key] = Math.max(0, Math.min(1, val)); + availableCount++; + } else { + resolvedFactors[key] = null; + } + } + + // Confidence based on data availability + const confidenceMap = { 3: 1.0, 2: 0.67, 1: 0.33, 0: 0.0 }; + const confidence = confidenceMap[availableCount] ?? 0.0; + + // Compute weighted score using only available factors + let weightedSum = 0; + let totalWeight = 0; + + for (const key of FACTOR_KEYS) { + if (resolvedFactors[key] !== null) { + weightedSum += resolvedFactors[key] * WEIGHTS[key]; + totalWeight += WEIGHTS[key]; + } + } + + // When all factors present, use direct weighted sum. + // When some are missing, re-normalize based on available weights. + const performance_score = totalWeight > 0 + ? weightedSum / totalWeight + : 0.0; + + const normalizedScore = Number(performance_score.toFixed(4)); + + // Performance flags + const flags = []; + if (normalizedScore < 0.70 && availableCount > 0) { + flags.push("below_performance_threshold"); + } + if (resolvedFactors.uptime !== null && resolvedFactors.uptime < 0.995) { + flags.push("below_uptime_minimum"); + } + if (flags.includes("below_performance_threshold") || flags.includes("below_uptime_minimum")) { + flags.push("probation_recommended"); + } + + return { + address, + performance_score: normalizedScore, + confidence, + factors: { + uptime: resolvedFactors.uptime, + governance_participation: resolvedFactors.governance_participation, + ecosystem_contribution: resolvedFactors.ecosystem_contribution + }, + flags + }; +} + +// ── Self-test harness ────────────────────────────────────────────────── +// Run: node mechanisms/m014-authority-validator-governance/reference-impl/m014_score.js +import { readFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import path from "node:path"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +function selfTest() { + const inputPath = path.join(__dirname, "test_vectors", "vector_v0_sample.input.json"); + const expectedPath = path.join(__dirname, "test_vectors", "vector_v0_sample.expected.json"); + + const input = JSON.parse(readFileSync(inputPath, "utf8")); + const expected = JSON.parse(readFileSync(expectedPath, "utf8")); + + let pass = 0; + let fail = 0; + + for (const validatorInput of input.validators) { + const result = computeM014Score({ + validator: { address: validatorInput.address }, + factors: validatorInput.factors + }); + + const exp = expected.scores.find(s => s.address === validatorInput.address); + if (!exp) { + console.error(` FAIL: no expected output for ${validatorInput.address}`); + fail++; + continue; + } + + const scoreMatch = Math.abs(result.performance_score - exp.performance_score) < 0.0002; + const confMatch = Math.abs(result.confidence - exp.confidence) < 0.01; + const flagsMatch = JSON.stringify(result.flags.sort()) === JSON.stringify((exp.flags ?? []).sort()); + + if (scoreMatch && confMatch && flagsMatch) { + console.log(` PASS: ${validatorInput.address} → score=${result.performance_score}, confidence=${result.confidence}, flags=[${result.flags}]`); + pass++; + } else { + console.error(` FAIL: ${validatorInput.address}`); + if (!scoreMatch) console.error(` score: got ${result.performance_score}, expected ${exp.performance_score}`); + if (!confMatch) console.error(` confidence: got ${result.confidence}, expected ${exp.confidence}`); + if (!flagsMatch) console.error(` flags: got [${result.flags}], expected [${exp.flags}]`); + fail++; + } + } + + console.log(`\nm014_score self-test: ${pass} passed, ${fail} failed`); + if (fail > 0) process.exit(1); +} + +// Run self-test if executed directly +if (process.argv[1] === __filename) { + selfTest(); +} diff --git a/mechanisms/m014-authority-validator-governance/reference-impl/test_vectors/vector_v0_sample.expected.json b/mechanisms/m014-authority-validator-governance/reference-impl/test_vectors/vector_v0_sample.expected.json new file mode 100644 index 0000000..c7451bd --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/reference-impl/test_vectors/vector_v0_sample.expected.json @@ -0,0 +1,66 @@ +{ + "scores": [ + { + "address": "regenvaloper1alpha", + "performance_score": 0.9246, + "confidence": 1.0, + "factors": { + "uptime": 0.999, + "governance_participation": 0.9, + "ecosystem_contribution": 0.85 + }, + "flags": [] + }, + { + "address": "regenvaloper1beta", + "performance_score": 0.8488, + "confidence": 1.0, + "factors": { + "uptime": 0.997, + "governance_participation": 0.8, + "ecosystem_contribution": 0.7 + }, + "flags": [] + }, + { + "address": "regenvaloper1gamma", + "performance_score": 0.7272, + "confidence": 1.0, + "factors": { + "uptime": 0.993, + "governance_participation": 0.6, + "ecosystem_contribution": 0.5 + }, + "flags": [ + "below_uptime_minimum", + "probation_recommended" + ] + }, + { + "address": "regenvaloper1delta", + "performance_score": 0.602, + "confidence": 1.0, + "factors": { + "uptime": 0.98, + "governance_participation": 0.4, + "ecosystem_contribution": 0.3 + }, + "flags": [ + "below_performance_threshold", + "below_uptime_minimum", + "probation_recommended" + ] + }, + { + "address": "regenvaloper1epsilon", + "performance_score": 0.8263, + "confidence": 0.67, + "factors": { + "uptime": 0.996, + "governance_participation": null, + "ecosystem_contribution": 0.6 + }, + "flags": [] + } + ] +} diff --git a/mechanisms/m014-authority-validator-governance/reference-impl/test_vectors/vector_v0_sample.input.json b/mechanisms/m014-authority-validator-governance/reference-impl/test_vectors/vector_v0_sample.input.json new file mode 100644 index 0000000..3bcc26c --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/reference-impl/test_vectors/vector_v0_sample.input.json @@ -0,0 +1,60 @@ +{ + "description": "5 validators across 3 categories with varied performance profiles for m014 scoring.", + "validators": [ + { + "address": "regenvaloper1alpha", + "moniker": "AlphaBuilder", + "category": "infrastructure_builders", + "status": "active", + "factors": { + "uptime": 0.999, + "governance_participation": 0.9, + "ecosystem_contribution": 0.85 + } + }, + { + "address": "regenvaloper1beta", + "moniker": "BetaReFi", + "category": "trusted_refi_partners", + "status": "active", + "factors": { + "uptime": 0.997, + "governance_participation": 0.8, + "ecosystem_contribution": 0.7 + } + }, + { + "address": "regenvaloper1gamma", + "moniker": "GammaSteward", + "category": "ecological_data_stewards", + "status": "active", + "factors": { + "uptime": 0.993, + "governance_participation": 0.6, + "ecosystem_contribution": 0.5 + } + }, + { + "address": "regenvaloper1delta", + "moniker": "DeltaOps", + "category": "infrastructure_builders", + "status": "active", + "factors": { + "uptime": 0.980, + "governance_participation": 0.4, + "ecosystem_contribution": 0.3 + } + }, + { + "address": "regenvaloper1epsilon", + "moniker": "EpsilonPartner", + "category": "trusted_refi_partners", + "status": "active", + "factors": { + "uptime": 0.996, + "governance_participation": null, + "ecosystem_contribution": 0.6 + } + } + ] +} diff --git a/mechanisms/m014-authority-validator-governance/schemas/README.md b/mechanisms/m014-authority-validator-governance/schemas/README.md new file mode 100644 index 0000000..133e99b --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/schemas/README.md @@ -0,0 +1,14 @@ +# m014 output schemas + +These JSON Schemas define **canonical output shapes** for m014 (Authority Validator Governance) artifacts. + +## Files +- `m014_validator.schema.json` — schema for individual authority validators (address, category, lifecycle status, term, performance). +- `m014_performance.schema.json` — schema for computed performance score output (composite score, confidence, factor breakdown, flags). +- `m014_kpi.schema.json` — schema for the KPI JSON block emitted by agents/digests (validator counts by status/category, average performance, compensation stats, composition validity). + +## Notes +- These schemas are intended for **validation** and consistency across repos (Heartbeat, agent skills, etc.). +- v0 is specification-only: schemas describe outputs, not enforcement. +- The `status` field on validators tracks lifecycle state (candidate, approved, active, probation, removed, term_expired). See SPEC.md section 6.1. +- Performance scoring uses a 3-factor weighted model: uptime (0.4) + governance participation (0.3) + ecosystem contribution (0.3). See SPEC.md section 5. diff --git a/mechanisms/m014-authority-validator-governance/schemas/m014_kpi.schema.json b/mechanisms/m014-authority-validator-governance/schemas/m014_kpi.schema.json new file mode 100644 index 0000000..2436ea5 --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/schemas/m014_kpi.schema.json @@ -0,0 +1,118 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "m014 KPI output", + "type": "object", + "additionalProperties": false, + "required": [ + "mechanism_id", + "scope", + "as_of", + "total_validators", + "validators_by_status", + "validators_by_category", + "avg_performance_score", + "composition_valid" + ], + "properties": { + "mechanism_id": { + "const": "m014" + }, + "scope": { + "type": "string" + }, + "as_of": { + "type": "string", + "description": "ISO-8601 datetime with timezone (e.g., 2026-02-18T12:00:00Z)", + "format": "date-time" + }, + "total_validators": { + "type": "integer", + "minimum": 0, + "description": "Total number of validators across all statuses" + }, + "validators_by_status": { + "type": "object", + "additionalProperties": false, + "properties": { + "candidate": { "type": "integer", "minimum": 0 }, + "approved": { "type": "integer", "minimum": 0 }, + "active": { "type": "integer", "minimum": 0 }, + "probation": { "type": "integer", "minimum": 0 }, + "removed": { "type": "integer", "minimum": 0 }, + "term_expired": { "type": "integer", "minimum": 0 } + } + }, + "validators_by_category": { + "type": "object", + "additionalProperties": false, + "description": "Count of active validators per category", + "properties": { + "infrastructure_builders": { "type": "integer", "minimum": 0 }, + "trusted_refi_partners": { "type": "integer", "minimum": 0 }, + "ecological_data_stewards": { "type": "integer", "minimum": 0 } + } + }, + "avg_performance_score": { + "type": ["number", "null"], + "minimum": 0.0, + "maximum": 1.0, + "description": "Average composite performance score across active validators" + }, + "min_performance_score": { + "type": ["number", "null"], + "minimum": 0.0, + "maximum": 1.0, + "description": "Minimum performance score among active validators" + }, + "max_performance_score": { + "type": ["number", "null"], + "minimum": 0.0, + "maximum": 1.0, + "description": "Maximum performance score among active validators" + }, + "validators_below_threshold": { + "type": "integer", + "minimum": 0, + "description": "Count of active validators with performance_score < 0.70" + }, + "composition_valid": { + "type": "boolean", + "description": "True if each category has >= 5 active validators" + }, + "byzantine_tolerance": { + "type": "object", + "additionalProperties": false, + "description": "Byzantine fault tolerance metrics", + "properties": { + "active_count": { "type": "integer", "minimum": 0 }, + "max_byzantine_f": { "type": "integer", "minimum": 0 }, + "tolerance_met": { "type": "boolean" } + } + }, + "compensation": { + "type": "object", + "additionalProperties": false, + "description": "Compensation statistics for the period", + "properties": { + "validator_fund_balance": { + "type": ["number", "null"], + "minimum": 0.0, + "description": "Total validator fund balance from M013" + }, + "base_per_validator": { + "type": ["number", "null"], + "minimum": 0.0, + "description": "Base compensation per active validator" + }, + "bonus_pool": { + "type": ["number", "null"], + "minimum": 0.0, + "description": "Total performance bonus pool (10% of fund)" + } + } + }, + "notes": { + "type": "string" + } + } +} diff --git a/mechanisms/m014-authority-validator-governance/schemas/m014_performance.schema.json b/mechanisms/m014-authority-validator-governance/schemas/m014_performance.schema.json new file mode 100644 index 0000000..ba1131d --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/schemas/m014_performance.schema.json @@ -0,0 +1,77 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "m014 performance score output", + "description": "Schema for a computed validator performance score. See SPEC.md section 5.", + "type": "object", + "additionalProperties": false, + "required": [ + "address", + "performance_score", + "confidence", + "factors" + ], + "properties": { + "address": { + "type": "string", + "description": "Validator operator address" + }, + "performance_score": { + "type": "number", + "minimum": 0.0, + "maximum": 1.0, + "description": "Composite weighted score: uptime*0.4 + governance*0.3 + ecosystem*0.3" + }, + "confidence": { + "type": "number", + "minimum": 0.0, + "maximum": 1.0, + "description": "Data availability confidence: 1.0 (all factors), 0.67 (one missing), 0.33 (two missing), 0.0 (none)" + }, + "factors": { + "type": "object", + "additionalProperties": false, + "required": [ + "uptime", + "governance_participation", + "ecosystem_contribution" + ], + "properties": { + "uptime": { + "type": ["number", "null"], + "minimum": 0.0, + "maximum": 1.0, + "description": "blocks_signed / blocks_expected (null if unavailable)" + }, + "governance_participation": { + "type": ["number", "null"], + "minimum": 0.0, + "maximum": 1.0, + "description": "votes_cast / proposals_available (null if unavailable)" + }, + "ecosystem_contribution": { + "type": ["number", "null"], + "minimum": 0.0, + "maximum": 1.0, + "description": "AGENT-004 assessed score (null if unavailable)" + } + } + }, + "flags": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "below_performance_threshold", + "below_uptime_minimum", + "probation_recommended" + ] + }, + "description": "Performance flags based on thresholds (section 5.3)" + }, + "evaluated_at": { + "type": "string", + "format": "date-time", + "description": "ISO-8601 timestamp of evaluation" + } + } +} diff --git a/mechanisms/m014-authority-validator-governance/schemas/m014_validator.schema.json b/mechanisms/m014-authority-validator-governance/schemas/m014_validator.schema.json new file mode 100644 index 0000000..c2e1339 --- /dev/null +++ b/mechanisms/m014-authority-validator-governance/schemas/m014_validator.schema.json @@ -0,0 +1,90 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "m014 validator item", + "description": "Schema for an authority validator in the m014 curated validator set. See SPEC.md section 6.", + "type": "object", + "additionalProperties": false, + "required": [ + "address", + "moniker", + "category", + "status", + "term_start", + "term_end" + ], + "properties": { + "address": { + "type": "string", + "description": "Validator operator address (e.g., regenvaloper1...)" + }, + "moniker": { + "type": "string", + "description": "Human-readable validator name" + }, + "category": { + "type": "string", + "enum": [ + "infrastructure_builders", + "trusted_refi_partners", + "ecological_data_stewards" + ], + "description": "Validator category per composition requirements" + }, + "status": { + "type": "string", + "enum": [ + "candidate", + "approved", + "active", + "probation", + "removed", + "term_expired" + ], + "description": "Validator lifecycle state. See SPEC.md section 6.1." + }, + "term_start": { + "type": "string", + "format": "date-time", + "description": "ISO-8601 term start date" + }, + "term_end": { + "type": "string", + "format": "date-time", + "description": "ISO-8601 term end date" + }, + "performance": { + "type": "object", + "additionalProperties": false, + "description": "Most recent performance evaluation", + "properties": { + "uptime": { + "type": ["number", "null"], + "minimum": 0.0, + "maximum": 1.0, + "description": "blocks_signed / blocks_expected (null if unavailable)" + }, + "governance_participation": { + "type": ["number", "null"], + "minimum": 0.0, + "maximum": 1.0, + "description": "votes_cast / proposals_available (null if unavailable)" + }, + "ecosystem_contribution": { + "type": ["number", "null"], + "minimum": 0.0, + "maximum": 1.0, + "description": "AGENT-004 assessed contribution score (null if unavailable)" + } + } + }, + "probation_start": { + "type": ["string", "null"], + "format": "date-time", + "description": "ISO-8601 timestamp when probation began (null if not on probation)" + }, + "removal_reason": { + "type": ["string", "null"], + "description": "Reason for removal (null if not removed)" + } + } +} diff --git a/package.json b/package.json index d174e09..bf7a676 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "agentic-tokenomics", "private": true, + "type": "module", "version": "0.0.0", "scripts": { "verify": "node scripts/verify.mjs",