@agentplat/mesh-protocol 0.3.0-alpha.1 → 0.3.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +294 -1
- package/dist/contracts.d.ts +335 -2
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/validation.d.ts +1 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +1654 -16
- package/dist/validation.js.map +1 -1
- package/fixtures/v0/README.md +6 -2
- package/fixtures/v0/capability-advertise.json +35 -0
- package/fixtures/v0/capability-withdraw.json +26 -0
- package/fixtures/v0/lease-certificate.json +29 -0
- package/fixtures/v0/lease-renew.json +41 -0
- package/fixtures/v0/lease-takeover-proposal.json +46 -0
- package/fixtures/v0/lease-vote.json +28 -0
- package/fixtures/v0/objective-announce.json +43 -0
- package/fixtures/v0/objective-cancel.json +28 -0
- package/fixtures/v0/objective-revise.json +44 -0
- package/fixtures/v0/peer-card.json +31 -0
- package/fixtures/v0/peer-goodbye.json +26 -0
- package/fixtures/v0/work-accept.json +38 -0
- package/fixtures/v0/work-award.json +46 -0
- package/fixtures/v0/work-bid.json +46 -0
- package/fixtures/v0/work-cancel.json +40 -0
- package/fixtures/v0/work-checkpoint.json +42 -0
- package/fixtures/v0/work-decline.json +38 -0
- package/fixtures/v0/work-offer.json +39 -0
- package/fixtures/v0/work-progress.json +41 -0
- package/fixtures/v0/work-release.json +41 -0
- package/fixtures/v0/work-result.json +42 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,12 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
Closed, bounded and transport-neutral wire contracts for AgentPlat Mesh peers.
|
|
4
4
|
|
|
5
|
-
The
|
|
5
|
+
The implementation provides:
|
|
6
6
|
|
|
7
7
|
- strict UTF-8 and JSON parsing that rejects duplicate decoded keys, malformed
|
|
8
8
|
Unicode, ambiguous syntax and documents outside explicit structural limits;
|
|
9
9
|
- deterministic JSON canonicalization for hashing and signing;
|
|
10
10
|
- closed-schema validation for `peer.hello`, `peer.ping` and `peer.ping_ack`;
|
|
11
|
+
- closed, bounded Alpha 2 discovery and capability records for `peer.card`,
|
|
12
|
+
`peer.goodbye`, `capability.advertise` and `capability.withdraw`;
|
|
13
|
+
- closed, bounded Alpha 2 Objective records for `objective.announce`,
|
|
14
|
+
`objective.revise` and `objective.cancel`;
|
|
15
|
+
- closed, bounded Alpha 2 Work Offer and Work Bid records for `work.offer` and
|
|
16
|
+
`work.bid`;
|
|
17
|
+
- closed, bounded Alpha 2 award-response records for `work.award`,
|
|
18
|
+
`work.accept` and `work.decline`;
|
|
19
|
+
- closed, bounded Alpha 2 execution records for `work.progress`,
|
|
20
|
+
`work.checkpoint` and `work.result`;
|
|
21
|
+
- closed, bounded Alpha 2 Work Release and Work Cancel records for
|
|
22
|
+
`work.release` and `work.cancel`;
|
|
23
|
+
- a closed, bounded Alpha 2 Lease Renewal record for `lease.renew`;
|
|
24
|
+
- a closed, bounded Alpha 2 Lease Takeover Proposal record for
|
|
25
|
+
`lease.takeover_proposal`;
|
|
11
26
|
- exact representations for message IDs, SHA-256 payload digests and Ed25519
|
|
12
27
|
proofs;
|
|
13
28
|
- receiver-context checks for tenant and Mesh scope, audience, freshness and
|
|
@@ -31,5 +46,283 @@ keys, verify signatures, perform replay admission, or mutate peer state. Those
|
|
|
31
46
|
are separate stages so callers cannot confuse structural validity with
|
|
32
47
|
cryptographic authenticity or local acceptance.
|
|
33
48
|
|
|
49
|
+
Evidence, trust and peer-sync message families remain reserved until their
|
|
50
|
+
closed payload contracts are implemented. They fail explicitly rather than
|
|
51
|
+
entering a generic payload path. Implemented Objective, Work, Lease Renewal,
|
|
52
|
+
Lease Takeover Proposal, Lease Vote and Lease Certificate records parse, sign
|
|
53
|
+
and verify structurally, but remain explicitly unsupported at the Mesh runtime
|
|
54
|
+
boundary until their reducers and state authorization are implemented.
|
|
55
|
+
|
|
56
|
+
## Frozen limits
|
|
57
|
+
|
|
58
|
+
Protocol v0 applies these structural limits before a payload can enter a
|
|
59
|
+
reducer:
|
|
60
|
+
|
|
61
|
+
| Limit | Maximum |
|
|
62
|
+
| -------------------------------------- | ------------------: |
|
|
63
|
+
| Decompressed envelope | 262,144 UTF-8 bytes |
|
|
64
|
+
| Payload | 196,608 UTF-8 bytes |
|
|
65
|
+
| Nesting depth | 32 |
|
|
66
|
+
| Total object keys / keys in one object | 2,048 / 256 |
|
|
67
|
+
| Total array items / items in one array | 4,096 / 1,024 |
|
|
68
|
+
| One string | 65,536 UTF-8 bytes |
|
|
69
|
+
| Extensions / critical extensions | 16 / 8 |
|
|
70
|
+
| Identifier | 256 UTF-8 bytes |
|
|
71
|
+
| Envelope lifetime | 10 minutes |
|
|
72
|
+
| Clock-skew allowance | 2 minutes |
|
|
73
|
+
| Replay window | 2,048 sequences |
|
|
74
|
+
|
|
75
|
+
The implemented Alpha 2 discovery and capability payloads additionally freeze
|
|
76
|
+
these narrower limits:
|
|
77
|
+
|
|
78
|
+
| Field | Rule |
|
|
79
|
+
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
80
|
+
| `protocolVersions` | 1–8 sorted unique non-negative safe integers and must include `0` |
|
|
81
|
+
| Peer Card transport hints | At most 8 sorted unique non-empty strings; 2,048 UTF-8 bytes each and 8,192 bytes in aggregate |
|
|
82
|
+
| Peer Card capability IDs | At most 32 sorted unique identifiers |
|
|
83
|
+
| Capability key | Non-empty; at most 4,096 UTF-8 bytes |
|
|
84
|
+
| Capability version and optional variant | Non-empty; at most 128 UTF-8 bytes each |
|
|
85
|
+
| Input or output media types | At most 16 sorted unique non-empty strings per collection; 128 UTF-8 bytes each |
|
|
86
|
+
| Capability attributes | At most 32 entries; non-empty keys up to 128 UTF-8 bytes, non-empty values up to 1,024 bytes, and 16,384 bytes in aggregate |
|
|
87
|
+
| Peer Card or capability-advertisement validity | Greater than zero and at most exactly 24 hours |
|
|
88
|
+
|
|
89
|
+
Every collection marked sorted and unique uses ascending lexicographic order
|
|
90
|
+
over UTF-16 code units, matching the JCS/RFC 8785 property-name ordering rule.
|
|
91
|
+
This is intentionally not Unicode code-point order; duplicate adjacent values
|
|
92
|
+
are rejected.
|
|
93
|
+
|
|
94
|
+
Envelope TTL is 30 seconds for `peer.ping` and `peer.ping_ack`, 60 seconds for
|
|
95
|
+
`peer.goodbye`, and 120 seconds for `peer.hello`, `peer.card`,
|
|
96
|
+
`capability.advertise` and `capability.withdraw`. These family limits are also
|
|
97
|
+
bounded by the global ten-minute maximum.
|
|
98
|
+
|
|
99
|
+
Work Release and Work Cancel envelopes have a two-minute TTL. Release is a
|
|
100
|
+
closed `owner`/`assignee` authority and `reoffer`/`close` disposition pair;
|
|
101
|
+
assignee release must be sent before its declared lease expiry. Cancel is a
|
|
102
|
+
closed `award_pending` branch without `acceptanceId` or `active` branch with
|
|
103
|
+
one. These are structural limits only; local state determines recipients,
|
|
104
|
+
authority, terminality, idempotency and accounting.
|
|
105
|
+
|
|
106
|
+
Lease Renewal envelopes have a 30-second TTL and must expire no later than the
|
|
107
|
+
currently declared lease. A renewal self-binds the assignee, requires direct
|
|
108
|
+
delivery and extends the declared expiry by a positive duration of at most 24
|
|
109
|
+
hours. The accepted Objective may impose a lower duration and renewal count.
|
|
110
|
+
|
|
111
|
+
Lease Takeover Proposal envelopes have a one-minute TTL. They require one direct
|
|
112
|
+
peer audience, mandatory causation and Objective-header equality. The trusted
|
|
113
|
+
receiver clock and accepted Objective policy—not sender-declared time—determine
|
|
114
|
+
whether lease expiry plus recovery grace has elapsed.
|
|
115
|
+
|
|
116
|
+
Lease Vote envelopes also have a one-minute TTL. They self-bind the witness,
|
|
117
|
+
require direct delivery and Objective-header equality, and causally name the
|
|
118
|
+
accepted takeover proposal they endorse. Witness membership and vote
|
|
119
|
+
uniqueness require accepted local state.
|
|
120
|
+
|
|
121
|
+
Lease Certificate envelopes have a one-minute TTL and self-bind their
|
|
122
|
+
assembler. They carry between two and 32 sorted unique vote IDs, require direct
|
|
123
|
+
delivery, Objective-header equality and proposal causation. The accepted
|
|
124
|
+
Objective determines the actual threshold.
|
|
125
|
+
|
|
126
|
+
Alpha 2 domain-limit, ordering, validity, self-binding and predecessor
|
|
127
|
+
violations return `invalid_payload`. Envelope lifetime violations return
|
|
128
|
+
`invalid_lifetime`; generic parser structural-limit violations return
|
|
129
|
+
`structural_limit_exceeded`.
|
|
130
|
+
|
|
131
|
+
## Objective limits
|
|
132
|
+
|
|
133
|
+
Objective documents are complete replacements: announce is revision 1 with no
|
|
134
|
+
envelope causation ID; revise is revision 2 or greater, names a different
|
|
135
|
+
`previousObjectiveDocumentId`, and requires envelope `causationId`; cancel names
|
|
136
|
+
the current document and revision and also requires envelope `causationId`.
|
|
137
|
+
The envelope `causationId` is a message ID, not a substitute for the payload's
|
|
138
|
+
previous-document ID. All three messages require an envelope `objectiveId` that
|
|
139
|
+
exactly matches the payload. Document issuers must self-bind to the sender.
|
|
140
|
+
Structural acceptance of `contentReference` does not authorize retrieval;
|
|
141
|
+
issuer authority, reference authorization and current-revision checks require
|
|
142
|
+
accepted local state and remain outside the protocol parser.
|
|
143
|
+
|
|
144
|
+
| Field | Rule |
|
|
145
|
+
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
146
|
+
| Summary or content reference | Exactly one non-empty representation; each at most 4,096 UTF-8 bytes |
|
|
147
|
+
| Success criteria | 1–32 non-empty strings, 4,096 UTF-8 bytes each and 16,384 bytes in aggregate |
|
|
148
|
+
| Permitted capability keys | 1–32 sorted unique non-empty strings, 4,096 UTF-8 bytes each |
|
|
149
|
+
| Work / concurrency | Work items 1–1,000,000; concurrency 1 through work-item maximum |
|
|
150
|
+
| Budget units | Non-negative safe integer |
|
|
151
|
+
| Timers | Bid window at most 1 hour; acceptance at most 15 minutes; lease at most 24 hours; recovery grace at most 1 hour; each must fit within validity |
|
|
152
|
+
| Lease renewals | Safe integer 0–100 |
|
|
153
|
+
| Recovery witnesses | 3–32 sorted unique identifiers and strict-majority threshold |
|
|
154
|
+
| Authorized observers | Optional, at most 32 sorted unique identifiers |
|
|
155
|
+
| Objective validity | Greater than zero and at most exactly 30 days |
|
|
156
|
+
|
|
157
|
+
Objective announce and revise have a five-minute envelope TTL; cancel has a
|
|
158
|
+
two-minute TTL. Objective scope, binding, closure, ordering, revision,
|
|
159
|
+
causation, timer and limit violations reject with `invalid_payload`; their TTL
|
|
160
|
+
violations reject with `invalid_lifetime`.
|
|
161
|
+
|
|
162
|
+
## Work Offer and Bid limits
|
|
163
|
+
|
|
164
|
+
Work Offers name an immutable Objective document and work-item revision. The
|
|
165
|
+
first attempt has no predecessor or envelope causation; later attempts require
|
|
166
|
+
both and must name a different `previousOfferId`. Offers self-bind their owner
|
|
167
|
+
to the envelope sender and may target one peer or the `work` topic. Work Bids
|
|
168
|
+
name one Offer, self-bind their bidder to the sender, require causation, and
|
|
169
|
+
must be addressed directly to the named owner. Bid revision 1 has no predecessor;
|
|
170
|
+
later revisions require a different `previousBidId`.
|
|
171
|
+
|
|
172
|
+
| Field | Rule |
|
|
173
|
+
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
174
|
+
| Required capability keys | 1–32 sorted unique non-empty strings, at most 4,096 UTF-8 bytes each |
|
|
175
|
+
| Matching attributes | At most 32 entries; non-empty keys up to 128 UTF-8 bytes, non-empty values up to 1,024 bytes, and 16,384 bytes in aggregate |
|
|
176
|
+
| Input summary or reference | Exactly one non-empty representation; each at most 4,096 UTF-8 bytes |
|
|
177
|
+
| Completion criteria | 1–32 non-empty strings, at most 4,096 UTF-8 bytes each and 16,384 bytes in aggregate |
|
|
178
|
+
| Bid assumptions | 0–32 non-empty strings, at most 4,096 UTF-8 bytes each and 16,384 bytes in aggregate |
|
|
179
|
+
| Reservation and budget units | Budget values are non-negative safe integers; capacity reservation is a safe integer from 1 through 1,000,000 |
|
|
180
|
+
| Offer deadlines | `sentAt < bidDeadline < workDeadline`; bid deadline is at most 1 hour after send, work deadline at most 30 days after send, and envelope expiry must not exceed bid deadline |
|
|
181
|
+
| Bid deadlines | `sentAt < bidExpiresAt <= bidDeadline < expectedCompletionAt <= workDeadline`; the same one-hour bid and 30-day work horizons apply, and envelope expiry must not exceed bid expiry |
|
|
182
|
+
|
|
183
|
+
Offer and Bid envelope TTL is two minutes. Structural validation does not decide
|
|
184
|
+
whether an Objective revision is current, a Work Item is current, an offer
|
|
185
|
+
attempt supersedes another offer, a capability advertisement is accepted, a
|
|
186
|
+
bid has capacity or budget authority, or deadlines and reservations are valid
|
|
187
|
+
against accepted local state. Those checks require reducer authorization state
|
|
188
|
+
and remain deferred.
|
|
189
|
+
|
|
190
|
+
## Work Award, Accept and Decline limits
|
|
191
|
+
|
|
192
|
+
An Award names one Offer and selected Bid and self-binds the owner sender. Any
|
|
193
|
+
direct peer audience is structurally valid; whether it is the assignee or a
|
|
194
|
+
witness is a local-state check. It carries an assignment epoch,
|
|
195
|
+
assignment-authority ID and fencing token. The normal `authorityKind: "award"`
|
|
196
|
+
branch requires both IDs to equal `awardId` and forbids recovery references. The
|
|
197
|
+
`authorityKind: "recovery_certificate"` branch requires `recoveryCertificateId`
|
|
198
|
+
and requires both IDs to equal that certificate; an optional resume checkpoint
|
|
199
|
+
is structural metadata only.
|
|
200
|
+
|
|
201
|
+
Accept and Decline each name the Award and self-bind the assignee sender.
|
|
202
|
+
Accept accepts any direct peer audience structurally; owner-or-witness
|
|
203
|
+
authorization is stateful. Decline is structurally directed to the owner. Both
|
|
204
|
+
require an envelope causation ID. Resolving Award causation to the selected Bid
|
|
205
|
+
envelope, and response causation to the accepted Award envelope, requires the
|
|
206
|
+
local causal journal and is stateful. All three records bind the envelope
|
|
207
|
+
Objective ID to the payload Objective ID.
|
|
208
|
+
|
|
209
|
+
| Field | Rule |
|
|
210
|
+
| ---------------- | ------------------------------------------------------------------------------------------ |
|
|
211
|
+
| Owner epoch | Positive safe integer; frozen at `1` for this protocol slice |
|
|
212
|
+
| Assignment epoch | Positive safe integer; recovery authority requires epoch `2` or greater |
|
|
213
|
+
| Award time order | `sentAt <= leaseStartsAt < acceptanceDeadline <= leaseExpiresAt <= workDeadline` |
|
|
214
|
+
| Award windows | Acceptance window at most 15 minutes; lease at most 24 hours; work horizon at most 30 days |
|
|
215
|
+
| Award expiry | At most two minutes and no later than `acceptanceDeadline` |
|
|
216
|
+
| Response time | `sentAt < acceptanceDeadline`; expiry at most two minutes and no later than that deadline |
|
|
217
|
+
|
|
218
|
+
These are structural contracts only. Selection of a current bid, current owner
|
|
219
|
+
and revision, budget reservation, acceptance uniqueness, deadline observation,
|
|
220
|
+
causal-reference resolution, and recovery-certificate acceptance all require
|
|
221
|
+
local state and remain deferred.
|
|
222
|
+
|
|
223
|
+
## Work Progress, Checkpoint and Result limits
|
|
224
|
+
|
|
225
|
+
Execution records self-bind the assignee sender, require a direct peer audience
|
|
226
|
+
and causation, and bind Objective and Work Item revisions, accepted assignment
|
|
227
|
+
IDs, epoch, authority token and lease expiry. Each record has a stable domain
|
|
228
|
+
ID independent of the envelope message ID.
|
|
229
|
+
|
|
230
|
+
| Field | Rule |
|
|
231
|
+
| ------------------ | ----------------------------------------------------------------------------------------------- |
|
|
232
|
+
| Owner epoch | Positive safe integer; frozen at `1` for this protocol slice |
|
|
233
|
+
| Assignment binding | Positive epoch; `assignmentAuthorityId` and `fencingToken` must be identical identifiers |
|
|
234
|
+
| Progress | Positive sequence and non-empty summary of at most 4,096 UTF-8 bytes; checkpoint ID is optional |
|
|
235
|
+
| Checkpoint | Positive sequence, canonical SHA-256 digest and exactly one summary or reference |
|
|
236
|
+
| Checkpoint parent | Sequence `1` omits a parent; later sequences require a different `previousCheckpointId` |
|
|
237
|
+
| Result | Canonical SHA-256 digest, optional checkpoint ID and exactly one summary or reference |
|
|
238
|
+
| Content | Summaries and references are non-empty and at most 4,096 UTF-8 bytes |
|
|
239
|
+
| Execution expiry | At most five minutes, strictly after `sentAt` and no later than the signed `leaseExpiresAt` |
|
|
240
|
+
|
|
241
|
+
The structural parser does not prove that causation resolves to the matching
|
|
242
|
+
accepted `work.accept`, that the recipient is an authorized owner, observer or
|
|
243
|
+
witness, or that the assignment, epoch, authority, token, lease and checkpoint
|
|
244
|
+
head are current. It also does not enforce progress ordering or result
|
|
245
|
+
uniqueness. Those checks require accepted local state and remain deferred to
|
|
246
|
+
the Mesh runtime reducer boundary.
|
|
247
|
+
|
|
248
|
+
## Lease Renewal limits
|
|
249
|
+
|
|
250
|
+
Lease Renewal carries the accepted assignment authority plus
|
|
251
|
+
`leaseRenewalId`, `leaseRenewalSequence` and `renewedLeaseExpiresAt`. The
|
|
252
|
+
existing `leaseExpiresAt` is the current lease that limits delivery; the renewed
|
|
253
|
+
timestamp is the proposed successor. Sequence `1` omits
|
|
254
|
+
`previousLeaseRenewalId`; later sequences require a different predecessor ID.
|
|
255
|
+
|
|
256
|
+
The sender self-binds to `assigneePeerId`, the audience is one direct peer, the
|
|
257
|
+
envelope Objective ID equals the payload Objective ID, and causation is
|
|
258
|
+
required. The first accepted renewal resolves causation to `work.accept`; later
|
|
259
|
+
renewals resolve it to the immediately preceding `lease.renew` envelope for
|
|
260
|
+
that recipient. Recipient authorization, exact predecessor and sequence,
|
|
261
|
+
current assignment and lease, Work deadline, Objective duration/count policy,
|
|
262
|
+
terminal state and idempotency remain stateful reducer checks.
|
|
263
|
+
|
|
264
|
+
## Lease Takeover Proposal limits
|
|
265
|
+
|
|
266
|
+
Lease Takeover Proposal carries the accepted assignment authority and current
|
|
267
|
+
lease expiry plus a stable `takeoverProposalId`. It identifies the self-bound
|
|
268
|
+
`proposerPeerId`, a closed `candidate` or `witness` `proposalAuthority`, the
|
|
269
|
+
different `proposedAssigneePeerId`, and exactly the next declared assignment
|
|
270
|
+
epoch. It does not propose a fencing token; an accepted recovery certificate's
|
|
271
|
+
stable ID becomes that token later.
|
|
272
|
+
|
|
273
|
+
`leaseRenewalSequence` is `0` for the initial accepted lease and omits
|
|
274
|
+
`latestLeaseRenewalId`. Values `1` through `100` require that stable renewal ID.
|
|
275
|
+
Causation resolves to the accepted `work.accept` for sequence `0`, or to the
|
|
276
|
+
latest accepted `lease.renew` envelope for the receiving witness.
|
|
277
|
+
|
|
278
|
+
The parser enforces closed fields, role consistency, direct delivery, mandatory
|
|
279
|
+
causation, Objective equality and the one-minute TTL. It does not establish that
|
|
280
|
+
the lease head is accepted or expired, recovery grace elapsed, the proposer and
|
|
281
|
+
candidate are eligible, the recipient is a configured witness, or the Work Item
|
|
282
|
+
is current and non-terminal. Those checks require accepted local state and a
|
|
283
|
+
trusted receiver clock. A valid proposal records recovery intent only; it does
|
|
284
|
+
not advance the epoch, grant execution authority, change fencing or reserve
|
|
285
|
+
budget.
|
|
286
|
+
|
|
287
|
+
## Lease Vote limits
|
|
288
|
+
|
|
289
|
+
Lease Vote is an affirmative witness endorsement of one accepted takeover
|
|
290
|
+
proposal. Its closed payload contains a stable `leaseVoteId`, the logical
|
|
291
|
+
`takeoverProposalId`, the self-bound `witnessPeerId` and the Objective ID. It
|
|
292
|
+
does not repeat candidate, Work Item, assignment, lease, epoch or fencing
|
|
293
|
+
fields; those are resolved from the causally accepted proposal so that two
|
|
294
|
+
signed snapshots cannot disagree.
|
|
295
|
+
|
|
296
|
+
The audience is one direct peer, the envelope Objective ID equals the payload
|
|
297
|
+
Objective ID, causation is required and TTL is at most one minute. The parser
|
|
298
|
+
does not establish that causation names the matching accepted proposal, the
|
|
299
|
+
sender belongs to its fixed witness set, the recipient is a recovery
|
|
300
|
+
participant, or the witness has not already endorsed another proposal for the
|
|
301
|
+
same Work Item revision and proposed epoch. Those are stateful reducer checks.
|
|
302
|
+
A vote alone does not advance an epoch, change fencing, grant execution
|
|
303
|
+
authority, activate a candidate or mutate budget.
|
|
304
|
+
|
|
305
|
+
## Lease Certificate limits
|
|
306
|
+
|
|
307
|
+
Lease Certificate references one accepted takeover proposal and the witness
|
|
308
|
+
votes that certify it. Its closed payload contains a stable `certificateId`,
|
|
309
|
+
the self-bound `certificateAssemblerPeerId`, `takeoverProposalId`, between two
|
|
310
|
+
and 32 sorted unique `leaseVoteIds`, and the Objective ID. It does not repeat
|
|
311
|
+
candidate, Work Item, assignment, lease, epoch or fencing fields; the accepted
|
|
312
|
+
proposal is their canonical source.
|
|
313
|
+
|
|
314
|
+
The audience is one direct peer, the envelope Objective ID equals the payload
|
|
315
|
+
Objective ID, causation names the proposal envelope and TTL is at most one
|
|
316
|
+
minute. The parser does not prove that the proposal or votes are accepted, that
|
|
317
|
+
the votes endorse the same proposal, come from distinct configured witnesses
|
|
318
|
+
or satisfy the Objective threshold, or that the assembler and recipient are
|
|
319
|
+
authorized. Those are stateful reducer checks.
|
|
320
|
+
|
|
321
|
+
After stateful acceptance, `certificateId` becomes the next assignment
|
|
322
|
+
authority ID and fencing token, and the Work Item enters recovery. The
|
|
323
|
+
certificate does not itself grant execution authority or activate the
|
|
324
|
+
candidate; that requires the existing owner-issued recovery award and
|
|
325
|
+
acceptance flow.
|
|
326
|
+
|
|
34
327
|
Importing the package performs no parsing, key resolution, network or storage
|
|
35
328
|
operation.
|
package/dist/contracts.d.ts
CHANGED
|
@@ -47,6 +47,20 @@ export interface PeerHelloPayload {
|
|
|
47
47
|
readonly peerCardId: string;
|
|
48
48
|
readonly cardRevision: number;
|
|
49
49
|
}
|
|
50
|
+
/** Publishes one bounded revision of a peer's discovery card. */
|
|
51
|
+
export interface PeerCardPayload {
|
|
52
|
+
readonly type: 'peer.card';
|
|
53
|
+
readonly peerCardId: string;
|
|
54
|
+
readonly cardRevision: number;
|
|
55
|
+
readonly subjectPeerId: string;
|
|
56
|
+
readonly instanceId: string;
|
|
57
|
+
readonly protocolVersions: readonly number[];
|
|
58
|
+
readonly transportHints: readonly string[];
|
|
59
|
+
readonly capabilityIds: readonly string[];
|
|
60
|
+
readonly validFrom: string;
|
|
61
|
+
readonly validUntil: string;
|
|
62
|
+
readonly previousPeerCardId?: string;
|
|
63
|
+
}
|
|
50
64
|
/** Requests a direct liveness response from the audience peer. */
|
|
51
65
|
export interface PeerPingPayload {
|
|
52
66
|
readonly type: 'peer.ping';
|
|
@@ -55,8 +69,327 @@ export interface PeerPingPayload {
|
|
|
55
69
|
export interface PeerPingAckPayload {
|
|
56
70
|
readonly type: 'peer.ping_ack';
|
|
57
71
|
}
|
|
58
|
-
/**
|
|
59
|
-
export
|
|
72
|
+
/** Retires the sender's current peer card and process instance. */
|
|
73
|
+
export interface PeerGoodbyePayload {
|
|
74
|
+
readonly type: 'peer.goodbye';
|
|
75
|
+
readonly peerCardId: string;
|
|
76
|
+
readonly cardRevision: number;
|
|
77
|
+
readonly instanceId: string;
|
|
78
|
+
}
|
|
79
|
+
/** Publishes one bounded revision of a peer-owned capability. */
|
|
80
|
+
export interface CapabilityAdvertisePayload {
|
|
81
|
+
readonly type: 'capability.advertise';
|
|
82
|
+
readonly advertisementId: string;
|
|
83
|
+
readonly capabilityId: string;
|
|
84
|
+
readonly capabilityRevision: number;
|
|
85
|
+
readonly ownerPeerId: string;
|
|
86
|
+
readonly capabilityKey: string;
|
|
87
|
+
readonly version: string;
|
|
88
|
+
readonly variant?: string;
|
|
89
|
+
readonly inputMediaTypes: readonly string[];
|
|
90
|
+
readonly outputMediaTypes: readonly string[];
|
|
91
|
+
readonly attributes: Readonly<Record<string, string>>;
|
|
92
|
+
readonly validFrom: string;
|
|
93
|
+
readonly validUntil: string;
|
|
94
|
+
readonly maximumConcurrency?: number;
|
|
95
|
+
readonly maximumPayloadBytes?: number;
|
|
96
|
+
readonly previousAdvertisementId?: string;
|
|
97
|
+
}
|
|
98
|
+
/** Withdraws one specific advertised revision of a capability. */
|
|
99
|
+
export interface CapabilityWithdrawPayload {
|
|
100
|
+
readonly type: 'capability.withdraw';
|
|
101
|
+
readonly capabilityId: string;
|
|
102
|
+
readonly capabilityRevision: number;
|
|
103
|
+
readonly advertisementId: string;
|
|
104
|
+
}
|
|
105
|
+
/** Fields shared by complete Objective announcement and revision documents. */
|
|
106
|
+
export interface ObjectiveDocumentFields {
|
|
107
|
+
readonly objectiveDocumentId: string;
|
|
108
|
+
readonly objectiveId: string;
|
|
109
|
+
readonly objectiveRevision: number;
|
|
110
|
+
readonly issuerPeerId: string;
|
|
111
|
+
readonly successCriteria: readonly string[];
|
|
112
|
+
readonly permittedCapabilityKeys: readonly string[];
|
|
113
|
+
readonly maximumWorkItems: number;
|
|
114
|
+
readonly maximumConcurrentAssignments: number;
|
|
115
|
+
readonly maximumBudgetUnits: number;
|
|
116
|
+
readonly bidWindowMs: number;
|
|
117
|
+
readonly acceptanceWindowMs: number;
|
|
118
|
+
readonly maximumLeaseDurationMs: number;
|
|
119
|
+
readonly recoveryGraceMs: number;
|
|
120
|
+
readonly maximumLeaseRenewals: number;
|
|
121
|
+
readonly recoveryWitnessPeerIds: readonly string[];
|
|
122
|
+
readonly recoveryWitnessThreshold: number;
|
|
123
|
+
readonly validFrom: string;
|
|
124
|
+
readonly validUntil: string;
|
|
125
|
+
readonly authorizedObserverPeerIds?: readonly string[];
|
|
126
|
+
}
|
|
127
|
+
/** Exactly one inline summary or external content reference. */
|
|
128
|
+
export type ObjectiveDocumentContent = {
|
|
129
|
+
readonly summary: string;
|
|
130
|
+
readonly contentReference?: never;
|
|
131
|
+
} | {
|
|
132
|
+
readonly summary?: never;
|
|
133
|
+
readonly contentReference: string;
|
|
134
|
+
};
|
|
135
|
+
/** Complete first revision of an objective issued to the mesh. */
|
|
136
|
+
export type ObjectiveAnnouncePayload = ObjectiveDocumentFields & ObjectiveDocumentContent & {
|
|
137
|
+
readonly type: 'objective.announce';
|
|
138
|
+
};
|
|
139
|
+
/** Complete replacement revision of an existing objective document. */
|
|
140
|
+
export type ObjectiveRevisePayload = ObjectiveDocumentFields & ObjectiveDocumentContent & {
|
|
141
|
+
readonly type: 'objective.revise';
|
|
142
|
+
readonly previousObjectiveDocumentId: string;
|
|
143
|
+
};
|
|
144
|
+
/** Cancels one specific objective document revision. */
|
|
145
|
+
export interface ObjectiveCancelPayload {
|
|
146
|
+
readonly type: 'objective.cancel';
|
|
147
|
+
readonly cancellationId: string;
|
|
148
|
+
readonly objectiveId: string;
|
|
149
|
+
readonly objectiveRevision: number;
|
|
150
|
+
readonly objectiveDocumentId: string;
|
|
151
|
+
}
|
|
152
|
+
/** Fields shared by every complete work offer. */
|
|
153
|
+
export interface WorkOfferFields {
|
|
154
|
+
readonly offerId: string;
|
|
155
|
+
readonly objectiveId: string;
|
|
156
|
+
readonly objectiveDocumentId: string;
|
|
157
|
+
readonly objectiveRevision: number;
|
|
158
|
+
readonly workItemId: string;
|
|
159
|
+
readonly workItemRevision: number;
|
|
160
|
+
readonly ownerPeerId: string;
|
|
161
|
+
readonly ownerEpoch: number;
|
|
162
|
+
readonly offerAttempt: number;
|
|
163
|
+
readonly previousOfferId?: string;
|
|
164
|
+
readonly requiredCapabilityKeys: readonly string[];
|
|
165
|
+
readonly matchingAttributes: Readonly<Record<string, string>>;
|
|
166
|
+
readonly completionCriteria: readonly string[];
|
|
167
|
+
readonly budgetReservationUnits: number;
|
|
168
|
+
readonly bidDeadline: string;
|
|
169
|
+
readonly workDeadline: string;
|
|
170
|
+
}
|
|
171
|
+
/** Exactly one inline work input summary or external content reference. */
|
|
172
|
+
export type WorkOfferInput = {
|
|
173
|
+
readonly inputSummary: string;
|
|
174
|
+
readonly inputReference?: never;
|
|
175
|
+
} | {
|
|
176
|
+
readonly inputSummary?: never;
|
|
177
|
+
readonly inputReference: string;
|
|
178
|
+
};
|
|
179
|
+
/** Offers one bounded work item for capability-based bidding. */
|
|
180
|
+
export type WorkOfferPayload = WorkOfferFields & WorkOfferInput & {
|
|
181
|
+
readonly type: 'work.offer';
|
|
182
|
+
};
|
|
183
|
+
/** Proposes one capacity and budget reservation for an accepted work offer. */
|
|
184
|
+
export interface WorkBidPayload {
|
|
185
|
+
readonly type: 'work.bid';
|
|
186
|
+
readonly bidId: string;
|
|
187
|
+
readonly bidRevision: number;
|
|
188
|
+
readonly previousBidId?: string;
|
|
189
|
+
readonly offerId: string;
|
|
190
|
+
readonly objectiveId: string;
|
|
191
|
+
readonly objectiveDocumentId: string;
|
|
192
|
+
readonly objectiveRevision: number;
|
|
193
|
+
readonly workItemId: string;
|
|
194
|
+
readonly workItemRevision: number;
|
|
195
|
+
readonly ownerPeerId: string;
|
|
196
|
+
readonly ownerEpoch: number;
|
|
197
|
+
readonly offerAttempt: number;
|
|
198
|
+
readonly bidderPeerId: string;
|
|
199
|
+
readonly advertisementId: string;
|
|
200
|
+
readonly capabilityId: string;
|
|
201
|
+
readonly capabilityRevision: number;
|
|
202
|
+
readonly capacityReservationUnits: number;
|
|
203
|
+
readonly budgetUnits: number;
|
|
204
|
+
readonly bidDeadline: string;
|
|
205
|
+
readonly workDeadline: string;
|
|
206
|
+
readonly expectedCompletionAt: string;
|
|
207
|
+
readonly bidExpiresAt: string;
|
|
208
|
+
readonly assumptions: readonly string[];
|
|
209
|
+
}
|
|
210
|
+
/** Fields common to both fresh awards and recovery-certified assignments. */
|
|
211
|
+
export interface WorkAwardFields {
|
|
212
|
+
readonly type: 'work.award';
|
|
213
|
+
readonly awardId: string;
|
|
214
|
+
readonly offerId: string;
|
|
215
|
+
readonly bidId: string;
|
|
216
|
+
readonly bidRevision: number;
|
|
217
|
+
readonly objectiveId: string;
|
|
218
|
+
readonly objectiveDocumentId: string;
|
|
219
|
+
readonly objectiveRevision: number;
|
|
220
|
+
readonly workItemId: string;
|
|
221
|
+
readonly workItemRevision: number;
|
|
222
|
+
readonly ownerPeerId: string;
|
|
223
|
+
readonly ownerEpoch: number;
|
|
224
|
+
readonly offerAttempt: number;
|
|
225
|
+
readonly assigneePeerId: string;
|
|
226
|
+
readonly assignmentEpoch: number;
|
|
227
|
+
readonly assignmentAuthorityId: string;
|
|
228
|
+
readonly fencingToken: string;
|
|
229
|
+
readonly budgetReservationUnits: number;
|
|
230
|
+
readonly workDeadline: string;
|
|
231
|
+
readonly leaseStartsAt: string;
|
|
232
|
+
readonly leaseExpiresAt: string;
|
|
233
|
+
readonly acceptanceDeadline: string;
|
|
234
|
+
}
|
|
235
|
+
/** Assigns work under either the original award or recovery authority. */
|
|
236
|
+
export type WorkAwardPayload = (WorkAwardFields & {
|
|
237
|
+
readonly authorityKind: 'award';
|
|
238
|
+
readonly recoveryCertificateId?: never;
|
|
239
|
+
readonly resumeCheckpointId?: never;
|
|
240
|
+
}) | (WorkAwardFields & {
|
|
241
|
+
readonly authorityKind: 'recovery_certificate';
|
|
242
|
+
readonly recoveryCertificateId: string;
|
|
243
|
+
readonly resumeCheckpointId?: string;
|
|
244
|
+
});
|
|
245
|
+
/** Fields echoed by an assignee when responding to one assignment. */
|
|
246
|
+
export interface WorkAssignmentResponseFields {
|
|
247
|
+
readonly awardId: string;
|
|
248
|
+
readonly objectiveId: string;
|
|
249
|
+
readonly objectiveDocumentId: string;
|
|
250
|
+
readonly objectiveRevision: number;
|
|
251
|
+
readonly workItemId: string;
|
|
252
|
+
readonly workItemRevision: number;
|
|
253
|
+
readonly ownerPeerId: string;
|
|
254
|
+
readonly ownerEpoch: number;
|
|
255
|
+
readonly assigneePeerId: string;
|
|
256
|
+
readonly assignmentEpoch: number;
|
|
257
|
+
readonly assignmentAuthorityId: string;
|
|
258
|
+
readonly fencingToken: string;
|
|
259
|
+
readonly acceptanceDeadline: string;
|
|
260
|
+
}
|
|
261
|
+
/** Accepts one assignment before its bounded response deadline. */
|
|
262
|
+
export interface WorkAcceptPayload extends WorkAssignmentResponseFields {
|
|
263
|
+
readonly type: 'work.accept';
|
|
264
|
+
readonly acceptanceId: string;
|
|
265
|
+
}
|
|
266
|
+
/** Declines one assignment before its bounded response deadline. */
|
|
267
|
+
export interface WorkDeclinePayload extends WorkAssignmentResponseFields {
|
|
268
|
+
readonly type: 'work.decline';
|
|
269
|
+
readonly declineId: string;
|
|
270
|
+
}
|
|
271
|
+
/** Assignment authority echoed by every assignment lifecycle record. */
|
|
272
|
+
export interface WorkAssignmentAuthorityFields {
|
|
273
|
+
readonly objectiveId: string;
|
|
274
|
+
readonly objectiveDocumentId: string;
|
|
275
|
+
readonly objectiveRevision: number;
|
|
276
|
+
readonly workItemId: string;
|
|
277
|
+
readonly workItemRevision: number;
|
|
278
|
+
readonly ownerPeerId: string;
|
|
279
|
+
readonly ownerEpoch: number;
|
|
280
|
+
readonly assigneePeerId: string;
|
|
281
|
+
readonly awardId: string;
|
|
282
|
+
readonly assignmentEpoch: number;
|
|
283
|
+
readonly assignmentAuthorityId: string;
|
|
284
|
+
readonly fencingToken: string;
|
|
285
|
+
readonly leaseExpiresAt: string;
|
|
286
|
+
}
|
|
287
|
+
/** Accepted assignment authority echoed by every execution record. */
|
|
288
|
+
export interface WorkExecutionAuthorityFields extends WorkAssignmentAuthorityFields {
|
|
289
|
+
readonly acceptanceId: string;
|
|
290
|
+
}
|
|
291
|
+
/** Reports bounded incremental progress under one accepted assignment. */
|
|
292
|
+
export interface WorkProgressPayload extends WorkExecutionAuthorityFields {
|
|
293
|
+
readonly type: 'work.progress';
|
|
294
|
+
readonly progressId: string;
|
|
295
|
+
readonly progressSequence: number;
|
|
296
|
+
readonly progressSummary: string;
|
|
297
|
+
readonly checkpointId?: string;
|
|
298
|
+
}
|
|
299
|
+
/** Exactly one inline checkpoint summary or external content reference. */
|
|
300
|
+
export type WorkCheckpointContent = {
|
|
301
|
+
readonly checkpointSummary: string;
|
|
302
|
+
readonly checkpointReference?: never;
|
|
303
|
+
} | {
|
|
304
|
+
readonly checkpointSummary?: never;
|
|
305
|
+
readonly checkpointReference: string;
|
|
306
|
+
};
|
|
307
|
+
/** Persists a content-addressed checkpoint under one accepted assignment. */
|
|
308
|
+
export type WorkCheckpointPayload = WorkExecutionAuthorityFields & WorkCheckpointContent & {
|
|
309
|
+
readonly type: 'work.checkpoint';
|
|
310
|
+
readonly checkpointId: string;
|
|
311
|
+
readonly checkpointSequence: number;
|
|
312
|
+
readonly previousCheckpointId?: string;
|
|
313
|
+
readonly checkpointDigest: string;
|
|
314
|
+
};
|
|
315
|
+
/** Exactly one inline result summary or external content reference. */
|
|
316
|
+
export type WorkResultContent = {
|
|
317
|
+
readonly resultSummary: string;
|
|
318
|
+
readonly resultReference?: never;
|
|
319
|
+
} | {
|
|
320
|
+
readonly resultSummary?: never;
|
|
321
|
+
readonly resultReference: string;
|
|
322
|
+
};
|
|
323
|
+
/** Publishes a content-addressed result under one accepted assignment. */
|
|
324
|
+
export type WorkResultPayload = WorkExecutionAuthorityFields & WorkResultContent & {
|
|
325
|
+
readonly type: 'work.result';
|
|
326
|
+
readonly resultId: string;
|
|
327
|
+
readonly resultDigest: string;
|
|
328
|
+
readonly checkpointId?: string;
|
|
329
|
+
};
|
|
330
|
+
/** Releases an active assignment under owner or assignee authority. */
|
|
331
|
+
export interface WorkReleasePayload extends WorkExecutionAuthorityFields {
|
|
332
|
+
readonly type: 'work.release';
|
|
333
|
+
readonly releaseId: string;
|
|
334
|
+
readonly releaseAuthority: 'owner' | 'assignee';
|
|
335
|
+
readonly releaseDisposition: 'reoffer' | 'close';
|
|
336
|
+
}
|
|
337
|
+
/** Cancels either a pending award or an active accepted assignment. */
|
|
338
|
+
export type WorkCancelPayload = WorkAssignmentAuthorityFields & {
|
|
339
|
+
readonly type: 'work.cancel';
|
|
340
|
+
readonly cancellationId: string;
|
|
341
|
+
} & ({
|
|
342
|
+
readonly assignmentState: 'award_pending';
|
|
343
|
+
readonly acceptanceId?: never;
|
|
344
|
+
} | {
|
|
345
|
+
readonly assignmentState: 'active';
|
|
346
|
+
readonly acceptanceId: string;
|
|
347
|
+
});
|
|
348
|
+
/** Extends one accepted assignment lease without changing its authority. */
|
|
349
|
+
export interface LeaseRenewPayload extends WorkExecutionAuthorityFields {
|
|
350
|
+
readonly type: 'lease.renew';
|
|
351
|
+
readonly leaseRenewalId: string;
|
|
352
|
+
readonly leaseRenewalSequence: number;
|
|
353
|
+
readonly previousLeaseRenewalId?: string;
|
|
354
|
+
readonly renewedLeaseExpiresAt: string;
|
|
355
|
+
}
|
|
356
|
+
/** Assignment and lease snapshot shared by candidate and witness proposals. */
|
|
357
|
+
export interface LeaseTakeoverProposalFields extends WorkExecutionAuthorityFields {
|
|
358
|
+
readonly type: 'lease.takeover_proposal';
|
|
359
|
+
readonly takeoverProposalId: string;
|
|
360
|
+
readonly proposerPeerId: string;
|
|
361
|
+
readonly proposedAssigneePeerId: string;
|
|
362
|
+
readonly proposedAssignmentEpoch: number;
|
|
363
|
+
readonly leaseRenewalSequence: number;
|
|
364
|
+
readonly latestLeaseRenewalId?: string;
|
|
365
|
+
}
|
|
366
|
+
/** Proposes the next assignment epoch after one accepted lease expires. */
|
|
367
|
+
export type LeaseTakeoverProposalPayload = LeaseTakeoverProposalFields & ({
|
|
368
|
+
readonly proposalAuthority: 'candidate';
|
|
369
|
+
readonly candidateConsentProposalId?: never;
|
|
370
|
+
} | {
|
|
371
|
+
readonly proposalAuthority: 'witness';
|
|
372
|
+
readonly candidateConsentProposalId: string;
|
|
373
|
+
});
|
|
374
|
+
/** Endorses one accepted takeover proposal under configured witness authority. */
|
|
375
|
+
export interface LeaseVotePayload {
|
|
376
|
+
readonly type: 'lease.vote';
|
|
377
|
+
readonly leaseVoteId: string;
|
|
378
|
+
readonly takeoverProposalId: string;
|
|
379
|
+
readonly witnessPeerId: string;
|
|
380
|
+
readonly objectiveId: string;
|
|
381
|
+
}
|
|
382
|
+
/** Certifies one takeover proposal from a bounded set of witness votes. */
|
|
383
|
+
export interface LeaseCertificatePayload {
|
|
384
|
+
readonly type: 'lease.certificate';
|
|
385
|
+
readonly certificateId: string;
|
|
386
|
+
readonly certificateAssemblerPeerId: string;
|
|
387
|
+
readonly takeoverProposalId: string;
|
|
388
|
+
readonly leaseVoteIds: readonly string[];
|
|
389
|
+
readonly objectiveId: string;
|
|
390
|
+
}
|
|
391
|
+
/** Structurally implemented protocol payload subset. */
|
|
392
|
+
export type MeshMessagePayload = PeerHelloPayload | PeerCardPayload | PeerPingPayload | PeerPingAckPayload | PeerGoodbyePayload | CapabilityAdvertisePayload | CapabilityWithdrawPayload | ObjectiveAnnouncePayload | ObjectiveRevisePayload | ObjectiveCancelPayload | WorkOfferPayload | WorkBidPayload | WorkAwardPayload | WorkAcceptPayload | WorkDeclinePayload | WorkProgressPayload | WorkCheckpointPayload | WorkResultPayload | WorkReleasePayload | WorkCancelPayload | LeaseRenewPayload | LeaseTakeoverProposalPayload | LeaseVotePayload | LeaseCertificatePayload;
|
|
60
393
|
/** Shared fields that participate in envelope identity and signing. */
|
|
61
394
|
export interface MeshEnvelopeHeader<TPayload extends MeshMessagePayload = MeshMessagePayload> {
|
|
62
395
|
readonly protocol: typeof MESH_PROTOCOL;
|