Skip to content

Add m009 Service Provision Escrow mechanism spec#21

Open
CShear wants to merge 2 commits intoregen-network:mainfrom
CShear:feat/m009-service-escrow
Open

Add m009 Service Provision Escrow mechanism spec#21
CShear wants to merge 2 commits intoregen-network:mainfrom
CShear:feat/m009-service-escrow

Conversation

@CShear
Copy link
Contributor

@CShear CShear commented Feb 18, 2026

Summary

  • Adds full mechanism spec for m009 (Service Provision Escrow) following the established m010 pattern
  • Includes SPEC.md (13 sections), JSON schemas (agreement lifecycle, milestone review, KPI), reference implementation with deterministic self-test, replay datasets with dispute scenarios
  • 4-factor milestone review scoring: deliverable quality (0.40), evidence completeness (0.25), milestone consistency (0.20), provider reputation (0.15)
  • Recommendation engine: APPROVE / NEEDS_REVISION / FLAG_FOR_CLIENT based on score and confidence thresholds
  • Covers milestone-based escrow, provider bond, cancellation guards, Arbiter DAO dispute resolution (CLIENT_WINS, PROVIDER_WINS, SPLIT), and 5 standard service types
  • Updates MECHANISM_CONSUMERS.md with m009 consumer mappings

Test plan

  • node mechanisms/m009-service-escrow/reference-impl/m009_score.js — self-test PASS (5 test vectors)
  • npm run verify — PASS
  • npm run check:index — mechanism index up to date
  • m010 regression — self-test still passes
  • Review SPEC.md sections for accuracy against phase-2/2.1 and phase-3/3.1 source material
  • Validate JSON schema coverage against SPEC.md state machine

🤖 Generated with Claude Code

Adds full mechanism spec for m009 following the m010 pattern:
- SPEC.md with 13 sections covering milestone-based escrow, dispute resolution
  via Arbiter DAO, cancellation guards, and agent milestone review scoring
- JSON schemas for agreement lifecycle, milestone review score, and KPI metrics
- Reference implementation (m009_score.js, m009_kpi.js) with deterministic self-test
- Test vectors and replay dataset fixtures including dispute scenarios
  (CLIENT_WINS, PROVIDER_WINS, SPLIT)
- 4-factor scoring: deliverable quality (0.40), evidence completeness (0.25),
  milestone consistency (0.20), provider reputation (0.15)
- Updates MECHANISM_CONSUMERS.md with m009 consumer mappings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @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 core mechanism, m009 Service Provision Escrow, designed to facilitate trustless, milestone-based service agreements within the ecosystem. It provides a robust framework for managing service engagements from proposal to completion, including agent-assisted deliverable review, defined token flows, and a structured dispute resolution process. The addition aims to enhance transparency and reliability for both clients and providers of ecosystem services.

Highlights

  • New Mechanism: m009 Service Provision Escrow: Introduced the full specification for m009, a trustless milestone-based escrow mechanism for ecosystem services, following the established m010 pattern.
  • Comprehensive Specification: The mechanism includes a detailed SPEC.md (13 sections), JSON schemas for agreement lifecycle, milestone review, and KPI, along with a reference implementation and deterministic replay datasets for dispute scenarios.
  • Milestone Review Scoring: A 4-factor weighted scoring system for milestone reviews has been defined: deliverable quality (0.40), evidence completeness (0.25), milestone consistency (0.20), and provider reputation (0.15).
  • Recommendation Engine: An agent-based recommendation engine is included, providing 'APPROVE', 'NEEDS_REVISION', or 'FLAG_FOR_CLIENT' based on score and confidence thresholds.
  • Lifecycle and Dispute Resolution: The mechanism covers milestone-based escrow, provider bonds, cancellation guards, and integrates with Arbiter DAO for dispute resolution (CLIENT_WINS, PROVIDER_WINS, SPLIT), supporting 5 standard service types.
  • Documentation and Tooling Updates: Updated the main README.md and MECHANISM_CONSUMERS.md to reflect the new m009 mechanism, and added reference implementation with self-tests and replay datasets.
