Crafting & exchange

Job resolution

job-resolution-2

Tests included

This contract defines the behavior of jobs: a crafting bench, a build queue, or research.

This contract decides what your crafting bench or build queue does when a job stops, fails, or has no place for its result.

Use in your package

The first button opens the authoring tool with this contract added and its questions unanswered. You can also download the zip file and add the contract later.

What is in the zip file

The zip file holds the contract and its acceptance tests. In the authoring tool, choose Add contract and pick this zip file. If you edit your package outside the authoring tool, unpack the zip file in your package folder. The files of the zip file go into contracts/. Fill in the answers there.

Questions

Up to 9 questions. Some appear only after earlier answers.

  1. Does this job need inputs? A job claims an input when it reserves the input, so that no other rule can use it. A job spends an input when it uses the input up.
  2. What happens to recorded work when this job stops?
  3. What does a listed failure do when its row gives no result of its own?
  4. What happens to inputs this job still claims when it is canceled?
  5. What happens to later waiting jobs that needed a canceled job's output?
  6. When do required inputs become unavailable to other rules?
  7. Does a stopped job keep the inputs it has already claimed?
  8. When is the completed result delivered?
  9. What happens when the whole output does not fit at its normal destination?

Try the answers

Pick answers to see which rules and tests apply. Nothing is saved here. In the zip file and in the authoring tool, the questions have no answers yet.

Does this job need inputs? A job claims an input when it reserves the input, so that no other rule can use it. A job spends an input when it uses the input up.

Choices for Does this job need inputs? A job claims an input when it reserves the input, so that no other rule can use it. A job spends an input when it uses the input up.
The job needs one or more inputs. Brewing one potion may need two herbs and one bottle.

The request checks the required share at the request gate. The lifecycle claims and spends that share at the selected times.

The job claims and spends no input. Researching Pottery may need an unlocked lab but no material.

Input checks, claims, returns, and spending are empty. Eligibility conditions may still prevent the game from offering the request.

What happens to recorded work when this job stops?

Asked when
the work phases list has at least one row.
If not asked
The job has no work span before finish. Start and finish settle in one batch, unless an allowed delivery answer keeps the job in the visible state finished. No partial work is recorded. No interruption can stop the job before its finish gate. A recoverable failure while the job waits still moves the job to stopped, and the start gate is its resume point.
Choices for What happens to recorded work when this job stops?
Recorded work stays with the same job. A half-built wall remains halfway built after rain stops the work.

An ordinary stop preserves all recorded work. Only this job can resume from it.

Recorded work falls while the job is stopped. A cooling forge loses heat while no smith works.

Recorded work decreases under reversal-declared-in and never passes below no work. Claim changes caused by the decrease settle through lifecycle step 12.

Recorded work returns to none when the job stops. An interrupted lockpick attempt starts again from the beginning.

The first ordinary stop sets the recorded work to none. On cancellation, the recorded work becomes none after the claim snapshot is taken.

What does a listed failure do when its row gives no result of its own?

Asked when
the failures list has at least one row.
If not asked
No accepted or finished job fails; refusal, stopping, cancellation, and blocked delivery are different outcomes.
Choices for What does a listed failure do when its row gives no result of its own?
Failure may lose part of the current inputs, recorded work, or both, whichever exist. A spill may lose one cup of broth while the same soup remains unfinished.

The cited failure rule may lose a strict subset of claimed inputs, reduce recorded work without passing below no work, or do both. It creates no successful output and leaves the same job stopped.

Failure ends this job permanently. An overcooked meal is ruined and cannot finish as the same meal.

The job enters terminal failed and creates no successful output. A finished but undelivered new output is destroyed.

What happens to inputs this job still claims when it is canceled?

Asked when
the cancellations list has at least one row.
If not asked
An accepted job cannot be canceled. A reviewer confirms this before the adoption relies on it.
Choices for What happens to inputs this job still claims when it is canceled?
Every input that the job still claims returns to its source. Canceling a queued soldier returns the 50 gold that was reserved for the soldier.

Release every unit still claimed by the job. Do not add units that were never claimed or were already lost.

No claimed input returns. Canceling a fired clay pot spends the clay already placed in the kiln.

Spend every unit still claimed by the job and release none. Inputs not yet claimed remain at their sources.

A game rule chooses the returned share. Canceling a half-built wall may return unused bricks but not dried mortar.

Release the subset named by cancel-return-declared-in, never more than the current claim, and spend the rest.

What happens to later waiting jobs that needed a canceled job's output?

Asked when
the dependent cancellations list has at least one row.
If not asked
Canceling a job leaves later waiting jobs in place, even when they needed its output.
Choices for What happens to later waiting jobs that needed a canceled job's output?
Later jobs that can no longer get the needed output are canceled too. Canceling an iron ingot also cancels the waiting sword that needed it.

Cancel every transitively dependent later waiting job whose requirement can no longer be met. Settle them in waiting order.

Later jobs remain waiting. A sword order may wait for another iron ingot after its first ingot job is canceled.

Leave every later dependent job waiting. The wait ends only when the requirement is met again or the job is canceled.

When do required inputs become unavailable to other rules?

Asked when
Job inputs is Required inputs.
If not asked
This job claims no input, so there is no claim time to choose.
Choices for When do required inputs become unavailable to other rules?
All inputs are claimed when the request is accepted. A queued soldier reserves its full gold cost before training starts.

Atomically claim the full requirement at admission, whether the job waits or starts.

All inputs are claimed when work starts. A workbench leaves wood available until the bench begins the chair.

Atomically claim the full requirement at start. No other rule can use claimed units.

Inputs stay available until successful finish. A ritual checks for three crystals only when the casting completes.

Claim and spend the full requirement at the finish gate. No pre-finish input claim exists.

Inputs are claimed as work advances. A wall claims half its bricks when it reaches half of its recorded work.

Before each observable advance, claim the rounded share required at the proposed work point. Release the matching share when work reverses.

Does a stopped job keep the inputs it has already claimed?

Asked when
Partial work is Keep with job or Reverse while stopped or Reset at stop and Input claim timing is Taken at request or Taken at start or With progress.
If not asked
When no pre-finish claim exists there is nothing to hold; otherwise the stopped job keeps its claim.
Choices for Does a stopped job keep the inputs it has already claimed?
The job keeps the claim while stopped. A paused wall keeps its reserved bricks at the site.

Retain the current claim while stopped. Work changes may first reduce a progress-based claim.

The claim is released while the job is stopped, and the job must claim the inputs again before it resumes. A paused research topic releases its points for another topic.

Release the current claim while stopped. Reclaim the required share before resuming; remain stopped if that share is unavailable.

When is the completed result delivered?

Asked when
the delivery cases list has at least one row, or the output destinations list has at least one row, or the collection events list has at least one row, or the readmission events list has at least one row, or the redelivery events list has at least one row.
If not asked
A finished output is delivered automatically as soon as its normal destination accepts it.
Choices for When is the completed result delivered?
Delivery happens as soon as a destination accepts the output. A trained unit leaves the barracks for its rally point at once.

Move from finished to delivered immediately after the capacity policy accepts one destination.

The output waits at the destination that accepted it until it is collected. A cooked meal stays on the stove until a player picks it up.

Keep the accessible output in finished until collection-declared-in occurs, then report delivery once.

What happens when the whole output does not fit at its normal destination?

Choices for What happens when the whole output does not fit at its normal destination?
The normal destination always accepts the output. Completed research always fits in the research ledger.

No job reaches a capacity-blocked state. A reviewer confirms the capacity promise before the adoption relies on it. An adoption with an in-place output always gives this answer. If the capacity promise is false, the adoption is invalid; there is no fallback lifecycle branch.

The job waits before starting until room is reserved. A bakery starts a loaf only after one shelf space is held for it.

Keep admission pending until the whole output has reserved room. Hold that reservation through delivery.

The job stops at the finish gate with its completed work until the output fits. An assembler holds a finished engine while its output slot is full.

The job moves to stopped at its finish gate, whether or not it has a work phase. It retains completed work until the destination has room.

The job finishes and keeps the output. Nobody can use the output until a new delivery attempt succeeds. A forge holds one finished sword while the rack is full.

Spend inputs and keep one owned output in finished. Only redelivery-declared-in retries the normal destination; work is not repeated.

The job tries named places in order. A mined gem tries the backpack, then the cart, then waits if both refuse it.

Try the normal destination, then output-destinations in written order. Keep the same output in finished if all refuse; only redelivery-declared-in retries the route.

Numbers and rulesno numbers, 3 rules

Numbers

This contract has no numbers to set.

Rules

  • A job that claims inputs with progress cannot also reset all its work at a stop, because the job stops when inputs run out. Keep or reverse the work, or claim inputs at another time.

    Forbidden when Input claim timing is With progress and Partial work is Reset at stop.

  • Reversing work while inputs are claimed with progress can make the same materials leave and return repeatedly.

    Forbidden when Input claim timing is With progress and Partial work is Reverse while stopped. (a warning, not an error)

  • A result that waits for collection must already be at a destination that accepted it. Choose an answer to output-full that puts the result at a destination first.

    Forbidden when Delivery trigger is On collection and Output full is Hold undelivered, or Delivery trigger is On collection and Output full is Try destinations.

Lists17 lists

Some settings are lists of rows.

A reference points to a number or a rule in your design. For a number, use the address of a decided number in your tuning, not an open one. For a rule, use its file and heading, such as 02-mechanics.md#recovery. The reference must match exactly one heading in that file. No > DELEGATED: or > PERSONALIZATION: tag may cover any part of the section under that heading. Each field's description says what it needs.

Job

job

Give the job rule and the normal output destination. One adoption has exactly one row.

An empty list means: An empty job list is never a behavior choice: this adoption requires exactly one job row, and a reviewer rejects a file without it.

Each row is: job-declared-in, normal-destination-declared-in, output-kind.

Every field
FieldKindWhen it appearsMeaning
job-declared-in reference Required Where your game's rules say what this job needs and what it makes. The rules name the required inputs. They name one unit of successful output. They name the target, when the job changes a thing in place. They state any choices or quality rules that belong to your game.
normal-destination-declared-in reference Required Where your game's rules say what the normal destination of the output is.
output-kind choice: new-thing, in-place Required Whether success creates a new thing or transforms the cited target in place.

