Skip to main content

tool_contracts

Typed specification

Generated by the pinned ess generate --kind docs from ess. Structural validation establishes consistency; behaviour, storage and cross-record predicates remain implementation obligations.

A tool-contract/1 document an instance's descriptor revision publishes for its admitted operations, with the profile authored beside the adapter, and the refusals of its publisher.

connectors.tool_contracts is one of connectors's bounded contexts. Back to the index.

Types​

Bound​

connectors.tool_contracts.Bound is a record of two fields:

  • default — Optional<Integer>, which may be absent
  • max — Integer

Bounds​

connectors.tool_contracts.Bounds is a record of two fields:

  • timeout_ms — connectors.tool_contracts.Bound
  • output_bytes — Optional<connectors.tool_contracts.Bound>, which may be absent

Consequence​

connectors.tool_contracts.Consequence is one of money, delete, send_external, irreversible and sensitive_data.

Determinism​

connectors.tool_contracts.Determinism is one of deterministic and nondeterministic.

Effect​

connectors.tool_contracts.Effect is one of read, write, process, network, secret, external and human_visible.

Idempotency​

connectors.tool_contracts.Idempotency is one of idempotent, keyed and non_idempotent.

OperationToolDeclaration​

connectors.tool_contracts.OperationToolDeclaration is a record of four fields:

  • operation — String
  • name — String
  • profile — Optional<connectors.tool_contracts.ToolProfile>, which may be absent
  • omit — List<String>

Placement​

connectors.tool_contracts.Placement is one of local, confined and container.

PublicationDecision​

connectors.tool_contracts.PublicationDecision is one of publish, profile_missing, schema_unrepresentable, risk_below_floor, profile_invalid and name_invalid.

Risk​

connectors.tool_contracts.Risk is one of none, low, medium, high and critical.

ToolProfile​

connectors.tool_contracts.ToolProfile is a record of nine fields:

  • effects — List<connectors.tool_contracts.Effect>
  • consequences — List<connectors.tool_contracts.Consequence>
  • risk — connectors.tool_contracts.Risk
  • idempotency — connectors.tool_contracts.Idempotency
  • determinism — connectors.tool_contracts.Determinism
  • bounds — connectors.tool_contracts.Bounds
  • placement — connectors.tool_contracts.Placement
  • capability — String
  • output_untrusted — Boolean

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.

ToolContract​

connectors.tool_contracts.ToolContract.

An instance is identified by contract_ref, a String. 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:

  • instance — String
  • descriptor_revision — String
  • toolset — String
  • version — String
  • operations — List<connectors.tool_contracts.OperationToolDeclaration>
  • digest — String

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 connectors.tool_contracts.ToolContract.State, one of Published. 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 Published. Published 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: ToolContracts.

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.

ToolContracts​

connectors.tool_contracts.ToolContracts.

It reads ToolContract.

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:

  • contract_ref — String
  • instance — String
  • descriptor_revision — String
  • toolset — String
  • version — String
  • digest — String
  • state — connectors.tool_contracts.ToolContract.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​

PublishToolContract​

connectors.tool_contracts.PublishToolContract.

It takes:

  • decision — connectors.tool_contracts.PublicationDecision
  • instance — String
  • descriptor_revision — String
  • toolset — String
  • version — String
  • operations — List<connectors.tool_contracts.OperationToolDeclaration>
  • digest — String

It has six outcomes.

published — Taken when decision == publish holds of the input. It creates a connectors.tool_contracts.ToolContract, which starts in Published. The new instance's identity is published as contract_ref on connectors.tool_contracts.ToolContractPublished. It emits connectors.tool_contracts.ToolContractPublished. It sets instance from input.instance, descriptor_revision from input.descriptor_revision, toolset from input.toolset, version from input.version, operations from input.operations and digest from input.digest. A test reaches it by constructing an input that satisfies that condition.

profile-missing — Taken when decision == profile_missing holds of the input. No entity in this specification changes. It reports connectors.tool_contracts.ProfileMissing. It emits nothing. A test reaches it by constructing an input that satisfies that condition.

schema-unrepresentable — Taken when decision == schema_unrepresentable holds of the input. No entity in this specification changes. It reports connectors.tool_contracts.SchemaUnrepresentable. It emits nothing. A test reaches it by constructing an input that satisfies that condition.

risk-below-floor — Taken when decision == risk_below_floor holds of the input. No entity in this specification changes. It reports connectors.tool_contracts.RiskBelowFloor. It emits nothing. A test reaches it by constructing an input that satisfies that condition.

profile-invalid — Taken when decision == profile_invalid holds of the input. No entity in this specification changes. It reports connectors.tool_contracts.ProfileInvalid. It emits nothing. A test reaches it by constructing an input that satisfies that condition.

name-invalid — The default branch, taken when no other outcome's condition matched. No entity in this specification changes. It reports connectors.tool_contracts.NameInvalid. It emits nothing. A test reaches it by constructing an input that satisfies no other outcome's condition.

Events​

ToolContractPublished​

connectors.tool_contracts.ToolContractPublished.

It carries:

  • contract_ref — String
  • toolset — String
  • version — String

Emitted by connectors.tool_contracts.PublishToolContract on its published outcome.

Nothing in this system reacts to it.

Errors​

NameInvalid​

It carries nothing beyond its name, so a caller can tell what went wrong and not which value caused it.

Reported by connectors.tool_contracts.PublishToolContract on its name-invalid outcome.

ProfileInvalid​

It carries nothing beyond its name, so a caller can tell what went wrong and not which value caused it.

Reported by connectors.tool_contracts.PublishToolContract on its profile-invalid outcome.

ProfileMissing​

It carries nothing beyond its name, so a caller can tell what went wrong and not which value caused it.

Reported by connectors.tool_contracts.PublishToolContract on its profile-missing outcome.

RiskBelowFloor​

It carries nothing beyond its name, so a caller can tell what went wrong and not which value caused it.

Reported by connectors.tool_contracts.PublishToolContract on its risk-below-floor outcome.

SchemaUnrepresentable​

It carries nothing beyond its name, so a caller can tell what went wrong and not which value caused it.

Reported by connectors.tool_contracts.PublishToolContract on its schema-unrepresentable outcome.

Actors​

An actor is who may ask this context for something. Every grant below points at a command this specification declares — a grant is a resolved reference, so "may invoke" something nobody wrote is not a permission this model can express, and an authorisation that authorises nothing cannot ship quietly.

LocalHost​

connectors.tool_contracts.LocalHost.

It may invoke PublishToolContract.


Generated from connectors v1 · model digest e1e1672d0af4753cb8f2da6c0b22a7f6ae8ce9f7abc168f86169babdf1325787 · contract digest slice-sha256/2:754131bc06736d946fc4d69f09f78b7a0fc404953a7db8e125200a32f699b5ab. Do not edit this file; change the specification and regenerate it with ess generate.