Changelog
  • README.md
    • Added a link to the new m009 Service Provision Escrow mechanism in the main mechanisms index.
  • docs/MECHANISM_CONSUMERS.md
    • Appended a new section for m009, detailing its canonical specification, output schemas (KPI, milestone review, agreement lifecycle), deterministic datasets, and known consumers.
  • mechanisms/m009-service-escrow/README.md
    • Created a new README file for m009, outlining its purpose, outputs (milestone review score, confidence, recommendation, KPI block), current limitations (v0), scoring formula, and how to reference its components.
  • mechanisms/m009-service-escrow/SPEC.md
    • Added the comprehensive specification document for m009, detailing the problem, target actors, signal definition, evidence inputs, scoring function, agreement and milestone state machines, token flows, governance parameters, standard service types, security invariants, attack model, integration points, acceptance tests, and a multi-phase rollout plan.
  • mechanisms/m009-service-escrow/datasets/README.md
    • Created a README file for m009 replay datasets, describing their purpose and listing the schema and fixture files for sample and dispute scenarios.
  • mechanisms/m009-service-escrow/datasets/fixtures/v0_dispute_sample.json
    • Added a JSON fixture file containing sample service agreements specifically designed to test dispute resolution scenarios, including CLIENT_WINS, PROVIDER_WINS, and SPLIT outcomes.
  • mechanisms/m009-service-escrow/datasets/fixtures/v0_sample.json
    • Added a JSON fixture file containing sample service agreements across various lifecycle statuses (IN_PROGRESS, MILESTONE_REVIEW, COMPLETED, CANCELLED, PROPOSED) for general testing.
  • mechanisms/m009-service-escrow/datasets/schema.json
    • Added a JSON schema defining the structure and validation rules for m009 replay datasets, including agreement and milestone details.
  • mechanisms/m009-service-escrow/reference-impl/README.md
    • Created a README file for the m009 reference implementation, detailing the inputs and outputs for both the scoring and KPI computation scripts, including the scoring formula.
  • mechanisms/m009-service-escrow/reference-impl/m009_kpi.js
    • Added a JavaScript file (m009_kpi.js) that implements the logic for computing Key Performance Indicator (KPI) metrics based on m009 service agreements, such as agreement counts, dispute rates, and escrow economics.
  • mechanisms/m009-service-escrow/reference-impl/m009_score.js
    • Added a JavaScript file (m009_score.js) that implements the weighted composite scoring function for milestone deliverable reviews, including confidence calculation and recommendation logic, along with a self-test.
  • mechanisms/m009-service-escrow/reference-impl/test_vectors/vector_v0_sample.expected.json
    • Added a JSON file containing the expected output scores and recommendations for the m009 scoring function's self-test, based on sample input vectors.
  • mechanisms/m009-service-escrow/reference-impl/test_vectors/vector_v0_sample.input.json
    • Added a JSON file containing input test vectors for the m009 scoring function's self-test, including milestone metadata and pre-computed factor scores.
  • mechanisms/m009-service-escrow/schemas/README.md
    • Created a README file for m009 output schemas, explaining their purpose for validation and listing the agreement, milestone review, and KPI schema files.
  • mechanisms/m009-service-escrow/schemas/m009_agreement.schema.json
    • Added a JSON schema defining the structure and validation rules for the m009 service agreement lifecycle object, including client, provider, escrow, milestones, and dispute details.
  • mechanisms/m009-service-escrow/schemas/m009_kpi.schema.json
    • Added a JSON schema defining the structure and validation rules for m009 KPI metrics, such as agreement counts, dispute rates, and escrow economics.
  • mechanisms/m009-service-escrow/schemas/m009_milestone_review.schema.json
    • Added a JSON schema defining the structure and validation rules for the m009 milestone review quality score output, including score, confidence, recommendation, and individual factor breakdowns.
  • package.json
    • Updated the package.json to specify 'type': 'module' for consistent ES module behavior.