Read first

read-first

Optionally point a reviewer to prose that must be read before trusting the adoption.

An empty list means: No advance reading is required.

Each row is: id, read-first.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this reviewer note in your game's words, such as firing-is-one-batch.
read-first reference Required Where your game's rules say what a reviewer must know before trusting this adoption.

Work phases

work-phases

List the work span before finish. One adoption has at most one row.

An empty list means: Start and finish settle in one batch.

Each row is: id, duration-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for the work span in your game's words, such as cooking or wall-building.
duration-declared-in reference Required Where your game's rules say how long the work takes and which clock measures it, or which event completes the work.

Interruptions

interruptions

List the game rules allowed to instruct a working job to stop.

An empty list means: A job stops only when it is unable to advance. No game rule can instruct it to stop.

Each row is: id, interruptions-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this interruption in your game's words, such as fuel-runs-out or smith-called-away.
interruptions-declared-in reference Required Where your game's rules say which rules may instruct a working job to stop.

Reversal rules

reversal-rules

Add a row when the answer to partial-work is reverse-while-stopped. In every other case, leave this list empty. The row points to the rule that says how recorded work decreases.

An empty list means: Stopped work does not reverse.

Each row is: id, reversal-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this reversal rule in your game's words, such as forge-cooling.
reversal-declared-in reference Required Where your game's rules say how recorded work decreases while the job is stopped.

Progress rounding rules

progress-rounding-rules

Add a row when the answer to input-claim-timing is with-progress. In every other case, leave this list empty. The row points to the rule that rounds the share of each input that the job claims as work advances.

An empty list means: Inputs are not claimed with progress.

Each row is: id, progress-rounding-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this rounding rule in your game's words, such as material-by-work.
progress-rounding-declared-in reference Required Where your game's rules say how to round the share of each divisible input that the job claims as work advances.

Cancel return rules

cancel-return-rules

Add a row when the answer to cancel-return is return-by-rule. In every other case, leave this list empty. The row points to the rule that says which part of the claimed inputs returns.

An empty list means: Cancellation does not return a share that a game rule chooses.

Each row is: id, cancel-return-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this return rule in your game's words, such as unused-stock-returns.
cancel-return-declared-in reference Required Where your game's rules say which part of the current claim returns when the job is canceled.

Collection events

collection-events

Add a row when the answer to delivery-trigger is on-collection. In every other case, leave this list empty. The row points to the event that collects the finished output.

An empty list means: A finished output does not wait for collection.

Each row is: id, collection-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this collection event in your game's words, such as player-collects-dish.
collection-declared-in reference Required Where your game's rules say which event accepts the finished output and delivers it.

Readmission events

readmission-events

Add a row when the answer to output-full is wait-before-start. In every other case, leave this list empty. The row points to the rule or event that makes the game try admission again.

An empty list means: Output room is not reserved before start.

Each row is: id, readmission-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this readmission event in your game's words, such as shelf-space-freed.
readmission-declared-in reference Required Where your game's rules say which rule or event tries admission again. The game tries again only then. It does not check repeatedly by itself.

Redelivery events

redelivery-events

Add a row when a held output, or a route that can be refused, can try delivery again. The row points to the event that tries delivery again.

An empty list means: A held output or a route that can be refused does not retry delivery.

Each row is: id, redelivery-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this redelivery event in your game's words, such as rack-space-freed or storage-changed.
redelivery-declared-in reference Required Where your game's rules say which rule or event tries delivery again. The game tries again only then. It does not check repeatedly by itself.

Work limits

work-limits

List each pool. A pool is a group of jobs that share one limit on how many may work at the same time. A pool can also limit how many jobs may wait. Each job that works uses one working slot of the pool, and each job that waits uses one waiting slot.

An empty list means: Jobs share no work limit and every otherwise-ready job starts.

Each row is: id, covers-declared-in, scope, places-declared-in, place-assignment-declared-in, working-limit-key, waiting-limit-key, waiting-order, order-declared-in, releases-working-at.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this pool in your game's words, such as barracks-line or one-burner.
covers-declared-in reference Required Where your game's rules say exactly which requests use this pool.
scope choice: each-place, shared Required Whether each cited place has its own working slots and waiting slots, or all covered jobs share one set of slots.
places-declared-in reference Present when row scope is Each place. Where your game's rules say which places have their own slots. Fill this in when each place has its own slots. Leave it out when all covered jobs share one set of slots.
place-assignment-declared-in reference Present when row scope is Each place. Where your game's rules say how each request is assigned to one place. Fill this in when each place has its own slots. Leave it out when all covered jobs share one set of slots.
working-limit-key reference Required Where your game's rules say how many jobs of the pool may work at the same time. The number is a positive whole number.
waiting-limit-key reference Optional Where your game's rules say how many jobs of the pool may wait. The number is a whole number, zero or more. When the field is absent, the number of waiting jobs has no limit.
waiting-order choice: request-order, game-rule-order Required Whether a free working slot is offered to jobs in request order, or in the order that a cited rule gives. The cited rule must put all jobs of the pool in one complete order.
order-declared-in reference Present when row waiting order is Game rule order. Where your game's rules say in which order the jobs of the pool get a free working slot. The rules must put all jobs in one complete order. Fill this in when the waiting order is game-rule-order. Leave it out when the waiting order is request-order.
releases-working-at choice: finished, delivered Optional When a successful job frees its working slot: after it is finished, or after it is delivered. When the field is absent, the job frees the slot after it is finished.

Standing orders

standing-orders

List each repeating order. A repeating order stays after it creates a job, and can create a job of the same kind again.

An empty list means: No request repeats automatically.

Each row is: id, work-limit, requests-job-declared-in, eligible-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this repeating order in your game's words, such as repeat-selected.
work-limit string Required The work-limits row for this order. When that pool has a free working slot, the order may create a job.
requests-job-declared-in reference Required Where your game's rules say which kind of job this order requests.
eligible-declared-in reference Required Where your game's rules say whether this order may create another request.

Failures

failures

List failures that may happen after acceptance.

An empty list means: Accepted and finished jobs do not fail.

Each row is: id, from-state, trigger-declared-in, result.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this failure in your game's words, such as overcooked or storm-damage.
from-state choice: waiting, working, stopped, finished Required The state from which this failure may happen.
trigger-declared-in reference Required Where your game's rules say what causes this failure: a chance, a condition, or an event. The rules also say what the failure may lose.
result choice: partial-inputs-or-work, job-ruined Optional The result of this failure. When the field is absent, the default answer applies.

Cancellations

cancellations

List controls or events that may cancel an unfinished job.

An empty list means: An accepted job cannot be canceled; a reviewer confirms this before the adoption relies on it.

Each row is: id, trigger-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for the cancellation in your game's words, such as cancel-unit or cancel-order.
trigger-declared-in reference Required Where your game's rules say which control or event cancels the unfinished job.

Dependent cancellations

dependent-cancellations

List static links through which a later waiting job needs an earlier job's output.

An empty list means: No later waiting job has a static dependency on an earlier job's output.

Each row is: id, cancellation, link-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this dependency case in your game's words, such as sword-needs-ingot.
cancellation string Required The matching cancellation row.
link-declared-in reference Required Where your game's rules say which static link connects the requirement of the later job to the output of the earlier job.

Delivery cases

delivery-cases

List each capacity or delivery condition of your game that no collection, readmission, redelivery, or fallback row already states.

An empty list means: When every other delivery row set is also empty, delivery is automatic and the normal destination always accepts the output. A reviewer confirms both promises before the adoption relies on them.

Each row is: id, condition-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this delivery situation in your game's words, such as full-output-slot.
condition-declared-in reference Required Where your game's rules say which capacity rule or collection rule makes this situation apply.

Output destinations

output-destinations

List fallback destinations after the normal destination, in the order tried.

An empty list means: No fallback destination follows the normal destination.

Each row is: id, destination-declared-in.

Every field
FieldKindWhen it appearsMeaning
id string Required A short name for this fallback destination in your game's words, such as mine-cart.
destination-declared-in reference Required Where your game's rules say what this destination is and how it accepts the whole output.

For builders

Exact wording for builders and 66 pack tests

Exact wording for builders

This text decides the order of the steps for states, events, input claims, and reports. The questions and rows supply choices and cited game rules. They do not change the order.

A job run begins with one request and ends at refusal, cancellation, terminal failure, or delivery. Every report carries the same job id and run id. It also carries old and new lifecycle state, cause, recorded work before and after, input units newly claimed, released, spent, or lost, and the output destination when chosen. Amounts use units and numbers from the cited game rules. job-requested has no old state and is outside the ordered instant batch. job-rejected is the report of a refused request. It ends the run but is not a lifecycle state. destination-refused changes no state: old and new state are both finished.

A claim makes inputs unavailable to every other rule while keeping their source known. Releasing a claim returns the units that are still claimed to that source. Spending or losing units removes them; neither can later be released.

The forward path is requested -> waiting -> started -> working -> finished -> delivered. Side paths are working -> stopped -> working, requested/waiting/working/stopped -> canceled, and waiting/working/stopped/finished -> failed. A recoverable failure reports job-failed and moves the job to stopped instead.

Not every job visits every state. waiting and stopped can return to the forward path. canceled, terminal failed, and delivered are terminal. started is a transition boundary, not a waiting state. A pool limits how many jobs may work, and can limit how many may wait. A job that starts takes one working slot of its pool, and a job that waits takes one waiting slot. The working limit and the waiting limit give the number of slots. Entry to any terminal state immediately frees every slot that the job holds. releases-working-at affects only the success path and never delays the freeing of slots at a terminal state.

Every stopped job records all active stop causes and its resume point. It resumes only after every cause clears. Finish-gate causes are output-full and inputs-unavailable-at-finish; a finish-gate cause keeps the working slot. Every other cause does not keep it. Entry to stopped always frees a waiting slot. A stopped job keeps its working slot only while every active cause is a finish-gate cause; the first other cause frees it. partial-work applies once when the first ordinary stop cause joins the set, never for a finish-gate cause. failure-recovery is neither a finish-gate cause nor an ordinary stop cause: it does not keep the working slot, and partial-work never applies to it, because step 16 has already settled the loss.

