0.0.0 Initial version.
0.1.0 Split off the request/response layer into its own spec.
Changed GET to POST in the offer interface.
0.2.0 Allow the client to submit the job to the executor early; it just
won't start running until the start time.
Added the Now field to acceptance responses.
Changed the start of the averaging interval from the acceptance
time to the actual start time.
0.3.0 Changed the format of the Payment field to include user.
0.4.0 Allow *_bounds fields when Intent == "offer".
Require all floats to be non-negative.
0.4.1 Replace cycles with computrons.
0.4.2 In the Payment field, speak of "account" instead of "user".
0.5.0 Added speed field to acceptance responses.
0.5.1 Clarification of Jobcontrol and Jobrenew.
0.5.2 Formatting and clarification of payment_bounds.
0.6.0 Rejections may contain optional meta-info without a hint offer.
0.7.0 The Now field must be part of the terms, otherwise other terms
cannot be interpreted.
0.7.1 Payment amount must be >= Min_charge. This could have been
inferred, but now it's explicit.
Every interaction with the agent is a request/response. (See the request/response layer specification.)
All times are measured in seconds. Absolute times are measured since
0:00:00 UTC 1 Jan 1970.
All money is measured in compucredits, a fictitious unit.
All computational work is measured in computrons, a fictitious unit.
For now, a computron is nominally one clock cycle, but a more accurate
measure may be defined in the future.
All floats are non-negative unless otherwise specified.
Each agent has a main URL, which we will denote "AGENTURL/". A GET on
AGENTURL/ will return a human-readable page describing the agent and
providing instructions for using it. There is a submission interface:
input: A real offer (see below).
outputs: Reaction = "accept" | "reject" | "error"
If reaction is error, there will also be:
errnum = integer
An ID for the error. We'll define these later.
errmsg = string
A human-readable error message.
If reaction is accept, the terms of the offer become a
contract binding on both parties. There will also be:
Jobcontrol = URL
For controlling the job. This is JOBURL/ (including
the trailing slash). See the executor interface.
Jobrenew = URL
For renegotiating if the job stops before it
terminates. This is AGENTJOBURL/ (including the
trailing slash). See below.
Now = float
The current time.
Start = float
The nominal time at which the job will start running
(must be >= Now). The client must submit the job to
the executor before this time, or the agent may cancel
the job and charge the Min_charge (see below). If
Start is not much more than Now (they will commonly be
equal), a reasonable grace period will be allowed.
speed = float
The speed of the executor assigned to the job, in
computrons per second.
If Reaction is "reject" (and only then), the response
may additionally contain an offer. It must be a hint
offer (see below). Or, instead of an offer, the response
may leave out *all* the required fields and use only the
optional meta-information fields.
An offer is a set of name/value pairs, some of which specify the
terms of the offer, and some of which supply meta-information.
Intent = "offer" | "hint-acceptable" | "hint-unacceptable"
Indicates how the terms are to be interpreted. If Intent is
"offer", this is a real offer that will become a contract
if accepted. Otherwise, it is merely a hint, providing an
example of terms that would be acceptable or unacceptable
Now = float
The current time. Some of the other terms are specified
relative to this.
Expiration = float
The duration for which this offer is valid. The agent may not
accept the offer after Now + Expiration (plus some reasonable
fudge factor to allow for processing, communication delays,
and clock skew). In the simplest case, this field is zero,
meaning that no pausing to wait on events is permitted before
the offer is accepted.
Delay = float
The delay, from now, until the job may start running. If the
offer is accepted, the Start time will be the acceptance time
or Now + Delay, whichever is later. In the simplest case,
this field is zero. Positive values allow contracts to be
negotiated now for services to be rendered later, which is
useful for speculation and for holding auctions.
Lease = float
If the job has not already stopped before Start + Lease, the
agent will suspend it.
Price_shape = "basic"
For now, always "basic". After the job stops, the price per
computron is maxprice * (avgspeed - minspeed) / (maxspeed -
minspeed). Exceptions: If avgspeed > maxspeed the price is
maxprice. If maxspeed == minspeed, the price is maxprice if
avgspeed >= minspeed, zero otherwise.
Price_minspeed = float
The minimum speed (in computrons per second) at which the
job is guaranteed to run, averaged over any interval [t0,t],
where t0 is the actual start time of the job, and t0 < t <=
the moment the job stops. This guarantee is good only if the
job is "always" ready to run, at some granularity that I'm
not going to specify right now. If the job blocks too much
and minspeed > 0, the agent is authorized to suspend the job
(though I'm not sure we have any mechanism for that).
Price_maxspeed = float
Must be >= minspeed. Affects the price per computron.
Price_maxprice = float
The maximum price per computron.
Min_charge = float
If the final charge turns out to be less than Min_charge, it
will be rounded up to Min_charge.
Payment = account amount
The account is a string and the amount is a float >=
Min_charge. Someday the payment will be a lot more
sophisticated and secure. For now, clients should use $USER
as the account string. We assume that the agent has the
ability to shuffle money around in accounts. If the agent
accepts the offer, it is authorized to collect the entire
payment immediately. When the job stops, the final charge is
calculated, and a refund is made if necessary. While the job
is running, if the agent determines that the payment has been
exhausted, it may suspend the job. Under no circumstances
may the agent collect more than the amount specified by the
Any of the following optional fields may appear. Because they are
not terms of the offer, their interpretation is not affected by
the value of Intent.
expiration_bounds = min max
delay_bounds = min max
lease_bounds = min max
price_minspeed_bounds = min max
price_maxspeed_bounds = min max
price_maxprice_bounds = min max
payment_bounds = min max
min_charge_bounds = min max
For all of the above, min and max specify outer limits of
acceptable values for the corresponding fields (capitalized
and without the _bounds suffix). Exception: payment_bounds
applies only to the amount of the Payment.
price_shape_options = word-list
A space-separated list of recognized values for the
After a job stops without terminating, the client can negotiate a
renewal contract for it by submitting an offer using the Jobrenew URL
that was returned when the initial offer was accepted:
This interface is exactly like the AGENTURL/offer interface. If
a renewal offer is accepted, it is guaranteed to return the same
Jobcontrol and Jobrenew URLs as in the original acceptance.
If a job remains suspended for too long, it may be killed.