Activity
  • The author, CShear, has implemented a new mechanism, m009 Service Provision Escrow, including its full specification, schemas, and reference implementation.
  • Self-tests for the m009_score.js reference implementation have been executed and passed successfully, validating its core scoring logic.
  • General repository verification (npm run verify) and mechanism index checks (npm run check:index) were performed and passed, ensuring overall project integrity and up-to-date documentation.
  • Regression tests for the existing m010 mechanism were run and passed, confirming no unintended side effects from the new additions.
  • The author has indicated that a review of SPEC.md sections for accuracy against source material and validation of JSON schema coverage against SPEC.md state machine are pending.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive specification for the m009 Service Provision Escrow mechanism, including detailed documentation, JSON schemas, and a reference implementation. However, a critical security vulnerability has been identified: the milestone review scoring's confidence calculation incorrectly treats missing or undefined signals as available, potentially leading to inflated scores and incorrect approval recommendations for escrowed funds. Additionally, there are critical issues within the specification's token flow logic for dispute resolution and inconsistencies between the specification, reference implementation, and test data regarding state transitions, data type definitions, and KPI calculations. Several comments have been enhanced with references to established repository rules regarding transition logic, state definitions, and data structure alignment.

| Outcome | Client receives | Provider receives | Community pool |
|---------|----------------|-------------------|----------------|
| **CLIENT_WINS** | remaining escrow − arbiter_fee | 0 (bond slashed: 50% client, 50% pool) | 50% of bond + arbiter_fee |
| **PROVIDER_WINS** | 0 | remaining escrow + bond − arbiter_fee | arbiter_fee |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The token flow for a PROVIDER_WINS dispute outcome appears to be incorrect and could lead to significant fund mismanagement. It states the provider receives remaining escrow + bond - arbiter_fee.

The term "remaining escrow" is ambiguous. If it refers to the entire remaining balance in the escrow contract (including funds for future, uncompleted milestones), this is a critical flaw. A provider winning a dispute on a single milestone should only be entitled to that milestone's payment, not the entire remaining contract value.

Please clarify that the payment is limited to the disputed milestone's amount. The disposition of funds for future milestones and the provider bond should also be specified based on whether the agreement continues or is terminated.

References
  1. 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.

|---------|----------------|-------------------|----------------|
| **CLIENT_WINS** | remaining escrow − arbiter_fee | 0 (bond slashed: 50% client, 50% pool) | 50% of bond + arbiter_fee |
| **PROVIDER_WINS** | 0 | remaining escrow + bond − arbiter_fee | arbiter_fee |
| **SPLIT(X%)** | X% of remaining − arbiter_fee share | (100−X)% of remaining + bond − arbiter_fee share | arbiter_fee |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Similar to the PROVIDER_WINS case, the token flow for a SPLIT(X%) resolution is ambiguous and potentially incorrect. It refers to splitting the "remaining" escrow, which is problematic.

The split should apply to the value of the disputed milestone, not the entire remaining escrow for the contract. Please clarify the specification to prevent incorrect implementation where a split on one milestone could incorrectly distribute funds for future, un-started work.

References
  1. 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.

"review_score": null
}
],
"status": "RESOLVED",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The status of agreement agr-d03 is RESOLVED, which appears to be inconsistent with the state machine defined in SPEC.md.

According to the spec (section 6), a RESOLVED state where the provider wins (PROVIDER_WINS) and there are remaining milestones should transition to IN_PROGRESS. Since this agreement has a pending milestone, its status should likely be IN_PROGRESS rather than RESOLVED, which is a transient state.

Please update the test data to align with the specified state machine transitions.

References
  1. 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.