Whenever a pool has a free working slot, it first offers that slot to admitted jobs that are eligible to start or resume, in the pool's waiting order. A job stopped by an instruction joins that order at the stop moment and is never placed before the job that displaced it. A cleared reason also causes a waiting or stopped job to be offered a free working slot again. After those offers, the pool scans standing orders in written order. It also scans when it is created, after a refusal of a request that the pool did not create in this scan, and when cited eligibility becomes true. A scan keeps creating eligible requests until no row is eligible or no working slot is free. A scan may create more than one job from the same row, until every free working slot is filled. Each scan reads the conditions as they are at that time. A row that is still eligible creates requests again in a later scan; it does not act only once, at the moment when it becomes eligible.

### Request and accept

1. Read job-declared-in once. It names required inputs, one successful output unit, any in-place target, and the game's own choice or quality rules. If work limits exist, assign the request to exactly one pool. For a pool with separate slots for each place, assign it to exactly one cited place. Report job-requested.

2. Check availability without reserving anything. For required inputs, test the full requirement under the three whole-claim timings. Under progress-based claiming, test only the initial rounded share. A game rule may require a stricter offer check. If the tested share is missing, report job-rejected with cause missing-inputs; claim nothing, record no work, and create no output. Jobs with no inputs skip the check.

3. Decide whether the request would enter waiting. This includes a pool with a free working slot whose order places an earlier admitted job first. A request that is admitted to waiting always takes one waiting slot. If the waiting limit is full, refuse the request: report job-rejected with cause job-limit-full. A request that starts immediately takes no waiting slot.

4. Attempt admission. When room for the output must be reserved before start, reserve room for the whole output atomically. If room is unavailable, the request stays requested; readmission-declared-in causes another attempt without polling, which means that the game does not check again by itself. Recheck input and waiting limits on delayed admission. On admission, accept the request. Claim the full requirement in the same batch when inputs are taken at request. An admitted request that cannot start enters waiting; report job-waiting and every current reason. No work is recorded in waiting, and no input is claimed there except the claim made by taken-at-request.

### Start

5. Recheck every admission and start gate. Claim the full requirement under start timing. Under progress-based timing, claim the initial share. When the claim fails, the job enters waiting and takes one waiting slot. If the waiting limit is full, refuse the request instead: report job-rejected with cause job-limit-full, and release any output reservation. Otherwise report job-waiting with cause inputs-unavailable. Inputs taken at request are already held; inputs taken at finish remain at their source.

6. Keep any output reservation through delivery; other output answers reserve nothing. Free the waiting slot, take a working slot, and report job-started.

7. Without a work-phase row, resolve start and finish in one batch. The reports stay in one ordered batch, unless hold-undelivered, try-destinations with every destination refusing, or on-collection keeps the job in the visible state finished, as the answer allows, or a finish-gate cause stops the job at the finish gate. With a work phase, enter working and report job-working.

### Work and input claims

8. Work completes as duration-declared-in says: its clock advances or its completion event occurs. Record exposed work points at full precision. A display meter is outside this contract.

9. With progress-based timing, every observable advance first claims the rounded share for the proposed work point. If the share is unavailable, do not record the advance; stop with cause inputs-unavailable. Whole-claim timings keep their full claim. Finish timing keeps inputs available elsewhere.

10. Reaching the required work moves the job to the finish gate. It does not yet spend inputs or create the successful output.

### Stop, resume, and interrupt

11. An interruption is a temporary inability to advance, or an instruction to stop, that is not refusal, failure, cancellation, or delivery. It moves working -> stopped, adds its cause, applies partial-work and the claim policy, then reports job-stopped. An instructed stop must be named by interruptions-declared-in. A later cause joins the set and reports stopped -> stopped; it does not apply the work answer again.

12. First adjust a progress-based claim to any reduced work. Then apply stopped-claims: hold the claim, or release it to its source. Whole claims taken at request or start follow the same answer. Finish timing has no claim. When the question is not asked, the claim is held.

13. When every cause clears, the job competes for a free working slot through its pool, or proceeds without a pool. Recheck every gate and reclaim any released share. If a gate or claim is unavailable, remain stopped and leave the working slot free. Otherwise report job-resumed and return to the recorded resume point: after a failure from waiting, the job continues at step 5 and takes its working slot at step 6, while interrupted work takes a working slot again and enters working. The same job resumes; no new request is created.

14. The finish gate tests capacity and any finish-time claim together. The finish-gate wait answer adds output-full; an unavailable claim adds inputs-unavailable-at-finish. These causes preserve completed work and keep the working slot unless another active cause frees it. They never apply partial-work. stopped-claims applies to finish-gate stops exactly as in step 12. When every cause clears and any released claim is reclaimed, report job-resumed and return directly to the finish gate.

### Fail

15. A failure row fires when its failure happens. It may fire only from its named state. A failure from finished is always terminal; no recoverable result exists there. Resolve its row result, or the default answer to failure-result when the row has none, atomically. For a recoverable result, apply the stopped-claim policy before the one job-failed report.

16. A recoverable result may lose a strict subset of claimed inputs, reduce work without passing below none, or do both. It creates no successful output. Under progress-based timing, apply losses first. If the claim is held, reduce work to the highest point that the remaining claim supports and release the excess claim. If the claim was released, reduce work only by the named loss. The same job moves to stopped with cause failure-recovery; its recorded resume point is the start gate for a failure from waiting, the prior work point for a failure from working, or the already-recorded point for a failure from stopped. Later recovery follows the normal resume rule.

17. A ruined job enters terminal failed, can never finish as the same job, and creates no successful output. Failure from finished destroys its one undelivered new output. For in-place work, the failure ruins the transformation, but the target still exists. The cited failure rule defines the damaged state. Failure itself returns no claimed input; remaining claims stay assigned to the failed job unless the cited failure rule states another result for them. After the claim changes that the cited rule makes, terminal entry frees every slot and reports job-failed.

### Cancel

18. A declared cancellation may target requested, waiting, working, or stopped. Take a snapshot of the current claims, free every slot, apply the return answer when asked, enter canceled, and report job-canceled. Under the reset answer, terminal work becomes none after the snapshot. Cancellation creates no output and never undoes a finished or delivered output.

19. Returning claimed inputs releases every unit that is still claimed. Returning nothing spends them. A return chosen by a rule releases exactly the subset that the rule names and spends the rest. No answer recreates a unit already lost, and unclaimed inputs remain where they are.

20. A dependency is the declared static link from a later waiting job's requirement to the canceled job's output. Ending dependents finds every transitive later waiting job whose requirement can no longer be met. After the first cancellation settles, cancel those jobs in waiting order, each with its own claim settlement and report. Leaving dependents keeps them waiting. Completed intermediate jobs and delivered outputs remain.

### Finish and deliver

21. At the finish gate, finish-time timing tries to claim the full input. If the input is unavailable, follow the finish-gate stop rule. Other timings must hold the required claim. Atomically spend inputs and establish the one successful output: a new thing or a cited target transformed in place. An in-place output is delivered by that state change at its site. A compound output is still one atomic delivery unit. Report job-finished.

22. Resolve capacity by the selected answer. An always-accepting destination takes the whole output. A pre-start reservation is already held. A finish-gate wait follows the stop rule. A held output remains one owned, inaccessible output until its cited retry. An ordered route tries the normal destination and then fallback rows. Every refusal by any destination, including a held output's first refusal and each refusal on a cited retry, reports destination-refused. If all refuse, keep the same output until the cited retry. Delivery never polls. An in-place output has no destination capacity: it is delivered by the state change of step 21, and the adoption answers never-full.

23. Automatic delivery moves an accepted result finished -> delivered immediately. Collection keeps it accessible at its chosen destination until the cited event, then moves it to delivered. Report job-delivered exactly once.

24. On success, free the working slot after the transition named by the pool row and after that transition's report. Then offer the free working slot and scan the standing orders, as described above. A refusal ends the run of the refused request; a later retry is a new run that the requester starts, unless a standing order creates it.

### Ordering guarantee

One transition, all claim changes, and all reports settle before another transition begins. Claim changes happen before the transition report unless a step says otherwise. Automatic delivery to an accepting destination after an instant start keeps job-started, job-finished, and job-delivered in one ordered batch with no outside event between them. Events offered at the same moment enter this lifecycle one at a time in the order supplied by Event resolution. This contract creates no same-moment ordering rule.

Verification pack

sha256:485313c991e5954a45c583ea1fd9d3f7f0e249252c88a0da3ae689483cd32403

The format calls an adoption that has its matching pack Checked. The tests are included, but this does not mean that a game has passed them. An adoption without the pack is Promised. The builder must still build the chosen behavior.

66 pack tests

Placeholders are filled from the adoption's answers, numbers, rows, and test inputs.

reports identify their job run and state change

reports-identify-the-run

scenarioonce

Applies for every adoption

A request reads the rule cited at job-declared-in once, makes any pool and place assignment, and reports job-requested. Across the runs needed to reach every constructible report, every report in each run keeps that run's id and the same job id and records the cause, work, claim changes, and chosen destination. Every report except job-requested carries old and new state; job-requested carries a new state only. The report job-rejected is not a state. The report destination-refused has finished as both its old and its new state.

Given

the set of Instance job runs needed to reach every transition and every report without a state change that the adoption can construct

When
  • the report log is read in settlement order
Then
  • the request reads the rule cited at job-declared-in once, assigns exactly one pool and one cited place where those declarations exist, then reports job-requested
  • every report in each run carries that run's id and the same job id, plus cause, work before and after, units newly claimed, released, spent, or lost, and the destination when one is chosen
  • every report except job-requested carries old and new state; job-requested carries a new state only and is outside any ordered instant batch
  • job-rejected ends the run without becoming a lifecycle state, and destination-refused has old and new state both finished
Diagnostics
  • Instance-job-rule-read-log
  • Instance-report-log
  • Instance-state-trace
  • Instance-work-before-after
  • Instance-claim-ledger
claims preserve ownership and settle once

claims-keep-their-source

scenarioonce

Applies for every adoption

A claim makes its units unavailable everywhere else but keeps their source known. Release returns the units that are still claimed to that source. Spending and loss remove units, so neither kind can later be released. An adoption with no inputs has no claim event. In that case this test checks nothing.

Given

each claim, release, spend, and loss that a run of Instance can construct; an adoption with no inputs has no claim, and in that case this test checks nothing

When
  • another rule tries to use a claimed unit and the run later settles that unit
Then
  • the claimed unit is unavailable to every other rule while its source remains recorded
  • release returns each unit that is still claimed to that source
  • spending or losing removes the unit, and no removed unit is later released
Diagnostics
  • Instance-claim-ledger
  • Instance-source-record
  • Instance-usable-inputs
a request with a missing tested share is refused and changes nothing

exact-inputs-required

scenarioonce

Applies when Job inputs is Required inputs.

A request cannot pass with less than its tested share. Whole-claim timings test the full requirement. For progress claiming, both gates test at least the initial rounded share and never the full requirement by default; a stricter offer check named by the rule cited at job-declared-in may test more, and the test reads that rule to decide. The refusal claims nothing, records no work, and creates no output.

Given

a request for Instance with less than the tested input share available — the full requirement for a whole-claim timing; for progress claiming both gates test at least the initial rounded share and never the full requirement by default, while a stricter offer check named by the rule cited at job-declared-in may test more, and the test reads that rule to decide

When
  • the availability check runs without reserving inputs
Then
  • job-rejected reports cause missing-inputs and ends the run
  • no input is claimed, no work is recorded, and no output is created
Diagnostics
  • Instance-report-log
  • Instance-claim-ledger
  • Instance-work-before-after
  • Instance-output-identity
a no-input job skips the input check

no-input-check-is-empty

scenarioonce

Applies when Job inputs is No inputs.

This job needs no input, so its input check and every input settlement are empty. Pool, place, capacity, and other admission gates still apply.

Given

an otherwise eligible Instance request

When
  • the request reaches its availability check
Then
  • the input check is skipped and the claim, release, spend, and loss fields remain empty
  • non-input admission gates still decide whether the request is admitted
Diagnostics
  • Instance-admission-trace
  • Instance-claim-ledger
request-time inputs are claimed at admission

request-time-claim-is-atomic

scenarioonce

Applies when Input claim timing is Taken at request.

In each constructible admission shape, the whole requirement is claimed in one batch before job-started and, where the job waits, before job-waiting. For an adoption with no waiting shape, this test checks only the immediate-start case.

Given

each admission shape Instance can construct; the waiting shape is checked only where one exists

When
  • each constructible admission runs
Then
  • the full requirement is claimed atomically in the admission batch
  • the claim precedes job-started in the report order, and where the job waits, precedes job-waiting
  • no partial claim is observable
Diagnostics
  • Instance-admission-trace
  • Instance-claim-ledger
  • Instance-report-order
Row.id uses a waiting slot for each waiting admission

waiting-admission-uses-pool-capacity

scenarioper work-limits row

Applies for every adoption

Pool Row.id is selected under Row.covers declared in. A waiting admission takes one of its waiting slots; an immediate start takes none. Where the row declares a waiting limit and the limit is reached, the next request that would wait is refused with job-limit-full. With no waiting limit, this pool's waiting slots never cause job-limit-full. This test names the address and restates nothing from it.

Given

requests assigned to pool Row.id, including one that can start immediately and one that would wait; where this pool declares a waiting limit, also fill that limit

When
  • each request reaches admission under the coverage rule cited at Row.covers declared in
Then
  • an admitted waiting request takes one waiting slot, while an immediate start takes none
  • where the pool declares a waiting limit, a request that would exceed it reports job-rejected with cause job-limit-full
  • where the row declares no waiting limit, this pool's waiting slots never cause a refusal with job-limit-full
Diagnostics
  • Instance-count-trace
  • Instance-report-log
  • Instance-pool-assignment
Row.id is legal exactly for pre-start reservation

readmission-event-pairs-with-reservation

scenarioper readmission-events row

Applies for every adoption

Row Row.id is legal exactly when output-full is wait-before-start. Under that answer, the lifecycle consults the rule cited at Row.readmission declared in. When the row is present under another answer, the adoption is invalid, and this test fails. The test names the address and restates nothing from it.

Given

readmission-events row Row.id in the adoption

When
  • the output-full answer is checked
Then
  • the row is legal only under wait-before-start; when the row is present under any other answer, the adoption is invalid, and this test fails
  • the lifecycle consults the rule cited at Row.readmission declared in under that answer
Diagnostics
  • Instance-admission-trace
  • Instance-event-log
pre-start reservation declares a readmission event

reservation-needs-a-readmission-event

scenarioonce

Applies when Output full is Wait before start.

An adoption answering wait-before-start declares at least one readmission-events row. When it declares none, the adoption is invalid, and this test fails.

Given

an adoption answering wait-before-start

When
  • its readmission-events rows are inspected
Then
  • the adoption declares at least one readmission-events row; when it declares none, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
waiting records reasons but no work

waiting-records-every-current-reason

scenarioonce

Applies for every adoption

Each waiting shape this adoption can construct reports every current reason and records no work. Only the taken-at-request answer can already hold an input claim there. For an adoption with no waiting shape, this test checks nothing.

Given

each admitted Instance request that the adoption can construct with one or more reasons it cannot start; when the adoption can construct none, this test checks nothing

When
  • the admitted request enters waiting
Then
  • job-waiting reports every current reason
  • no work is recorded and no input is claimed in waiting except an already-required request-time claim
Diagnostics
  • Instance-report-log
  • Instance-state-trace
  • Instance-claim-ledger
start-time inputs are claimed before start

start-time-claim-is-atomic

scenarioonce

Applies when Input claim timing is Taken at start.

The full requirement is claimed atomically at the start gate. If it cannot be claimed, the job waits with inputs-unavailable; if a declared waiting limit is full, the request is refused with job-limit-full and any output reservation is released.

Given

an admitted Instance job at its start gate

When
  • the full requirement is available, then in a second run is unavailable
Then
  • the available run claims the full requirement atomically before job-started
  • the unavailable run enters waiting with cause inputs-unavailable, or is refused with job-limit-full where its full waiting limit prevents admission; the refusal releases any output reservation
Diagnostics
  • Instance-claim-ledger
  • Instance-report-log
  • Instance-reservation-ledger
finish-time inputs remain usable before the finish gate

finish-time-inputs-stay-at-source

scenarioonce

Applies when Input claim timing is Taken at finish.

Before the finish gate, all required inputs remain at their source and available to other rules.

Given

an admitted Instance job before its finish gate

When
  • the job waits, starts, and records every pre-finish work point it can construct
Then
  • the full required inputs remain at their source and no pre-finish claim exists
Diagnostics
  • Instance-claim-ledger
  • Instance-usable-inputs
progress claiming begins with the initial share

progress-claim-starts-with-rounded-share

scenarioonce

Applies when Input claim timing is With progress.

The request and start gates test at least the initial rounded share and never the full requirement by default. A stricter offer check named by the rule cited at job-declared-in may test more, and the test reads that rule to decide. Start claims the required share before reporting job-started.

Given

a request and start for Instance whose initial rounded share can be observed

When
  • the request check and then the start gate run
Then
  • both gates test at least the initial rounded share and never the full requirement by default; a stricter offer check named by the rule cited at job-declared-in may test more, and the test reads that rule to decide
  • start claims that share before job-started, and an unavailable share follows the start-time rule for waiting or refusal
Diagnostics
  • Instance-claim-ledger
  • Instance-report-log
start frees the waiting slot and takes a working slot

start-counts-settle-before-report

scenarioonce

Applies for every adoption

At job-started, the job has freed any waiting slot and taken any working slot. No job stays in started; it is a transition boundary. A pre-start output reservation remains held. For a shape that this adoption cannot construct, this test checks nothing.

Given

each admitted Instance job that can start, with and without a pool where those shapes exist

When
  • the job crosses the start boundary
Then
  • any waiting slot is freed and any working slot is taken before job-started
  • an output reservation, where the selected answer created one, remains held through delivery
  • no job is ever observed to stay in started; it is a transition boundary
Diagnostics
  • Instance-count-trace
  • Instance-reservation-ledger
  • Instance-report-log
Row.id enters working and reaches the finish gate

work-phase-enters-working

scenarioper work-phases row

Applies for every adoption

Work phase Row.id enters working, reports job-working, and completes as Row.duration declared in says. Work is recorded at full precision. Reaching the required amount moves the job to the finish gate but does not spend inputs or create output. The test names the address and restates nothing from it.

Given

a started Instance job using work phase Row.id

When
  • the job enters working and completes as Row.duration declared in says
Then
  • job-working reports entry to working
  • exposed work points use full precision and any display meter remains outside this contract
  • reaching the required work moves the job to the finish gate without yet spending inputs or creating output
Diagnostics
  • Instance-state-trace
  • Instance-work-before-after
  • Instance-claim-ledger
  • Instance-output-identity
a job without work settles start and finish together

instant-start-settles-finish-in-one-batch

scenarioonce

Applies for every adoption

With no work phase, start and finish settle in one batch unless hold-undelivered, a try-destinations route that every destination refuses, or on-collection keeps the job in the visible state finished, or a finish-gate cause stops it at the gate: an unavailable finish-time claim or a wait-until-space capacity wait. For an adoption with a work phase, this test checks nothing.

Given

the case with no work phase: if Instance has no work-phases row, a request that passes its gates; if it has a work phase, this test checks nothing

When
  • the job starts
Then
  • start and finish settle in one ordered batch
  • the ordered batch ends early only when hold-undelivered, a try-destinations route that every destination refuses, or on-collection keeps the job in the visible state finished, or a finish-gate cause stops it at the gate: an unavailable finish-time claim or a wait-until-space capacity wait
Diagnostics
  • Instance-report-log
  • Instance-state-trace
a job without work does not stop before finish

no-stop-before-the-finish-gate

scenarioonce

Applies for every adoption

An adoption with no work-phases row records no partial work and never enters stopped for an interruption of work before its finish gate. A recoverable failure while waiting is a failure, not an interruption: it moves the job to stopped under step 16 with the start gate as its resume point. For an adoption with a work phase, this test checks nothing.

Given

the case where Instance has no work-phases row; for an adoption with a work phase, this test checks nothing

When
  • an admitted job advances to its finish gate
Then
  • no partial work is recorded
  • the job never enters stopped for an interruption of work before its finish gate; a recoverable failure while waiting moves the job to stopped under step 16 with the start gate as its resume point
Diagnostics
  • Instance-work-before-after
  • Instance-state-trace
Row.id is legal exactly for progress claiming

progress-rounding-rule-pairs-with-progress

scenarioper progress-rounding-rules row

Applies for every adoption

Row Row.id is legal exactly when input-claim-timing is with-progress. Under that answer, the lifecycle consults the rule cited at Row.progress rounding declared in. When the row is present under another answer, the adoption is invalid, and this test fails. The test names the address and restates nothing from it.

Given

progress-rounding-rules row Row.id in the adoption

When
  • the input-claim-timing answer is checked
Then
  • the row is legal only under with-progress; when the row is present under any other answer, the adoption is invalid, and this test fails
  • the lifecycle consults the rule cited at Row.progress rounding declared in under that answer
Diagnostics
  • Instance-claim-ledger
  • Instance-work-before-after
progress claiming declares a rounding rule

progress-needs-a-rounding-rule

scenarioonce

Applies when Input claim timing is With progress.

An adoption answering with-progress declares at least one progress-rounding-rules row. When it declares none, the adoption is invalid, and this test fails.

Given

an adoption answering with-progress

When
  • its progress-rounding-rules rows are inspected
Then
  • the adoption declares at least one progress-rounding-rules row; when it declares none, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
Row.id records an ordinary stop once

declared-interruption-stops-once

scenarioper interruptions row

Applies for every adoption

Instruction Row.id is allowed by Row.interruptions declared in. When the adoption has this row but no work phase, the adoption is invalid, and this test fails. Entry to stopped records every active cause and its resume point, frees any waiting slot the adoption's pool gives it (an adoption with no work-limits row has none), and applies the work and claim answers once before job-stopped; a later cause reports stopped to stopped without applying the work answer again. The test names the address and restates nothing from it.

Given

a working Instance job and the instruction allowed by Row.interruptions declared in; when an adoption with no work-phases row has an interruptions row, the adoption is invalid, and this test fails

When
  • Row.id adds the first ordinary cause and a second cause later joins while the job is stopped
Then
  • the first cause moves working to stopped, records every active cause and its resume point, applies partial-work and the claim policy once, frees any waiting slot the adoption's pool gives it, then reports job-stopped
  • the later cause reports stopped to stopped and does not apply the work answer again
Diagnostics
  • Instance-state-trace
  • Instance-stop-causes
  • Instance-work-before-after
  • Instance-report-log
only named instructions can stop work

unnamed-instructions-cannot-stop

scenarioonce

Applies for every adoption

An instruction absent from every interruptions row is not an allowed stop. With an empty list, a job stops only when it is unable to advance. For an adoption with no working state, or with no unnamed instruction, this test checks nothing.

Given

each instruction this adoption can construct that is absent from all interruptions rows; for an adoption with no working state, or with no unnamed instruction, this test checks nothing

When
  • the instruction is offered to a Instance job in working, where that state exists
Then
  • the instruction does not add a stop cause and does not report job-stopped
Diagnostics
  • Instance-stop-causes
  • Instance-report-log
an ordinary stop preserves recorded work

kept-work-stays-with-the-job

scenarioonce

Applies when Partial work is Keep with job.

The same job keeps all recorded work through an ordinary stop and resumes from that amount; the work is never transferred to another job. When the adoption can construct no ordinary stop, this test checks nothing. A finish-gate stop never applies this answer.

Given

each Instance job with recorded work that the adoption can bring to a first ordinary stop; when the adoption can construct no ordinary stop, this test checks nothing, and a finish-gate stop never applies this answer

When
  • the stop settles and that same job later resumes
Then
  • the same job retains the same recorded amount through the stop and resumes from it
  • no other job receives that work
Diagnostics
  • Instance-work-before-after
  • Instance-run-id-trace
Row.id is legal exactly for reversing stopped work

reversal-rule-pairs-with-reversing-work

scenarioper reversal-rules row

Applies for every adoption

Row Row.id is legal exactly when partial-work is reverse-while-stopped. Under that answer, the lifecycle consults the rule cited at Row.reversal declared in: recorded work decreases while the job is stopped as that rule says and never passes below no work. When the row is present under another answer, the adoption is invalid, and this test fails. The test names the address and restates nothing from it.

Given

reversal-rules row Row.id in the adoption

When
  • the partial-work answer is checked
Then
  • the row is legal only under reverse-while-stopped; when the row is present under any other answer, the adoption is invalid, and this test fails
  • the lifecycle consults the rule cited at Row.reversal declared in under that answer
  • under that answer recorded work decreases while the job is stopped as the cited rule says and never passes below no work
Diagnostics
  • Instance-reversal-log
reversing stopped work declares a reversal rule

reversing-work-needs-a-reversal-rule

scenarioonce

Applies when Partial work is Reverse while stopped.

An adoption answering reverse-while-stopped declares at least one reversal-rules row. When it declares none, the adoption is invalid, and this test fails.

Given

an adoption answering reverse-while-stopped

When
  • its reversal-rules rows are inspected
Then
  • the adoption declares at least one reversal-rules row; when it declares none, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
an ordinary stop resets recorded work

reset-work-clears-on-ordinary-stop

scenarioonce

Applies when Partial work is Reset at stop.

Each first ordinary stop this adoption can construct resets recorded work to none. Where cancellation exists, it first takes a snapshot of the claim and leaves no terminal work. A recoverable failure is not an ordinary stop and does not reset work here; step 16 alone settles its loss.

Given

each Instance job with recorded work that can reach a first ordinary stop, and each separate cancellable run the adoption can construct

When
  • each available ordinary stop settles and, separately where cancellation is constructible, cancellation occurs
Then
  • the ordinary stop sets the recorded work to none
  • where cancellation is constructible, its claim snapshot is taken before terminal work becomes none, and no terminal work remains after cancellation
Diagnostics
  • Instance-work-before-after
  • Instance-claim-snapshot
  • Instance-state-trace
a stopped job keeps its current claim

stopped-job-holds-claim

scenarioonce

Applies when Stopped claims is Hold.

Where stopped work reverses, claim changes caused by the decrease settle through this stopped-claims step. A whole claim taken at request or start then follows hold exactly as a progress claim does, after any progress claim is first reduced to the recorded work. The adjusted claim remains assigned to the job.

Given

each Instance stop the adoption can construct with a current claim; for an adoption with no such stop, this test checks nothing

When
  • any work decrease and progress-based claim adjustment settle and the stop remains active
Then
  • where reverse-while-stopped applies, claim changes caused by the decrease settle through the stopped-claims step
  • a whole claim taken at request or at start follows this answer exactly as a progress claim does, after any progress claim is first reduced to the recorded work
  • the adjusted current claim stays assigned to the job and unavailable elsewhere until another lifecycle step settles it
Diagnostics
  • Instance-claim-ledger
  • Instance-stop-causes
a stopped job releases and must reclaim inputs

stopped-job-releases-and-reclaims

scenarioonce

Applies when Stopped claims is Release and reclaim.

Where stopped work reverses, claim changes caused by the decrease settle through this stopped-claims step. A whole claim taken at request or start then follows release-and-reclaim exactly as a progress claim does, after any progress claim is first reduced to the recorded work. Resume must reclaim the required share; if it cannot, the same job stays stopped and leaves the working slot free.

Given

each Instance stop the adoption can construct with a current claim; for an adoption with no such stop, this test checks nothing

When
  • any work decrease and progress-based claim adjustment settle, then all causes clear once with the required share available and once without it
Then
  • where reverse-while-stopped applies, claim changes caused by the decrease settle through the stopped-claims step
  • a whole claim taken at request or at start follows this answer exactly as a progress claim does, after any progress claim is first reduced to the recorded work
  • the adjusted claim is released while stopped
  • the available run reclaims the required share before job-resumed, while the unavailable run remains stopped and leaves the working slot free
Diagnostics
  • Instance-claim-ledger
  • Instance-state-trace
  • Instance-count-trace
the same job resumes only after every cause clears

resume-waits-for-every-cause

scenarioonce

Applies for every adoption

The same job resumes only after every active cause clears and every gate passes. It competes for a free working slot through its pool where the adoption declares one, and otherwise proceeds without a pool. If a gate or claim is unavailable, it remains stopped and leaves the working slot free; on success it reports job-resumed and returns to its recorded resume point without creating another request.

Given

each stopped Instance shape the adoption can construct, including overlapping causes where constructible

When
  • causes clear one at a time and the last cause clears
Then
  • no resume occurs while a cause remains
  • after the last cause clears, the same job rechecks gates and competes for a free working slot through its pool where the adoption declares one, and otherwise proceeds without a pool; it reports job-resumed only on success and creates no new request
  • if a gate or claim is unavailable, the job remains stopped and leaves the working slot free
  • a resume after interrupted work returns to its recorded work point, while a resume after a recoverable failure from waiting returns to the start gate
Diagnostics
  • Instance-stop-causes
  • Instance-resume-point
  • Instance-run-id-trace
  • Instance-report-log
when stopped-claims is not asked, the claim is held

unasked-stopped-claim-answer-holds

scenarioonce

Applies for every adoption

Where stopped-claims was not asked, a request-time claim held by a job stopped from waiting or by a finish-gate cause remains assigned after any progress adjustment. For an adoption that answered stopped-claims, or that cannot reach this case, this test checks nothing.

Given

each Instance request-time claim held while its job is stopped from waiting or by a finish-gate cause and stopped-claims was not asked; for an adoption that answered stopped-claims, or that has no such claim, this test checks nothing

When
  • the stop settles
Then
  • the current claim remains assigned to the stopped job after any progress-based adjustment
Diagnostics
  • Instance-claim-ledger
  • Instance-stop-causes
a full destination stops the job at the finish gate

finish-gate-wait-retains-completed-work

scenarioonce

Applies when Output full is Wait until space.

