Add m008 Data Attestation Bonding mechanism spec#20
Add m008 Data Attestation Bonding mechanism spec#20CShear wants to merge 2 commits intoregen-network:mainfrom
Conversation
Adds full mechanism spec for m008 following the m010 pattern: - SPEC.md with 13 sections covering bond lifecycle, Arbiter DAO resolution, type-based bond schedule, and 4-factor quality scoring - JSON schemas for attestation lifecycle, quality score output, and KPI metrics - Reference implementation (m008_score.js, m008_kpi.js) with deterministic self-test - Test vectors and replay dataset fixtures including challenge scenarios - Updates MECHANISM_CONSUMERS.md with m008 consumer mappings Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary of ChangesHello @CShear, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a new mechanism, m008 Data Attestation Bonding, aimed at enhancing the integrity and reliability of ecological data within the Regen ecosystem. By requiring attesters to bond REGEN tokens, the system creates economic incentives for high-quality data submissions and establishes a structured process for challenging and resolving disputes. This foundational work provides the necessary specifications, schemas, and reference implementations for future on-chain deployment, fostering a more trustworthy and accountable data attestation environment. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces the m008 Data Attestation Bonding mechanism, including its specification, reference implementation, schemas, and test data. The changes are comprehensive and well-structured. My review focuses on ensuring consistency and clarity across these new artifacts. I've identified a few areas where the specification, schemas, and implementation have minor inconsistencies, particularly around state definitions, transition logic, and return values. Addressing these will improve the overall robustness and clarity of the new mechanism, aligning with established guidelines for state machine documentation and explicit logic definition.
| CHALLENGED → RESOLVED_INVALID | ||
| trigger: arbiter_dao.vote(INVALID) OR admin.resolve(INVALID) (v0) | ||
| guard: quorum_met (v1), resolution_authority_verified | ||
| action: challenger.receive(bond × 0.5 + challenge_deposit - arbiter_fee) | ||
| community_pool.receive(bond × 0.5) | ||
| attestation.status = SLASHED |
There was a problem hiding this comment.
There's an inconsistency in the state machine regarding the RESOLVED_INVALID and SLASHED states. The CHALLENGED → RESOLVED_INVALID transition specifies an action of attestation.status = SLASHED. This implies an invalid resolution directly leads to the SLASHED state. However, RESOLVED_INVALID is also defined as a distinct status in the state list, schemas, and is used in the v0_challenge_sample.json dataset.
Please clarify this relationship. For instance, if a RESOLVED_INVALID outcome always results in the SLASHED state, then RESOLVED_INVALID should probably not be a state itself. The current definition is contradictory.
References
- To improve document clarity, co-locate all state definitions and transitions within the primary state machine documentation, including definitions for edge-case flows like escalations.
| "resolution": { | ||
| "type": "string", | ||
| "enum": ["ATTESTER_WINS", "CHALLENGER_WINS"] | ||
| }, |
There was a problem hiding this comment.
The challenge.resolution property and its enum ["ATTESTER_WINS", "CHALLENGER_WINS"] are inconsistent with SPEC.md and the replay dataset schema (mechanisms/m008-attestation-bonding/datasets/schema.json). The spec and dataset use an outcome property with VALID or INVALID values. To maintain consistency across the mechanism's artifacts, this schema should be aligned with the specification.
| "resolution": { | |
| "type": "string", | |
| "enum": ["ATTESTER_WINS", "CHALLENGER_WINS"] | |
| }, | |
| "outcome": { | |
| "type": ["string", "null"], | |
| "enum": ["VALID", "INVALID", null] | |
| }, |
| - If M010 score exists: `f_reputation = m010_score` | ||
| - If no M010 score: `f_reputation = 300` (cautious default, below neutral) | ||
| - Track record adjustment: `f_reputation = 0.7 × m010_score + 0.3 × (unchallenged_rate × 1000)` |
There was a problem hiding this comment.
There's an ambiguity in how f_reputation is calculated. The spec provides a base calculation (f_reputation = m010_score or a default of 300) and a separate Track record adjustment formula. It's unclear under which conditions the adjustment formula should be used. Does it always apply when a track record exists, overriding the base score, or is it an optional calculation? Please clarify the logic to prevent implementation ambiguity.
For example, you could structure it like this:
- If M010 score exists:
- If attester has a track record (e.g., `unchallenged_rate` is available):
`f_reputation = 0.7 × m010_score + 0.3 × (unchallenged_rate × 1000)`
- Else:
`f_reputation = m010_score`
- If no M010 score: `f_reputation = 300` (cautious default, below neutral)References
- When specifying transition logic between different mechanisms (e.g., multipliers), explicitly define the function (e.g.,
max()) and the state-based conditions (phase-gating) that govern the transition to prevent implementation ambiguity.
| ## 6. State machine | ||
|
|
||
| ``` | ||
| States: {BONDED, ACTIVE, CHALLENGED, RESOLVED_VALID, RESOLVED_INVALID, RELEASED, SLASHED} |
There was a problem hiding this comment.
The state machine defines BONDED as the initial state. However, the sample dataset v0_sample.json and the dataset schema mechanisms/m008-attestation-bonding/datasets/schema.json include a SUBMITTED status, which appears to precede BONDED. For consistency, the state machine should be updated to include SUBMITTED as the initial state before a bond is confirmed.
| States: {BONDED, ACTIVE, CHALLENGED, RESOLVED_VALID, RESOLVED_INVALID, RELEASED, SLASHED} | |
| States: {SUBMITTED, BONDED, ACTIVE, CHALLENGED, RESOLVED_VALID, RESOLVED_INVALID, RELEASED, SLASHED} |
References
- To improve document clarity, co-locate all state definitions and transitions within the primary state machine documentation, including definitions for edge-case flows like escalations.
| const slash_rate = attestations_challenged > 0 | ||
| ? Number((attestations_slashed / attestations_challenged).toFixed(4)) | ||
| : null; |
There was a problem hiding this comment.
The calculation for slash_rate returns null if attestations_challenged is zero. This is inconsistent with challenge_rate, which returns 0.0 if attestations_submitted is zero. For consistency, slash_rate should also return 0.0 when there are no challenges, as a rate of zero is more accurate than an undefined (null) value in this context.
| const slash_rate = attestations_challenged > 0 | |
| ? Number((attestations_slashed / attestations_challenged).toFixed(4)) | |
| : null; | |
| const slash_rate = attestations_challenged > 0 | |
| ? Number((attestations_slashed / attestations_challenged).toFixed(4)) | |
| : 0.0; |
…ation clarity - SPEC.md: add SUBMITTED initial state, remove RESOLVED_INVALID (invalid resolution transitions directly to SLASHED), clarify terminal states - SPEC.md: restructure reputation formula with explicit conditional logic - m008_attestation.schema.json: rename resolution → outcome, align enum with dataset schema (VALID/INVALID instead of ATTESTER_WINS/CHALLENGER_WINS) - m008_kpi.js: slash_rate returns 0.0 instead of null when no challenges Fixes Gemini review on PR regen-network#20. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Test plan
node mechanisms/m008-attestation-bonding/reference-impl/m008_score.js— self-test PASS (5 test vectors)npm run verify— PASSnpm run check:index— mechanism index up to date🤖 Generated with Claude Code