Skip to content

Simplify PIP-01 escrow descriptor - #17

Draft
okjodom wants to merge 5 commits into
mainfrom
agent/simplify-pip01
Draft

Simplify PIP-01 escrow descriptor#17
okjodom wants to merge 5 commits into
mainfrom
agent/simplify-pip01

Conversation

@okjodom

@okjodom okjodom commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Simplify PIP-01 into a compact escrow interop descriptor.
  • Make service.schema the only service-related descriptor object.
  • Replace named funding models with funding_threshold / participant_count cardinality.
  • Remove descriptor-level release_rules and field-prescriptive subtype lists.
  • Keep service behavior in OpenAPI/AsyncAPI schemas, swap lifecycle in PIP-02, and dispute/timeout policy in PIP-03.

Validation

  • git diff --check
  • targeted stale-reference searches for removed PIP-01 service fields, subtype field lists, and release_rules

@okjodom
okjodom marked this pull request as ready for review August 11, 2026 13:07
Copilot AI lite review requested due to automatic review settings August 11, 2026 13:07
@okjodom

okjodom commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Implementation impact from checking current standalone escrow/client surfaces:

PR #17 changes PIP-01 from a descriptor-defined standalone service interface into a descriptor-level schema pointer. That is a cleaner boundary, but it is a real compatibility change for anything already consuming the old service object.

The currently deployed standalone descriptor at https://standalone-escrow.onrender.com/pontmore/v1/descriptor still publishes the old service shape:

"service": {
  "transport": ["https"],
  "interface": "pontmore_escrow_http_v1",
  "endpoint": "https://standalone-escrow.onrender.com/pontmore/v1",
  "schema_url": "https://standalone-escrow.onrender.com/pontmore/v1/openapi/v1.0.0.json",
  "auth": ["nostr_http_auth"],
  "operations": ["create", "funding_instructions", "fund_status", "release", "refund", "cancel"],
  "funding_model": ["single_funder", "two_party", "m_of_n"],
  "release_decisions": ["mutual_consent", "operator_decision", "application_signed_result"]
}

Under this PR, that should move toward:

"service": {
  "schema": {
    "type": "openapi",
    "url": "https://standalone-escrow.onrender.com/pontmore/v1/openapi/v1.0.0.json"
  }
}

The deployed OpenAPI document already carries most of the behavior that PR #17 moves out of PIP-01: server URL, NIP-98 auth, operation paths, request/response schemas, state machine extension, idempotency, funding model details, release decision details, and timeout metadata. A follow-up should update schema wording that still says values come from descriptor service.funding_model / descriptor service.release_decisions, because those are no longer descriptor fields after this change.

Rollpot is directly affected. It currently derives the endpoint from descriptor.service.endpoint, infers two-party support from descriptor.service.funding_model, and calls endpoint/{operation} directly. After this PR, it should fetch and validate service.schema.url, read the OpenAPI servers, paths, security schemes, and extension metadata, then use the discovered service contract.

Suggested migration sequence:

  1. Update descriptor producers to emit service.schema.type and service.schema.url while optionally retaining old fields during a transition window.
  2. Make the OpenAPI schema the complete source for endpoint, auth, operations, funding models, release decisions, idempotency, and timeout fallback.
  3. Update clients to discover service details from the referenced OpenAPI/AsyncAPI schema instead of descriptor-level service fields.
  4. Keep backward-compatible parsing for already-published descriptors until descriptors in the wild have been republished.

This PR is directionally consistent with the public/private boundary: PIP-01 becomes compatibility and schema discovery, while service mechanics live in the referenced schema.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the Pontmore protocol specs to make PIP-01 a compact “escrow interop descriptor” focused on discovery/compatibility and optional service schema discovery, while pushing detailed service behavior into referenced OpenAPI/AsyncAPI schemas and keeping lifecycle/policy rules in PIP-02/PIP-03.

Changes:

  • Simplifies PIP-01 by removing descriptor-level standalone service interface details and making service.schema the only service-related descriptor object.
  • Replaces named funding models with funding_rules.funding_threshold / funding_rules.participant_count cardinality.
  • Updates cross-document phrasing/links in README and PIP-03 to reflect the new PIP-01 scope.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
