Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion trustless-work-dev/skills/api/multi-release-escrow.md
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ export const approveMilestone = async (

**Endpoint:** `POST /escrow/multi-release/change-milestone-status`

Service Provider updates the status and evidence of a milestone.
Service Provider updates the status and evidence of a milestone. Rejected for a milestone that is released or resolved (`MilestoneAlreadyReleased`/`MilestoneAlreadyResolved`); still allowed while that milestone's dispute is open. (Contract lineage from 2026-09-15 onward.)

### Request Schema

Expand Down
2 changes: 1 addition & 1 deletion trustless-work-dev/skills/api/single-release-escrow.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ export const fundEscrow = async (contractId: string, amount: number) => {

**Endpoint:** `POST /escrow/single-release/change-milestone-status`

Service Provider updates the status and evidence of a milestone.
Service Provider updates the status and evidence of a milestone. Rejected once the escrow is released or resolved (`EscrowAlreadyReleased`/`EscrowAlreadyResolved`); still allowed while a dispute is open. (Contract lineage from 2026-09-15 onward.)

### Request Schema

Expand Down
2 changes: 1 addition & 1 deletion trustless-work-dev/skills/api/v2/multi-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ A new milestone's `receiver` must not be the `admin` or any `disputeResolver`. T
}
```

Same rules as single-release: `newStatus` max 50 chars, `newEvidence` optional, max 500.
Same rules as single-release: `newStatus` max 50 chars, `newEvidence` optional, max 500. Updates are **rejected for a milestone that is `released` or has its dispute `resolved`** (`MilestoneAlreadyReleased` = 16 / `MilestoneAlreadyResolved` = 17); they stay allowed while that milestone's dispute is open.

## Approve milestones

Expand Down
2 changes: 1 addition & 1 deletion trustless-work-dev/skills/api/v2/single-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Appends new milestones and edits existing descriptions (`newDescription` max 500
}
```

Batched. Status is free text (max 50 chars) and moves no funds; convention is `pending → in_progress → completed`. `newEvidence` is optional, max 500 chars.
Batched. Status is free text (max 50 chars) and moves no funds; convention is `pending → in_progress → completed`. `newEvidence` is optional, max 500 chars. Updates are **rejected once the escrow is `released` or its dispute `resolved`** (`EscrowAlreadyReleased` = 16 / `EscrowAlreadyResolved` = 17); they stay allowed while a dispute is open.

## Approve milestones

Expand Down
2 changes: 1 addition & 1 deletion trustless-work-dev/skills/protocol/v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Actors without a role slot:
- **Before funding — Multi Release:** the platform may update escrow properties subject to the validator; existing milestone flags must be preserved, and any newly appended milestone must start with all milestone flags false.
- **After funding — both V1 types:** existing escrow properties and existing milestones are frozen. The only permitted structural change is appending new milestones that satisfy the initial/unset flag requirements. **Existing approved milestones do not by themselves prevent appending new milestones** as long as the funded escrow's existing state is preserved.

4. **[ENFORCED]** Completion ≠ approval: the `serviceProvider` marking a milestone complete moves no funds. Only the `approver` role assignment's separate approval satisfies the approval precondition.
4. **[ENFORCED]** Completion ≠ approval: the `serviceProvider` marking a milestone complete moves no funds. Only the `approver` role assignment's separate approval satisfies the approval precondition. Status/evidence updates stay allowed while a dispute is open (fresh evidence can help resolve it) but are rejected once the state is terminal — single-release: escrow `released`/`resolved` (`EscrowAlreadyReleased`/`EscrowAlreadyResolved`); multi-release: that milestone `released`/`resolved` (`MilestoneAlreadyReleased`/`MilestoneAlreadyResolved`). Added to the V1 lineage on 2026-09-15 (commits `22a0b23` single / `887182a` multi); deployments predating them still accept these updates.

5. **[ENFORCED]** Single-release: **all** milestones must be approved and no dispute active before `release-funds`; the contract then pays out the **configured escrow amount** minus fees in one payment (release requires the contract balance to cover it — payouts are computed from `escrow.amount`, not from arbitrary excess balance).

Expand Down
5 changes: 5 additions & 0 deletions trustless-work-dev/skills/protocol/v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ Beyond the V1 set, V2 adds:
- **Appending** new milestones stays allowed after funding, until the escrow is released, disputed or resolved. Only edits to existing milestones and property updates are blocked.
- All of it is `admin`-only, updates are also rejected while a dispute is open, and `admin` and `platform` are immutable from initialization. Role mistakes are not recoverable after funding.

**[ENFORCED] Milestone status/evidence lifecycle.** A service provider may update a milestone's `status`/`evidence` **while a dispute is open** — fresh evidence is deliberately allowed because it can help resolve the dispute — but updates are rejected once the state is terminal:

- Single-release rejects when the **escrow** is `released` or its dispute `resolved` (`MilestoneError::EscrowAlreadyReleased` = 16 / `EscrowAlreadyResolved` = 17).
- Multi-release rejects per **milestone** once it is `released` or its dispute `resolved` (`MilestoneError::MilestoneAlreadyReleased` = 16 / `MilestoneAlreadyResolved` = 17).

**[ENFORCED] `withdraw-remaining-funds`** narrows the V1 precondition. "Fully processed" in V2 means:

- **Single Release:** `released || dispute.resolved`.
Expand Down
Loading