A full destination adds the cause output-full at the finish gate, whether or not the job has a work phase. This cause keeps the working slot. Completed work and the working slot remain; partial-work does not apply; resume returns directly to the finish gate. An instant job stops there too, and its one batch ends at that gate.

Given

a job in Instance with completed work, or an instant job at the finish gate of its one batch, and no room for the whole output

When
  • the finish gate first blocks and later gains room
Then
  • the job stops with cause output-full, which keeps the working slot; it preserves completed work, keeps its working slot while every active cause is a finish-gate cause, and does not apply partial-work
  • the first active cause that is not a finish-gate cause frees the working slot, and no successful output is established while output-full remains
  • where a current claim exists, the explicit stopped-claims answer applies; if that question was not asked, the claim is held
  • when every cause clears it reports job-resumed and returns directly to the finish gate without repeating work
Diagnostics
  • Instance-state-trace
  • Instance-work-before-after
  • Instance-count-trace
  • Instance-report-log
an unavailable finish claim stops the job at the finish gate

finish-claim-wait-is-slot-retaining

scenarioonce

Applies when Input claim timing is Taken at finish.

A missing finish-time claim adds inputs-unavailable-at-finish. The job keeps its working slot and its completed work, never applies partial-work, and returns directly to the finish gate after the claim succeeds. An adoption that always has its inputs at the gate constructs no wait. In that case this test checks nothing.

Given

a job in Instance at the finish gate without its full required input; an adoption that always has its inputs at the gate constructs no wait, and in that case this test checks nothing

When
  • the claim fails and later becomes available
Then
  • the job stops with cause inputs-unavailable-at-finish, which keeps the working slot; it preserves completed work, keeps any working slot while every active cause is a finish-gate cause, and does not apply partial-work
  • the first active cause that is not a finish-gate cause frees the working slot
  • any other current claim follows the explicit stopped-claims answer, or is held when that question was not asked
  • after every cause clears it claims the full requirement, reports job-resumed, and returns directly to the finish gate
Diagnostics
  • Instance-claim-ledger
  • Instance-state-trace
  • Instance-count-trace
Row.id offers and frees working slots in lifecycle order

work-limit-offers-room-and-releases-counts

scenarioper work-limits row

Applies for every adoption

Pool Row.id uses working limit Row.working limit key. It offers a free working slot to admitted jobs before it scans standing orders. Terminal entry frees every slot immediately. On success, finished or an absent field frees the working slot after job-finished; delivered frees it after job-delivered. The cited coverage and limit rules are at Row.covers declared in and Row.working limit key; this test restates neither.

Given

pool Row.id at its working limit Row.working limit key, with admitted jobs eligible to start or resume and active jobs brought through each success or terminal side path the adoption can construct

When
  • a working slot becomes free, a reason clears, a terminal state is entered, and a successful job reaches the transition this row selects
Then
  • a free working slot is offered first to admitted eligible jobs in the pool's waiting order, and a cleared reason causes a new offer
  • where the adoption declares an interruption, a job stopped by instruction joins the order at its stop moment and is never placed before the job that displaced it
  • entry to canceled, terminal failed, or delivered frees every slot immediately
  • on success, releases-working-at finished frees the working slot after finished and job-finished, releases-working-at delivered frees it after delivered and job-delivered, and an absent field follows finished; slot offers and standing-order scans then run
Diagnostics
  • Instance-count-trace
  • Instance-pool-offer-log
  • Instance-report-log
  • Instance-standing-order-scan-log
Row.id frees the working slot after finish

pool-releases-at-finished

scenarioper work-limits row

Applies when row releases working at is Finished.

Pool Row.id declares that the working slot is freed at finished. The working slot is freed after job-finished, and the slot offer and standing-order scan run after that report.

Given

a successful Instance job in pool Row.id reaching finished

When
  • job-finished is reported
Then
  • the working slot is freed after job-finished
  • the slot offer and standing-order scan run after that report
Diagnostics
  • Instance-count-trace
  • Instance-pool-offer-log
  • Instance-standing-order-scan-log
  • Instance-report-log
Row.id frees the working slot after delivery

pool-releases-at-delivered

scenarioper work-limits row

Applies when row releases working at is Delivered.

Pool Row.id declares that the working slot is freed at delivered. The working slot is freed after job-delivered, and the slot offer and standing-order scan run after that report.

Given

a successful Instance job in pool Row.id reaching delivered

When
  • job-delivered is reported
Then
  • the working slot is freed after job-delivered
  • the slot offer and standing-order scan run after that report
Diagnostics
  • Instance-count-trace
  • Instance-pool-offer-log
  • Instance-standing-order-scan-log
  • Instance-report-log
Row.id keeps separate slots for each place

each-place-pool-assigns-one-place

scenarioper work-limits row

Applies when row scope is Each place.

Pool Row.id keeps separate slots for the places at Row.places declared in and assigns each request through Row.place assignment declared in. Each request uses exactly one place. The test names the addresses and restates nothing from them.

Given

two places from Row.places declared in and requests covered by Row.covers declared in

When
  • Row.place assignment declared in assigns each request
Then
  • every request belongs to exactly one cited place and uses only that place's working slots and waiting slots
  • a free slot at one place does not change another place's slots
Diagnostics
  • Instance-pool-assignment
  • Instance-count-trace
Row.id shares one set of slots

shared-pool-uses-one-count

scenarioper work-limits row

Applies when row scope is Shared.

Every request covered by Row.covers declared in uses the one shared set of slots in pool Row.id. The test names the address and restates nothing from it.

Given

requests covered by Row.covers declared in from every place the adoption can construct

When
  • the requests enter pool Row.id
Then
  • all requests use the same shared working slots and waiting slots
Diagnostics
  • Instance-pool-assignment
  • Instance-count-trace
Row.id offers a free working slot in request order

request-order-pool-offers-in-admission-order

scenarioper work-limits row

Applies when row waiting order is Request order.

Pool Row.id offers a free working slot to eligible jobs in request order. A request enters waiting even with a free working slot when an earlier admitted job is first.

Given

two eligible admitted jobs in pool Row.id with a known admission order

When
  • one working slot becomes free
Then
  • the earlier admitted eligible job receives the first offer
  • a request whose pool has a free working slot still enters waiting when the pool's order places an earlier admitted job first
Diagnostics
  • Instance-pool-offer-log
  • Instance-waiting-order-record
Row.id offers a free working slot in its cited order

game-rule-pool-offers-in-cited-order

scenarioper work-limits row

Applies when row waiting order is Game rule order.

Pool Row.id follows the order named by Row.order declared in, subject to the stop-moment rule that a displaced job is never placed before the job that displaced it. A request enters waiting even with a free working slot when that order places an earlier admitted job first. The test names the address and restates nothing from it.

Given

two eligible admitted jobs in pool Row.id whose order can be distinguished by Row.order declared in

When
  • one working slot becomes free
Then
  • offers follow the order named by Row.order declared in, subject to the stop-moment rule that a displaced job is never placed before the job that displaced it
  • a request whose pool has a free working slot still enters waiting when the pool's order places an earlier admitted job first
Diagnostics
  • Instance-pool-offer-log
  • Instance-waiting-order-record
without a pool every ready job starts

no-pool-means-every-ready-job-starts

scenarioonce

Applies for every adoption

An adoption with no work-limits row starts every otherwise-ready job and never reports job-waiting with a pool cause. For an adoption with pools, this test checks nothing.

Given

the case where Instance has no work-limits row; for an adoption with pools, this test checks nothing

When
  • an otherwise-ready job reaches its start gate
Then
  • every otherwise-ready job starts
  • no job reports job-waiting with a pool cause
Diagnostics
  • Instance-state-trace
  • Instance-report-log
Row.id is scanned in written order until every free working slot is filled

standing-order-scans-are-level-triggered

scenarioper standing-orders row

Applies for every adoption

Standing order Row.id belongs to Row.work limit. After slot offers, scans consult Row.eligible declared in in written order and can create repeated requests from Row.requests job declared in until no row is eligible or no working slot is free. Scans also run at pool creation, when eligibility becomes true, and after the refusal of a request that the scan did not create. The test names the addresses and restates nothing from them.

Given

standing order Row.id attached to pool Row.work limit, with its cited eligibility false and then true and enough free working slots for more than one job

When
  • the pool is created, finishes slot offers, observes eligibility become true, and later receives a refused request that this scan did not create
Then
  • each scan considers rows in written order after slot offers and consults Row.eligible declared in
  • while this row remains eligible, one scan can create more than one request named by Row.requests job declared in until no row is eligible or no working slot is free
  • creation of the pool, eligibility that becomes true, and the stated refusal each cause a scan; the row remains for later scans
Diagnostics
  • Instance-standing-order-scan-log
  • Instance-request-log
  • Instance-count-trace
Row.id is read before the adoption is trusted

read-first-note-precedes-verification

scenarioper read-first row

Applies for every adoption

Before trusting this adoption, the reviewer reads Row.read first for note Row.id. This test names the address and restates nothing from it.

Given

review of the Instance adoption

When
  • the reviewer begins lifecycle verification
Then
  • the reviewer reads Row.read first before accepting results that depend on it
Diagnostics
  • Instance-review-record
Row.id resolves only from Row.from state

failure-row-fires-from-its-state

scenarioper failures row

Applies for every adoption

Failure Row.id can fire only from Row.from state under Row.trigger declared in and reports job-failed once. For a row that declares its own result, that result's own test below applies; for such a row this test checks only the firing state and the report. For a row that omits result, Bind shared result. A failure from finished is always terminal. When a row from finished resolves to a recoverable result, the adoption is invalid, and this test fails. The test names the address and restates nothing from it.

Given

Instance job runs in Row.from state and in each other reachable state where the adoption can offer failure Row.id through Row.trigger declared in

When
  • the trigger is offered in each state
Then
  • the failure fires only from Row.from state, resolves atomically, and reports job-failed once
  • for a row that declares its own result, that result's own test below applies; for such a row this test checks only the firing state and the report
  • for a row that omits result, Bind shared result
  • where Row.from state is finished, the resolved result is job-ruined; when a failure from finished has a recoverable result, the adoption is invalid, and this test fails