README.md Updates repository-level description of PIP-01 and the baseline scope to emphasize “escrow descriptor surface” and “service schema discovery”.
PIP-01-escrow-descriptor.md Major simplification of the descriptor: narrows service metadata to service.schema, introduces funding cardinality, and removes prior field-prescriptive subtype/service interface content.
PIP-03-dispute-policy.md Adds/adjusts references to PIP-01 and updates timeout-fallback wording to reflect descriptor-or-schema declaration.
Suppressed comments (2)

PIP-01-escrow-descriptor.md:179

  • dispute_rules is a required minimum-content field, but this section never defines what keys it must contain. The example includes policy and timeout_fallback, yet neither is specified here, and timeout_fallback: "operator_decision" doesn’t match any resolution-mode vocabulary in PIP-03. Define the required/optional fields for dispute_rules and how any fallback value should map to PIP-03 so clients can validate compatibility consistently.
`dispute_rules` declares descriptor-level compatibility facts about the applicable dispute policy.

PIP-01 does not define release, refund, cancellation, or partial-outcome semantics. For Pontmore swaps, public release and dispute lifecycle behavior is defined by [PIP-02-swap-state-machine.md](./PIP-02-swap-state-machine.md) and [PIP-03-dispute-policy.md](./PIP-03-dispute-policy.md). For service use, release and refund behavior belongs to the referenced service schema.

Timeout and refund fallback metadata advertised by an escrow descriptor MUST be compatible with [PIP-03-dispute-policy.md](./PIP-03-dispute-policy.md). PIP-03 is the source of truth for timeout classes and fallback resolution policy.

PIP-01-escrow-descriptor.md:210

  • The descriptor example uses timeout_fallback: "operator_decision", but PIP-03’s Resolution Modes are described in different terms (e.g., "escalating to manual review"). If timeout_fallback is intended to be machine-validated against PIP-03, the example should use a value that matches PIP-03’s resolution-mode vocabulary (or omit the field and require the mapping to live in the referenced service schema).
  "dispute_rules": {
    "policy": "operator_resolved",
    "timeout_fallback": "operator_decision"
  },

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +156 to +160
`funding_rules` declares descriptor-level compatibility facts about how an escrow expects funding to be satisfied.

```text
["d", "default"]
["network", "bitcoin"]
["network", "lightning"]
```
Escrow funding is described as an `m of n` requirement.

## Canonical Subtype: `lightning_hold_invoice`
- `funding_rules.funding_threshold` is `m`: the minimum number of declared funding participants whose funding must be confirmed before the escrow is considered funded
Comment thread PIP-03-dispute-policy.md
### Timeout Fallback

A timeout class (for example `resolution timeout` or an escrow's `refund_trigger` such as `timeout_requires_mutual_consent`) MUST NOT leave the escrow in a permanent deadlock where neither participant will consent and no other resolution path is defined. When a timeout elapses, the operator MUST resolve the swap using the fallback resolution bound to that timeout class; a `mutual_consent`-only path with no fallback is not a valid terminal policy. The escrow descriptor referenced by the swap MUST declare the applicable fallback resolution for every timeout class it advertises, and compatibility validation MUST use that explicit binding rather than inferring a fallback from the trigger name alone (see the Refund-Trigger Fallback section of [PIP-01-escrow-descriptor.md](./PIP-01-escrow-descriptor.md)).
A timeout class (for example `resolution timeout` or an escrow's `refund_trigger` such as `timeout_requires_mutual_consent`) MUST NOT leave the escrow in a permanent deadlock where neither participant will consent and no other resolution path is defined. When a timeout elapses, the operator MUST resolve the swap using the fallback resolution bound to that timeout class; a `mutual_consent`-only path with no fallback is not a valid terminal policy. The escrow descriptor or referenced service schema MUST declare the applicable fallback resolution for every timeout class it advertises, and compatibility validation MUST use that explicit binding rather than inferring a fallback from the trigger name alone (see [PIP-01-escrow-descriptor.md](./PIP-01-escrow-descriptor.md)).
@okjodom
okjodom marked this pull request as draft August 11, 2026 13:17
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.

2 participants