Run
The executor's record of a commission's run. Each catalogue is projected from one frontier; a selection names one action from that catalogue; arguments are generated for the selected action only. Loom never decides authority or completion.
loom.run is one of loom's bounded contexts. All domains.
Types
ArgumentRequestId
loom.run.ArgumentRequestId wraps Uuid and is not interchangeable with one: the whole value of naming it separately is the crossings the model then refuses.
CatalogueEntry
loom.run.CatalogueEntry is a record of two fields:
- action —
String status—loom.run.CatalogueEntryStatus
CatalogueEntryStatus
loom.run.CatalogueEntryStatus is one of Admissible and ApprovalRequired.
CatalogueId
loom.run.CatalogueId wraps Uuid and is not interchangeable with one: the whole value of naming it separately is the crossings the model then refuses.
CommissionRunId
loom.run.CommissionRunId wraps Uuid and is not interchangeable with one: the whole value of naming it separately is the crossings the model then refuses.
LoopStop
loom.run.LoopStop is one of two shapes, told apart by a kind field — tagged, so a decoder never has to guess which branch it is reading:
budget-unobservable—loom.run.LoopStopBudgetUnobservablemax-input-tokens—loom.run.LoopStopMaxInputTokens
LoopStopBudgetUnobservable
loom.run.LoopStopBudgetUnobservable is a record of two fields:
name—Stringreason—String
LoopStopMaxInputTokens
loom.run.LoopStopMaxInputTokens is a record of two fields:
limit—Integerreported—Integer
SelectionId
loom.run.SelectionId wraps Uuid and is not interchangeable with one: the whole value of naming it separately is the crossings the model then refuses.
SelectionRecordId
loom.run.SelectionRecordId wraps Uuid and is not interchangeable with one: the whole value of naming it separately is the crossings the model then refuses.
SelectionStrategy
loom.run.SelectionStrategy is one of ReasoningModel, FastTyped, Rule and Hybrid.
TurnId
loom.run.TurnId wraps Uuid and is not interchangeable with one: the whole value of naming it separately is the crossings the model then refuses.
One of the types above is reached by nothing else in this system: loom.run.LoopStop. No entity, view, command, event, error or crossing names it, so it is either vocabulary something outside this specification uses or a leftover — and only a person can tell which.
Entities
An entity is what this context is about: something with an identity that outlives any one request, a shape, and a lifecycle. The lifecycle is exhaustive — a move that is not drawn below is a move this specification does not permit, and that is the only way it says so. Every move is labelled with the command that takes it, because a move nothing can trigger is refused rather than drawn.
ActionCatalogue
loom.run.ActionCatalogue.
An instance is identified by catalogue_id, a loom.run.CatalogueId. The name is part of the model and not a convention: a view projects the identity under that name, so a projection inventing its own would disagree with the view.
It holds:
turn_id—loom.run.TurnIdfrontier—Stringcase_revision—Integerentries—List<loom.run.CatalogueEntry>
It declares no relation to another entity, and no other entity names it.
No invariant is declared, so nothing here constrains an instance at rest.
Its state is a loom.run.ActionCatalogue.State, one of Projected. That enum is synthesised from the lifecycle rather than declared beside it, so the states a view's filter compares and the states drawn below cannot disagree.
An instance is created in Projected. Projected is terminal, so an instance may rest there forever. That is declared rather than inferred from having no way out: an entity that cannot leave a state is either finished or stuck, and only its author knows which.
It declares no moves, so nothing changes its state once it exists.
It has one state, so there is no move to permit or to forbid.
One view projects it: Catalogues.
ArgumentRequest
loom.run.ArgumentRequest.
An instance is identified by argument_request_id, a loom.run.ArgumentRequestId. The name is part of the model and not a convention: a view projects the identity under that name, so a projection inventing its own would disagree with the view.
It holds:
selection_id—loom.run.SelectionId
It references at most one Selection, as selection, carried by ArgumentRequest.selection_id.
No invariant is declared, so nothing here constrains an instance at rest.
Its state is a loom.run.ArgumentRequest.State, one of Requested. That enum is synthesised from the lifecycle rather than declared beside it, so the states a view's filter compares and the states drawn below cannot disagree.
An instance is created in Requested. Requested is terminal, so an instance may rest there forever. That is declared rather than inferred from having no way out: an entity that cannot leave a state is either finished or stuck, and only its author knows which.
It declares no moves, so nothing changes its state once it exists.
It has one state, so there is no move to permit or to forbid.
No view projects it, so nothing outside this context is promised a way to observe one.
Selection
loom.run.Selection.
An instance is identified by selection_id, a loom.run.SelectionId. The name is part of the model and not a convention: a view projects the identity under that name, so a projection inventing its own would disagree with the view.
It holds:
catalogue_id—loom.run.CatalogueId- action —
String confidence—Optional<Decimal>, which may be absentstrategy—loom.run.SelectionStrategycase_revision—Integerreplaced_by—Optional<loom.run.SelectionId>, which may be absent
It references at most one ActionCatalogue, as catalogue, carried by Selection.catalogue_id. It references at most one Selection, as replacement, carried by Selection.replaced_by. It owns at most one SelectionRecord, as telemetry, carried by SelectionRecord.selection_id.
No invariant is declared, so nothing here constrains an instance at rest.
Its state is a loom.run.Selection.State, one of Admitted, Overruled, Refused and Selected. That enum is synthesised from the lifecycle rather than declared beside it, so the states a view's filter compares and the states drawn below cannot disagree.
An instance is created in Selected. Admitted, Overruled and Refused are terminal, so an instance may rest there forever. That is declared rather than inferred from having no way out: an entity that cannot leave a state is either finished or stuck, and only its author knows which.
Each move is taken by a declared command outcome, and a move nothing takes is refused as missing_causation rather than left as a state change nobody can trigger:
admit— taken byloom.run.RevalidateSelectionon itsadmittedoutcomerefuse— taken byloom.run.RevalidateSelectionon itsstale-revisionoutcome andloom.run.RevalidateSelectionon itsnot-in-frontieroutcomeoverrule— taken byloom.run.OverruleSelectionon itsoverruledoutcome
An instance is brought into existence by loom.run.SelectAction on its selected outcome.
Illegal transitions are illegal by absence: no rule forbids them, there is simply no arrow, because a rule would be a second place for the same truth to live. A diagram cannot show an absence, so the pairs it does not connect are listed here, derived from the same transitions — anything named below is a move this specification does not permit.
Admittedmay not becomeOverruledAdmittedmay not becomeRefusedAdmittedmay not becomeSelectedOverruledmay not becomeAdmittedOverruledmay not becomeRefusedOverruledmay not becomeSelectedRefusedmay not becomeAdmittedRefusedmay not becomeOverruledRefusedmay not becomeSelected
One view projects it: Selections.
SelectionRecord
loom.run.SelectionRecord.
An instance is identified by selection_record_id, a loom.run.SelectionRecordId. The name is part of the model and not a convention: a view projects the identity under that name, so a projection inventing its own would disagree with the view.
It holds:
selection_id—loom.run.SelectionIdstrategy—loom.run.SelectionStrategycandidate_count—Integerchosen_action—Stringconfidence—Optional<Decimal>, which may be absentfell_back_to—Optional<loom.run.SelectionStrategy>, which may be absentlatency_ms—Integerinput_tokens—Integeroutput_tokens—Integer
Its selection_id is what Selection owns it by, as telemetry.
No invariant is declared, so nothing here constrains an instance at rest.
Its state is a loom.run.SelectionRecord.State, one of Recorded. That enum is synthesised from the lifecycle rather than declared beside it, so the states a view's filter compares and the states drawn below cannot disagree.
An instance is created in Recorded. Recorded is terminal, so an instance may rest there forever. That is declared rather than inferred from having no way out: an entity that cannot leave a state is either finished or stuck, and only its author knows which.
It declares no moves, so nothing changes its state once it exists.
It has one state, so there is no move to permit or to forbid.
One view projects it: SelectionRecords.
Views
A view is what the outside world is promised it can observe. Each one says which instances it contains and how soon it reflects a command that has already returned, because "you can read this" without "how soon" is the promise every flaky suite is built on.
Catalogues
loom.run.Catalogues.
It reads ActionCatalogue.
It contains every instance of that entity: no filter narrows it, which is a decision somebody made and not a line somebody omitted.
It exposes:
catalogue_id—loom.run.CatalogueIdcase_revision—Integerstate—loom.run.ActionCatalogue.State
It declares no order, so the rows come back in whatever order the implementation has, and two reads may disagree.
Read-your-writes: it is current the moment the command that changed it returns. A caller that has just created an invoice and cannot see it in here has been told a lie about what it did.
A generated scenario asserts it once, immediately after the command: a view promising this and not keeping the promise has to fail the suite rather than be retried until it passes.
SelectionRecords
loom.run.SelectionRecords.
It reads SelectionRecord.
It contains every instance of that entity: no filter narrows it, which is a decision somebody made and not a line somebody omitted.
It exposes:
selection_record_id—loom.run.SelectionRecordIdselection_id—loom.run.SelectionIdstrategy—loom.run.SelectionStrategycandidate_count—Integerchosen_action—Stringfell_back_to—Optional<loom.run.SelectionStrategy>, which may be absentlatency_ms—Integerinput_tokens—Integeroutput_tokens—Integerstate—loom.run.SelectionRecord.State
It declares no order, so the rows come back in whatever order the implementation has, and two reads may disagree.
Read-your-writes: it is current the moment the command that changed it returns. A caller that has just created an invoice and cannot see it in here has been told a lie about what it did.
A generated scenario asserts it once, immediately after the command: a view promising this and not keeping the promise has to fail the suite rather than be retried until it passes.
Selections
loom.run.Selections.
It reads Selection.
It contains every instance of that entity: no filter narrows it, which is a decision somebody made and not a line somebody omitted.
It exposes:
selection_id—loom.run.SelectionIdcatalogue_id—loom.run.CatalogueId- action —
String strategy—loom.run.SelectionStrategycase_revision—Integerreplaced_by—Optional<loom.run.SelectionId>, which may be absentstate—loom.run.Selection.State
It declares no order, so the rows come back in whatever order the implementation has, and two reads may disagree.
Read-your-writes: it is current the moment the command that changed it returns. A caller that has just created an invoice and cannot see it in here has been told a lie about what it did.
A generated scenario asserts it once, immediately after the command: a view promising this and not keeping the promise has to fail the suite rather than be retried until it passes.
Commands
OverruleSelection
loom.run.OverruleSelection.
It takes:
selection_id—loom.run.SelectionIdreplacement_id—loom.run.SelectionId
It has two outcomes.
overruled — The default branch, taken when no other outcome's condition matched. It moves a loom.run.Selection from Selected to Overruled, along the declared move overrule. The instance is the one named by the input field selection_id. It emits loom.run.SelectionOverruled. It sets replaced_by from input.replacement_id. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — Taken when the subject is resting in a state none of this command's moves start from — a loom.run.Selection in Admitted, Overruled and Refused, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports loom.run.SelectionStateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
ProjectCatalogue
loom.run.ProjectCatalogue.
It takes:
catalogue_id—loom.run.CatalogueIdturn_id—loom.run.TurnIdfrontier—Stringcase_revision—Integerentries—List<loom.run.CatalogueEntry>
It has two outcomes.
catalogue-exists — Taken when a record already carries the identity the command's creating branch would create, and no input-guarded refusal applies. No entity in this specification changes. It reports loom.run.CatalogueExists, carrying catalogue_id. It emits nothing. A test reaches it by sending the command twice with one identity: the first call creates the record, the second is answered by this branch.
projected — The default branch, taken when no other outcome's condition matched. It creates a loom.run.ActionCatalogue, which starts in Projected. The new instance's identity is published as catalogue_id on loom.run.CatalogueProjected. It emits loom.run.CatalogueProjected. It sets turn_id from input.turn_id, frontier from input.frontier, case_revision from input.case_revision and entries from input.entries. A test reaches it by constructing an input that satisfies no other outcome's condition.
RecordSelection
loom.run.RecordSelection.
It takes:
selection_record_id—loom.run.SelectionRecordIdselection_id—loom.run.SelectionIdstrategy—loom.run.SelectionStrategycandidate_count—Integerchosen_action—Stringconfidence—Optional<Decimal>, which may be absentfell_back_to—Optional<loom.run.SelectionStrategy>, which may be absentlatency_ms—Integerinput_tokens—Integeroutput_tokens—Integer
It has three outcomes.
record-exists — Taken when a record already carries the identity the command's creating branch would create, and no input-guarded refusal applies. No entity in this specification changes. It reports loom.run.SelectionRecordExists, carrying selection_record_id. It emits nothing. A test reaches it by sending the command twice with one identity: the first call creates the record, the second is answered by this branch.
selection-unknown — Taken when no loom.run.Selection carries the identity input.selection_id names. No entity in this specification changes. It reports loom.run.SelectionNotFound, carrying selection_id. It emits nothing. A test reaches it by arranging the row of the other entity the input names, or its absence, and sending the command for it.
recorded — The default branch, taken when no other outcome's condition matched. It creates a loom.run.SelectionRecord, which starts in Recorded. The new instance's identity is published as selection_record_id on loom.run.SelectionRecorded. It emits loom.run.SelectionRecorded. It sets selection_id from input.selection_id, strategy from input.strategy, candidate_count from input.candidate_count, chosen_action from input.chosen_action, confidence from input.confidence, fell_back_to from input.fell_back_to, latency_ms from input.latency_ms, input_tokens from input.input_tokens and output_tokens from input.output_tokens. A test reaches it by constructing an input that satisfies no other outcome's condition.
RequestArguments
loom.run.RequestArguments.
It takes:
argument_request_id—loom.run.ArgumentRequestIdselection_id—loom.run.SelectionId
It has three outcomes.
selection-unknown — Taken when no loom.run.Selection carries the identity input.selection_id names. No entity in this specification changes. It reports loom.run.SelectionNotFound, carrying selection_id. It emits nothing. A test reaches it by arranging the row of the other entity the input names, or its absence, and sending the command for it.
selection-not-selected — Taken when the loom.run.Selection that input.selection_id names exists and its stored fields satisfy state != Selected. No entity in this specification changes. It reports loom.run.SelectionNotSelected, carrying selection_id. It emits nothing. A test reaches it by arranging the row of the other entity the input names, or its absence, and sending the command for it.
requested — The default branch, taken when no other outcome's condition matched. It creates a loom.run.ArgumentRequest, which starts in Requested. The new instance's identity is published as argument_request_id on loom.run.ArgumentsRequested. It emits loom.run.ArgumentsRequested. It sets selection_id from input.selection_id. A test reaches it by constructing an input that satisfies no other outcome's condition.
RevalidateSelection
loom.run.RevalidateSelection.
It takes:
selection_id—loom.run.SelectionIdcase_revision—Integerfrontier_actions—List<String>
It has four outcomes.
stale-revision — Taken when the existing subject's stored fields satisfy case_revision != input.case_revision. It moves a loom.run.Selection from Selected to Refused, along the declared move refuse. The instance is the one named by the input field selection_id. It emits loom.run.SelectionStale. A test establishes and independently observes the subject enum fact before selecting this branch.
not-in-frontier — Decided outside the input: the frontier action ids in the input do not list the selection's action. No predicate over the input reaches this branch, and saying when: false instead would have claimed it is unreachable, which is a different and false statement. It moves a loom.run.Selection from Selected to Refused, along the declared move refuse. The instance is the one named by the input field selection_id. It emits loom.run.SelectionNotInFrontier. A test reaches it by injecting the declared fault, because no input can.
admitted — The default branch, taken when no other outcome's condition matched. It moves a loom.run.Selection from Selected to Admitted, along the declared move admit. The instance is the one named by the input field selection_id. It emits loom.run.SelectionAdmitted. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — Taken when the subject is resting in a state none of this command's moves start from — a loom.run.Selection in Admitted, Overruled and Refused, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports loom.run.SelectionStateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
SelectAction
loom.run.SelectAction.
It takes:
selection_id—loom.run.SelectionIdcatalogue_id—loom.run.CatalogueId- action —
String confidence—Optional<Decimal>, which may be absentstrategy—loom.run.SelectionStrategycase_revision—Integer
It has five outcomes.
selection-exists — Taken when a record already carries the identity the command's creating branch would create, and no input-guarded refusal applies. No entity in this specification changes. It reports loom.run.SelectionExists, carrying selection_id. It emits nothing. A test reaches it by sending the command twice with one identity: the first call creates the record, the second is answered by this branch.
catalogue-unknown — Taken when no loom.run.ActionCatalogue carries the identity input.catalogue_id names. No entity in this specification changes. It reports loom.run.CatalogueNotFound, carrying catalogue_id. It emits nothing. A test reaches it by arranging the row of the other entity the input names, or its absence, and sending the command for it.
not-in-catalogue — Taken when the loom.run.ActionCatalogue that input.catalogue_id names exists and its stored fields satisfy not (exists entry in entries: (entry.action == input.action)). No entity in this specification changes. It reports loom.run.ActionNotInCatalogue, carrying action. It emits nothing. A test reaches it by arranging the row of the other entity the input names, or its absence, and sending the command for it.
revision-mismatch — Taken when the loom.run.ActionCatalogue that input.catalogue_id names exists and its stored fields satisfy case_revision != input.case_revision. No entity in this specification changes. It reports loom.run.CatalogueRevisionMismatch, carrying catalogue_id, case_revision and catalogue_revision. It emits nothing. A test reaches it by arranging the row of the other entity the input names, or its absence, and sending the command for it.
selected — The default branch, taken when no other outcome's condition matched. It creates a loom.run.Selection, which starts in Selected. The new instance's identity is published as selection_id on loom.run.ActionSelected. It emits loom.run.ActionSelected. It sets catalogue_id from input.catalogue_id, action from input.action, confidence from input.confidence, strategy from input.strategy and case_revision from input.case_revision. A test reaches it by constructing an input that satisfies no other outcome's condition.
Events
ActionSelected
loom.run.ActionSelected.
It carries:
selection_id—loom.run.SelectionIdcatalogue_id—loom.run.CatalogueId- action —
String
Emitted by loom.run.SelectAction on its selected outcome.
Nothing in this system reacts to it.
ArgumentsRequested
loom.run.ArgumentsRequested.
It carries:
argument_request_id—loom.run.ArgumentRequestIdselection_id—loom.run.SelectionId
Emitted by loom.run.RequestArguments on its requested outcome.
Nothing in this system reacts to it.
CatalogueProjected
loom.run.CatalogueProjected.
It carries:
catalogue_id—loom.run.CatalogueIdturn_id—loom.run.TurnIdcase_revision—Integer
Emitted by loom.run.ProjectCatalogue on its projected outcome.
Nothing in this system reacts to it.
SelectionAdmitted
loom.run.SelectionAdmitted.
It carries:
selection_id—loom.run.SelectionId
Emitted by loom.run.RevalidateSelection on its admitted outcome.
Nothing in this system reacts to it.
SelectionNotInFrontier
loom.run.SelectionNotInFrontier.
It carries:
selection_id—loom.run.SelectionId- action —
String
Emitted by loom.run.RevalidateSelection on its not-in-frontier outcome.
Nothing in this system reacts to it.
SelectionOverruled
loom.run.SelectionOverruled.
It carries:
selection_id—loom.run.SelectionIdreplacement_id—loom.run.SelectionId
Emitted by loom.run.OverruleSelection on its overruled outcome.
Nothing in this system reacts to it.
SelectionRecorded
loom.run.SelectionRecorded.
It carries:
selection_record_id—loom.run.SelectionRecordIdselection_id—loom.run.SelectionIdstrategy—loom.run.SelectionStrategyfell_back_to—Optional<loom.run.SelectionStrategy>, which may be absent
Emitted by loom.run.RecordSelection on its recorded outcome.
Nothing in this system reacts to it.
SelectionStale
loom.run.SelectionStale.
It carries:
selection_id—loom.run.SelectionIdcatalogue_revision—Integercase_revision—Integer
Emitted by loom.run.RevalidateSelection on its stale-revision outcome.
Nothing in this system reacts to it.
Errors
ActionNotInCatalogue
It carries:
- action —
String
Reported by loom.run.SelectAction on its not-in-catalogue outcome.
CatalogueExists
It carries:
catalogue_id—loom.run.CatalogueId
Reported by loom.run.ProjectCatalogue on its catalogue-exists outcome.
CatalogueNotFound
It carries:
catalogue_id—loom.run.CatalogueId
Reported by loom.run.SelectAction on its catalogue-unknown outcome.
CatalogueRevisionMismatch
It carries:
catalogue_id—loom.run.CatalogueIdcase_revision—Integercatalogue_revision—Integer
Reported by loom.run.SelectAction on its revision-mismatch outcome.
SelectionExists
It carries:
selection_id—loom.run.SelectionId
Reported by loom.run.SelectAction on its selection-exists outcome.
SelectionNotFound
It carries:
selection_id—loom.run.SelectionId
Reported by loom.run.RecordSelection on its selection-unknown outcome.
Reported by loom.run.RequestArguments on its selection-unknown outcome.
SelectionNotSelected
It carries:
selection_id—loom.run.SelectionId
Reported by loom.run.RequestArguments on its selection-not-selected outcome.
SelectionRecordExists
It carries:
selection_record_id—loom.run.SelectionRecordId
Reported by loom.run.RecordSelection on its record-exists outcome.
SelectionStateConflict
It carries:
state—loom.run.Selection.State
Reported by loom.run.OverruleSelection on its wrong-state outcome.
Reported by loom.run.RevalidateSelection on its wrong-state outcome.
Generated from loom v1 · model digest 687ce3d39bdb34d56d1fe0c221f558534fa9c3e8eda9e34862b5b742d61331e9 · contract digest slice-sha256/2:8b6042b044adc1f4bb583b5718f77936ed1c49181356f7cacfaaa560774261ae. Do not edit this file; change the specification and regenerate it with task docs-generate.