Diagnostics
  • Instance-failure-log
  • Instance-state-trace
  • Instance-claim-ledger
  • Instance-resume-point
  • Instance-output-identity
Row.id applies its recoverable result

failure-row-result-recoverable

scenarioper failures row

Applies when row result is Partial inputs or work.

Failure Row.id declares a recoverable result. It settles losses, creates no successful output, frees any waiting slot, stops the same job with cause failure-recovery, and reports job-failed once. Under reset-at-stop the work answer does not apply: a recoverable failure is not an ordinary stop, and step 16 alone settles the loss. The resume point is the start gate from waiting, the prior work point from working, or the already-recorded point from stopped. When a failure from finished has a recoverable result, the adoption is invalid, and this test fails.

Given

failure Row.id resolving from Row.from state under Row.trigger declared in with its declared recoverable result

When
  • the failure settles
Then
  • every named input loss is a strict subset of the current claim, work never falls below none, and the failure creates no successful output; under reset-at-stop the work answer does not apply, because a recoverable failure is not an ordinary stop
  • any waiting slot is freed, and the same job stops with cause failure-recovery and one job-failed report after claim settlement
  • the resume point is the start gate from waiting, the prior work point from working, or the already-recorded point from stopped; when a failure from finished has a recoverable result, the adoption is invalid, and this test fails
Diagnostics
  • Instance-failure-log
  • Instance-state-trace
  • Instance-claim-ledger
  • Instance-resume-point
  • Instance-output-identity
Row.id applies its ruined result

failure-row-result-ruined

scenarioper failures row

Applies when row result is Job ruined.

Failure Row.id declares a ruined result. Cited claim changes settle first, terminal entry frees every slot next, and job-failed follows. The job is terminal and creates no new successful output. The rule at Row.trigger declared in defines the damaged state; this test reads that rule only to confirm the job is terminal.

Given

failure Row.id resolving from Row.from state under Row.trigger declared in with its declared ruined result

When
  • the failure settles
Then
  • cited claim changes settle first, then terminal entry frees every slot, then job-failed is reported
  • the job enters terminal failed, creates no new successful output, returns no claim by failure, and keeps remaining claims assigned unless the cited rule states another result for them
  • where the job row declares new-thing and failure starts from finished, the undelivered output is destroyed; where it declares in-place, the transformation is ruined but the target still exists
  • the rule at Row.trigger declared in defines the damaged state, and this test reads it only to confirm the job is terminal
Diagnostics
  • Instance-failure-log
  • Instance-state-trace
  • Instance-claim-ledger
  • Instance-count-trace
  • Instance-report-log
  • Instance-output-identity
Row.id settles progress claims after failure loss

progress-failure-adjusts-claim-after-loss

scenarioper failures row

Applies when Input claim timing is With progress.

For each recoverable Row.id outcome that changes inputs or work, progress-based settlement applies losses first. With a held claim, work is reduced to the highest point that the remaining claim supports, and the excess claim is released. With a released claim, work is reduced only by the named loss. For a ruined outcome, this test checks nothing. The cited rule is Row.trigger declared in; this test restates nothing from it.

Given

each recoverable Row.id outcome the cited rule can construct with an input loss or work reduction; for a ruined outcome, this test checks nothing

When
  • Row.trigger declared in resolves the failure with the stopped claim held in one run and released in another
Then
  • losses settle first
  • with a held claim, work is reduced to the highest point the remaining claim supports and excess claim is released
  • with a released claim, work is reduced only by the named loss
Diagnostics
  • Instance-claim-ledger
  • Instance-work-before-after
accepted jobs do not fail without a declared failure

no-failure-without-a-failure-row

scenarioonce

Applies for every adoption

An adoption with no failures row never reports job-failed from an accepted or finished job. For an adoption with a failure row, this test checks nothing.

Given

the case where Instance has no failures row; for an adoption with a failure row, this test checks nothing

When
  • accepted and finished jobs are observed
Then
  • no accepted or finished job reports job-failed
Diagnostics
  • Instance-report-log
Row.id takes a claim snapshot and cancels one job

declared-cancellation-settles-one-job

scenarioper cancellations row

Applies for every adoption

Cancellation Row.id is legal from requested, waiting, working, and stopped where those states exist. It takes a snapshot of the claims, frees every slot, Bind return result, enters canceled, and reports job-canceled. It never recreates lost units or undoes finished output. Where this adoption declares no dependent-cancellations row, every later waiting job stays in place. The trigger is cited at Row.trigger declared in; this test restates nothing from it.

Given

Instance jobs in each of requested, waiting, working, and stopped that the adoption can construct, with cancellation Row.id offered through Row.trigger declared in

When
  • each legal cancellation settles
Then
  • a snapshot of the current claim is taken before settlement, every slot is freed, the answer Bind return result, and the job enters canceled before job-canceled
  • no answer returns more than the current claim, recreates a lost unit, or moves an unclaimed input
  • cancellation creates no output and never undoes a finished or delivered output
  • where this adoption declares no dependent-cancellations row, every later waiting job stays in place
Diagnostics
  • Instance-claim-snapshot
  • Instance-claim-ledger
  • Instance-count-trace
  • Instance-report-log
Row.id is legal exactly for a cancellation return chosen by a rule

cancel-return-rule-pairs-with-rule-sized-return

scenarioper cancel-return-rules row

Applies for every adoption

Row Row.id is legal exactly when cancel-return is return-by-rule. Under that answer, the lifecycle consults the rule cited at Row.cancel return declared in. When the row is present under another answer, the adoption is invalid, and this test fails. The test names the address and restates nothing from it.

Given

cancel-return-rules row Row.id in the adoption

When
  • the cancel-return answer is checked
Then
  • the row is legal only under return-by-rule; when the row is present under any other answer, the adoption is invalid, and this test fails
  • the lifecycle consults the rule cited at Row.cancel return declared in under that answer
Diagnostics
  • Instance-claim-snapshot
  • Instance-claim-ledger
a cancellation return chosen by a rule declares a return rule

rule-sized-return-needs-a-return-rule

scenarioonce

Applies when Cancel return is Return by rule.

An adoption answering return-by-rule declares at least one cancel-return-rules row. When it declares none, the adoption is invalid, and this test fails.

Given

an adoption answering return-by-rule

When
  • its cancel-return-rules rows are inspected
Then
  • the adoption declares at least one cancel-return-rules row; when it declares none, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
accepted jobs cannot be canceled without a declared cancellation

no-cancellation-without-a-cancellation-row

scenarioonce

Applies for every adoption

An adoption with no cancellations row never reports job-canceled, and a reviewer confirms that promise before the adoption relies on it. For an adoption with a cancellation row, this test checks nothing.

Given

the case where Instance has no cancellations row; for an adoption with a cancellation row, this test checks nothing

When
  • accepted jobs are observed and the adoption prepares to rely on this promise
Then
  • no accepted job reports job-canceled
Diagnostics
  • Instance-report-log
  • Instance-review-record
Row.id settles later dependent jobs

dependent-cancellation-follows-answer

scenarioper dependent-cancellations row

Applies for every adoption

For dependency Row.id after cancellation Row.cancellation, the adoption Bind dependent result. Completed intermediate jobs and delivered outputs remain. The link is cited at Row.link declared in; this test restates nothing from it.

Given

cancellation Row.cancellation and later waiting jobs connected by the static dependency at Row.link declared in

When
  • the earlier job is canceled before producing the required output
Then
  • the adoption Bind dependent result
  • completed intermediate jobs and delivered outputs remain
Diagnostics
  • Instance-dependency-trace
  • Instance-waiting-order-record
  • Instance-claim-ledger
  • Instance-report-log
the finish gate commits inputs and one output atomically

finish-spends-and-establishes-one-output

scenarioonce

Applies for every adoption

At the finish gate, required claims are spent and one successful output is established in the same commit before job-finished. A compound result is still one unit. For an in-place job, the state change at the site is the delivery; it has no destination capacity and answers never-full. A new thing follows the selected delivery path.

Given

a job in Instance at the finish gate with every required claim and capacity gate satisfied

When
  • the job finishes
Then
  • required claims are spent and exactly one successful output is established atomically before job-finished
  • a compound output remains one delivery unit
  • where the job row declares in-place, the state change at the site is the in-place delivery; an in-place output has no destination capacity, so the adoption answers never-full and no capacity branch is taken; where it declares new-thing, the one output follows the selected delivery rules
Diagnostics
  • Instance-claim-ledger
  • Instance-output-identity
  • Instance-state-trace
  • Instance-report-log
Row.id invokes the selected capacity response

delivery-case-invokes-selected-answer

scenarioper delivery-cases row

Applies for every adoption

When Row.condition declared in establishes delivery case Row.id, the lifecycle applies the selected output-full answer to the whole output: Bind capacity response. The test names the address and restates nothing from it.

Given

a whole Instance output and delivery case Row.id

When
  • the condition at Row.condition declared in holds
Then
  • the lifecycle applies exactly the selected output-full answer to the whole output, without splitting it or inventing another capacity response: Bind capacity response
Diagnostics
  • Instance-delivery-attempts
the normal destination accepts every whole output

normal-destination-never-blocks

generalonce

Applies when Output full is Never full.

Across Inputs scope, under never-full, the normal destination accepts every whole output. An in-place output is delivered by the state change at its site, so no capacity branch exists for it. There is no fallback for blocked capacity. When the destination refuses an output, the adoption is invalid, and this test fails.

Scope

Inputs scope

Holds

under the never-full answer, every successful whole output is accepted without a capacity-blocked state, fallback, or inaccessible held output; an in-place output is delivered by the state change at its site and no capacity branch exists for it; if the capacity promise fails, the adoption is invalid, and this test fails; the lifecycle takes no other branch

Diagnostics
  • Instance-delivery-attempts
a job waits before admission for reserved output room

pre-start-reservation-blocks-admission

scenarioonce

Applies when Output full is Wait before start.

Without room for the whole output, the request stays requested and waits for its cited readmission event. In an adoption that declares no such event, the request can never leave requested. The adoption is then invalid, and the paired existence test fails. Successful admission reserves the whole space atomically and holds it through delivery. An adoption whose destination always has room constructs no block. In that case this test checks nothing. An in-place job answers never-full, so this test never applies to it.

Given

a request for Instance whose whole output does not have reservable room; an adoption whose destination always has room constructs no block, and in that case this test checks nothing; an in-place job answers never-full, so this test never applies to it

When
  • admission is attempted
Then
  • the request remains requested, records no work, and makes no admission-time claim until a cited readmission event retries admission
  • when room exists, the whole output is reserved atomically and the reservation is held through delivery
  • in an adoption that declares no such readmission event, the request can never leave requested; the adoption is then invalid, and the paired existence test fails
Diagnostics
  • Instance-state-trace
  • Instance-reservation-ledger
  • Instance-claim-ledger
a held output remains one inaccessible owned result

held-output-retries-only-on-event

scenarioonce

Applies when Output full is Hold undelivered.

For a new-thing job, a refused normal destination leaves one owned inaccessible output in finished. Inputs stay spent; time alone does not retry; work is not repeated. The first refusal and every refusal on retry report destination-refused. Each cited redelivery event retries without creating a duplicate, and a successful retry reports job-delivered exactly once. An adoption with no such row can never deliver the output. The adoption is then invalid, and the paired existence test fails. An in-place job answers never-full, so this test never applies to it.

Given

a finished Instance job whose normal destination refuses the whole output; an in-place job answers never-full, so this test never applies to it

When
  • time passes and, where the adoption declares one, a cited redelivery event later occurs
Then
  • exactly one owned inaccessible output remains in finished with its inputs spent, and no polling or repeated work occurs
  • each cited event retries the normal destination and no duplicate output appears; the first refusal and every refusal on retry report destination-refused; an adoption with no redelivery event can never deliver the output; the adoption is then invalid, and the paired existence test fails
  • the retry that succeeds reports job-delivered exactly once
Diagnostics
  • Instance-output-location
  • Instance-delivery-attempts
  • Instance-claim-ledger
a held output declares a redelivery event

held-output-needs-a-redelivery-event

scenarioonce

Applies when Output full is Hold undelivered.

An adoption answering hold-undelivered declares at least one redelivery-events row. When it declares none, the adoption is invalid, and this test fails.

Given

an adoption answering hold-undelivered

When
  • its redelivery-events rows are inspected
Then
  • the adoption declares at least one redelivery-events row; when it declares none, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
Row.id is legal exactly for a refused-output retry

redelivery-event-pairs-with-retry-answer

scenarioper redelivery-events row

Applies for every adoption

Row Row.id is legal exactly when output-full is hold-undelivered or try-destinations. After refusal, only Row.redelivery declared in retries delivery, using the same output without repeating work. When the row is present under another answer, the adoption is invalid, and this test fails. The test names the address and restates nothing from it.

Given

redelivery-events row Row.id in the adoption

When
  • the output-full answer is checked and, under hold-undelivered or try-destinations, Row.redelivery declared in occurs after refusal
Then
  • the row is legal only under hold-undelivered or try-destinations; when the row is present under any other answer, the adoption is invalid, and this test fails
  • under either legal answer the lifecycle retries only on the cited event and keeps the same output without repeating work
Diagnostics
  • Instance-event-log
  • Instance-delivery-attempts
  • Instance-output-identity
Row.id is legal exactly for the ordered route

fallback-destination-pairs-with-ordered-route

scenarioper output-destinations row

Applies for every adoption

Fallback row Row.id at Row.destination declared in is legal only when output-full is try-destinations. When the row is present under any other answer, the adoption is invalid, and this test fails.

Given

output-destinations row Row.id in the adoption

When
  • the output-full answer is checked
Then
  • the row is legal only under try-destinations; when the row is present under any other answer, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
Row.id is tried in its written place

fallback-destination-keeps-written-order

scenarioper output-destinations row

Applies when Output full is Try destinations.

The ordered route tries the normal destination, then fallback Row.id at Row.destination declared in in written order. Each refusal reports destination-refused. When this row accepts, it receives the whole output and no later row is tried. The test names the address and restates nothing from it.

Given

one whole output, its normal destination and every fallback before Row.id refusing it, with Row.id able to accept it

When
  • the route reaches Row.destination declared in
Then
  • each refusal before acceptance reports destination-refused with both states finished
  • the whole output is delivered at Row.id, no later fallback is tried, and the output is never split
Diagnostics
  • Instance-delivery-attempts
  • Instance-report-log
  • Instance-output-location
the ordered route tries whole-output destinations in order

ordered-route-keeps-one-output

scenarioonce

Applies when Output full is Try destinations.

For a new-thing job, the route tries the normal destination and every fallback in written order, delivers the whole output to the first place that accepts, and stops there. Each refusal is reported as destination-refused. If all refuse, the same output stays finished without polling and cited redelivery events restart the route. Where every destination can refuse, the adoption declares a redelivery event; a route on which at least one destination cannot refuse the output needs none. An in-place job answers never-full, so this test never applies to it.

Given

a finished Instance output whose normal destination refuses it, with each fallback acceptance pattern the adoption can construct; an in-place job answers never-full, so this test never applies to it

When
  • the route tries the normal destination and fallback rows in written order
Then
  • every refusal reports destination-refused and the first accepting destination receives the whole output
  • no later destination is tried after acceptance and the output is never split
  • if all destinations refuse, the same output stays finished without polling; each cited redelivery event retries from the normal destination, and an adoption with no such event never retries
  • where every destination on the route can refuse the output, the adoption declares a redelivery event; a route on which at least one destination cannot refuse the output needs none
Diagnostics
  • Instance-delivery-attempts
  • Instance-output-identity
  • Instance-report-log
an accepted output is delivered immediately

automatic-delivery-reports-once

scenarioonce

Applies for every adoption

Under the automatic answer, or where delivery-trigger was never asked and delivery is therefore automatic, an accepted output moves from finished to delivered and reports job-delivered exactly once. For an adoption answering on-collection, this test checks nothing. Where the job row declares in-place, this test checks only the single report.

Given

a finished Instance output accepted by its chosen destination under the automatic answer, or where delivery-trigger was never asked and delivery is therefore automatic; for an adoption answering on-collection, this test checks nothing, and where the job row declares in-place, this test checks only the single report

When
  • capacity resolution accepts it
Then
  • the job moves finished to delivered immediately and reports job-delivered exactly once
Diagnostics
  • Instance-state-trace
  • Instance-report-log
Row.id is legal exactly for collection delivery

collection-event-pairs-with-collection-delivery

scenarioper collection-events row

Applies for every adoption

Row Row.id is legal exactly when delivery-trigger is on-collection. Under that answer, the lifecycle consults the rule cited at Row.collection declared in. When the row is present under another answer, the adoption is invalid, and this test fails. The test names the address and restates nothing from it.

Given

collection-events row Row.id in the adoption

When
  • the delivery-trigger answer is checked
Then
  • the row is legal only under on-collection; when the row is present under any other answer, the adoption is invalid, and this test fails
  • the lifecycle consults the rule cited at Row.collection declared in under that answer
Diagnostics
  • Instance-event-log
collection delivery declares a collection event

collection-needs-a-collection-event

scenarioonce

Applies when Delivery trigger is On collection.

An adoption answering on-collection declares at least one collection-events row. When it declares none, the adoption is invalid, and this test fails.

Given

an adoption answering on-collection

When
  • its collection-events rows are inspected
Then
  • the adoption declares at least one collection-events row; when it declares none, the adoption is invalid, and this test fails
Diagnostics
  • Instance-declaration-record
an accepted output remains accessible until collection

collection-delivery-waits-for-event

scenarioonce

Applies when Delivery trigger is On collection.

An accepted output stays accessible at its chosen destination in finished until a cited collection event occurs. That event delivers it and reports job-delivered exactly once. In an adoption that declares no such event, the job can never leave finished. The adoption is then invalid, and the paired existence test fails. When the adoption can construct no accepted output, this test checks nothing.

Given

an accepted Instance output at its chosen destination; when the adoption can construct no accepted output, this test checks nothing

When
  • time passes and, where the adoption declares one, a cited collection event occurs
Then
  • the output remains accessible in finished before the event
  • the event moves it to delivered and job-delivered reports exactly once
  • in an adoption that declares no such collection event, the job can never leave finished; the adoption is then invalid, and the paired existence test fails
Diagnostics
  • Instance-output-location
  • Instance-event-log
  • Instance-report-log
the lifecycle does not retry a refused request

rejection-ends-the-requested-run

scenarioonce

Applies for every adoption

A refusal ends the run of the refused request. The run does not start again when the reason clears: a later retry is a new run that the requester starts, unless a standing order creates it. Where this adoption declares no standing-orders row, no request repeats automatically.

Given

each Instance request that the adoption can construct as refused

When
  • the refusal settles and its cause later clears
Then
  • the run of the refused request remains ended and the lifecycle creates no retry
  • a later retry has a new run created by the requester unless a standing-order scan creates it
  • where this adoption declares no standing-orders row, no request repeats automatically
Diagnostics
  • Instance-run-id-trace
  • Instance-request-log
the lifecycle and settlement order hold for the whole run

lifecycle-holds

generalonce

Applies for every adoption

Across Inputs scope, each transition settles with its claim changes and reports before the next begins. Claim changes precede the report unless a numbered step says otherwise. The stated forward and side paths are the only observed transitions. Instant automatic delivery keeps job-started, job-finished, and job-delivered in one batch. Same-moment order comes from Event resolution, not this contract. The adoption supplies the audit seeds through verification inputs.

Holds

one transition, all of its claim changes, and all of its reports settle before another transition begins; claim changes precede the transition report unless a numbered step states otherwise; an instant start with an accepting destination keeps job-started, job-finished, and job-delivered in one ordered batch with no outside event between them; only the forward path requested to waiting to started to working to finished to delivered, with unvisited states skipped without changing order, the stopped and resume side path, the cancellation side path, terminal failure, and recoverable failure into stopped are observed; same-moment events enter one at a time in the order Event resolution supplies, and this contract adds no ordering rule

Seeds

Inputs seeds

Scope

Inputs scope

Diagnostics
  • Instance-state-trace
  • Instance-claim-ledger
  • Instance-report-log
  • Instance-first-ordering-violation

Use this contract in your package ↑