Comment on lines +43 to +47
const cancelled_funded = agrs.filter(a => a.status === "CANCELLED" && a.escrow_amount)
.map(a => parseInt(a.escrow_amount?.amount ?? "0", 10));
const completion_fees = Math.round(total_released * 0.01);
const cancellation_fees = Math.round(cancelled_funded.reduce((s, e) => s + e, 0) * 0.02);
const total_fees = completion_fees + cancellation_fees;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The logic for calculating cancellation fees is based on a flawed assumption. It identifies agreements for fee calculation using a.status === "CANCELLED" && a.escrow_amount. However, the specification allows for fee-free cancellations from the PROPOSED state, and the sample data (v0_sample.json, agr-005) shows that PROPOSED agreements can have an escrow_amount.

This implementation cannot distinguish between a fee-incurring cancellation from FUNDED and a fee-free cancellation from PROPOSED, which will lead to incorrect KPI calculations.

The underlying data model should be enhanced to provide the necessary state history to make this distinction. Without changes to the data model, this calculation will remain inaccurate.

References
  1. 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.

Comment on lines +69 to +71
if (factors.iri_resolvable !== false) available++;
if (factors.has_prior_milestones) available++;
if (factors.spec_available !== false) available++;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The computeConfidence function contains a logic flaw where iri_resolvable and spec_available are checked using !== false. This means that if these properties are missing or undefined in the factors object, they will be incorrectly counted as 'available'. This vulnerability can lead to an inflated confidence score and potentially result in an APPROVE recommendation for a milestone lacking critical verification data, leading to the improper release of escrowed funds. It is recommended to use explicit true checks for these factors to ensure consistent and secure signal availability assessment.

  if (factors.iri_resolvable === true) available++;
  if (factors.has_prior_milestones) available++;
  if (factors.spec_available === true) available++;

Comment on lines +96 to +100
| Condition | Recommendation |
|-----------|---------------|
| `score >= 700 AND confidence >= 750` | APPROVE |
| `score >= 400 AND score < 700` | NEEDS_REVISION |
| `score < 400 OR confidence < 250` | FLAG_FOR_CLIENT |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The recommendation logic defined in this table is incomplete. There is a gap in the conditions. For example, a case where score = 800 and confidence = 500 does not match any of the specified conditions, leading to an undefined recommendation.

The reference implementation (m009_score.js) handles this by defaulting to NEEDS_REVISION, which is a reasonable approach. The specification should be updated to reflect this behavior for clarity and completeness. I suggest restructuring the conditions to be exhaustive, for example:

Condition Recommendation
score >= 700 AND confidence >= 750 APPROVE
score < 400 OR confidence < 250 FLAG_FOR_CLIENT
Otherwise NEEDS_REVISION
References
  1. 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.

"enum": ["PENDING", "IN_PROGRESS", "SUBMITTED", "APPROVED", "DISPUTED", "REVISED"]
},
"deliverable_iri": { "type": ["string", "null"] },
"review_score": { "type": ["number", "null"] }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The schema defines review_score as type number, which allows for floating-point values. However, the SPEC.md and the reference implementation both define and calculate the score as an integer (via Math.round).

To maintain consistency and enforce the correct data type, please change the type to integer.

Suggested change
"review_score": { "type": ["number", "null"] }
"review_score": { "type": ["integer", "null"] }
References
  1. When defining data structures or type definitions, ensure they are aligned with the project's central data standards repository (regen-data-standards) to maintain coherence.

…fixture state, KPI fees

- computeConfidence: use explicit === true checks to prevent undefined
  being treated as available (security fix)
- SPEC.md dispute resolutions: clarify "remaining" means disputed
  milestone amount, not entire contract escrow
- SPEC.md recommendation table: make conditions exhaustive with
  "Otherwise → NEEDS_REVISION" fallthrough
- v0_dispute_sample.json: agr-d03 status RESOLVED → IN_PROGRESS
  (provider wins with remaining milestones continues agreement)
- m009_kpi.js: respect cancelled_from field to distinguish PROPOSED
  vs FUNDED cancellations for fee calculation
- schema.json: review_score type number → integer (matches Math.round)

Fixes Gemini review on PR regen-network#21.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant