Skip to content
Platform / Actions

Define the changes your business allows.

Give business operations typed inputs, eligibility rules, and explicit effects. Preview the change, require review when appropriate, and check again before applying it.

Explore ActionsInspect source

What can change, and under which rules?

Input
Typed values and object references
Eligibility
Current state, inputs, and evidence
Review
Required by the Action’s own rule
Effects
A bounded, inspectable change plan

A business operation, with its rules attached.

Inspect the effects of activating an agreement, then see how changed evidence makes a proposal stale.

Action plannerGuided example · sample data

ActivateSignedAgreement

Activate only when the signed document revision and evidence match the request.

Target
SignatureRequest / SIG-1042
Document input
v3
Current revision
v3
Review rule
not required
Eligibility is checked at execution.

Proposed changes

Not planned
PropertyBeforeAfter
Request statussigned
Case statusawaiting_signature
Supplier activefalse

Prepare a plan to inspect the exact proposed effects.

Browser illustration · no business records are changed.How planning works

How Actions work.

Explore supplier onboarding

Name the business operation.

Activate a supplier. Accept a quote. Record an extraction. Each Action names a business transition and declares the inputs and object state it needs.

Keep rules with the change.

Define who may act, when the target is eligible, which evidence is required, and the effects the operation may produce. Interfaces and automated callers use that same operation.

Preview, then apply.

Inspect the proposed effects before execution. Platform changes and their Action outcome commit together. External requests have separate queued, delivered, or failed receipts.

Review the proposal that will run.

The Action’s rule decides whether review is needed. Before a change is applied, authority, evidence, and relevant world state are checked again. Changed facts can require a new plan.

Follow it into the source.

An exact excerpt from the repository, with the complete source file available to inspect and download.

Define agreement Actions go
func signatureActions() []product.Action {	yes, no := policy(algebra.True()), policy(algebra.False())	pending := algebra.In(algebra.FieldRef("target", "status"), algebra.Literal(text("requested")), algebra.Literal(text("sending")), algebra.Literal(text("sent")))	requestAllowed := policy(algebra.Compare(algebra.CompareEq, algebra.FieldRef("target", "status"), algebra.Literal(text("approved"))))	return []product.Action{		product.NewAction(product.Action{Name: "RequestSignature", Label: "Request agreement signature", Target: "OnboardingCase", Inputs: []product.ActionInput{{Name: "request_id", Type: "string", MinimumLength: 1}, {Name: "document", Type: "file"}, {Name: "document_revision", Type: "integer", Minimum: intPointer(1)}, {Name: "signer", Type: "string", MinimumLength: 3}, {Name: "requested_at", Type: "timestamp"}, {Name: "reminder_at", Type: "timestamp"}, {Name: "expires_at", Type: "timestamp"}}, Programs: deferred("request_signature"), Ceiling: product.ProgramCeiling{Reads: []product.ProgramRead{read("target", "case_id"), read("target", "supplier_id"), read("target", "status"), read("input", "request_id"), read("input", "document"), read("input", "document_revision"), read("input", "signer"), read("input", "requested_at"), read("input", "reminder_at"), read("input", "expires_at")}, Dependencies: []string{"OnboardingCase", "SignatureRequest"}, Effects: []product.ProgramEffectPermission{permission("create_object", "SignatureRequest", "case_id", "supplier_id", "signer", "document_file_id", "document_revision", "requested_at", "reminder_at", "expires_at", "status", "delivery_id", "signature_evidence_file_id"), permission("set_properties", "OnboardingCase", "status"), permission("start_workflow", "CollectSignature", "input")}, MaxEffects: 3, MaxValueBytes: 32768}, AllowedFor: yes, AllowedIf: requestAllowed, RequiresReview: yes}),		product.NewAction(product.Action{Name: "SendSignatureRequest", Label: "Send signature request", Description: "Queue the signature request for delivery. The round becomes sending; only the provider's acknowledgement makes it sent.", Target: "SignatureRequest", Programs: deferred("send_signature_request"), Ceiling: signatureDeliveryCeiling(true), AllowedFor: yes, AllowedIf: policy(algebra.Compare(algebra.CompareEq, algebra.FieldRef("target", "status"), algebra.Literal(text("requested")))), RequiresReview: no}),		product.NewAction(product.Action{Name: "ConfirmSignatureDelivery", Label: "Confirm signature delivery", Description: "Record the signature provider's own acknowledged delivery identity. This is the evidence that turns a sending round into a sent one.", DeniedReason: "Only a round whose delivery is still in flight can be confirmed.", Target: "SignatureRequest", Inputs: []product.ActionInput{{Name: "delivery_id", Type: "string", MinimumLength: 1, Label: "Delivery", Doc: "The identity the signature provider acknowledged for this exact delivery."}}, Programs: deferred("confirm_signature_delivery"), Ceiling: product.ProgramCeiling{Reads: []product.ProgramRead{read("target", "request_id"), read("target", "status"), read("input", "delivery_id")}, Dependencies: []string{"SignatureRequest"}, Effects: []product.ProgramEffectPermission{permission("set_properties", "SignatureRequest", "status", "delivery_id")}, MaxEffects: 1, MaxValueBytes: 8192}, AllowedFor: yes, AllowedIf: policy(algebra.Compare(algebra.CompareEq, algebra.FieldRef("target", "status"), algebra.Literal(text("sending")))), RequiresReview: no}),		product.NewAction(product.Action{Name: "SendSignatureReminder", Label: "Send signature reminder", Target: "SignatureRequest", Programs: deferred("send_signature_reminder"), Ceiling: signatureDeliveryCeiling(false), AllowedFor: yes, AllowedIf: policy(pending), RequiresReview: no}),		product.NewAction(product.Action{Name: "AcceptSignature", Label: "Accept signature evidence", Target: "SignatureRequest", Inputs: []product.ActionInput{{Name: "document_revision", Type: "integer"}, {Name: "signature_evidence", Type: "file"}}, Programs: deferred("accept_signature"), Ceiling: product.ProgramCeiling{Reads: signatureReads(read("target", "request_id"), read("target", "status"), read("target", "document_revision"), read("target", "expires_at"), read("input", "document_revision"), read("input", "signature_evidence")), Dependencies: []string{"SignatureRequest"}, Effects: []product.ProgramEffectPermission{permission("set_properties", "SignatureRequest", "status", "signature_evidence_file_id"), permission("emit", signatureChanged)}, MaxEffects: 2, MaxValueBytes: 16384}, AllowedFor: yes, AllowedIf: policy(algebra.And(pending, algebra.Compare(algebra.CompareEq, algebra.FieldRef("target", "document_revision"), algebra.FieldRef("input", "document_revision")), algebra.Compare(algebra.CompareLT, algebra.BasisTime(), algebra.FieldRef("target", "expires_at")))), RequiresReview: yes}),		product.NewAction(product.Action{Name: "ExpireSignatureRequest", Label: "Expire unsigned request", Target: "SignatureRequest", Programs: deferred("expire_signature"), Ceiling: product.ProgramCeiling{Reads: signatureReads(read("target", "request_id"), read("target", "case_id"), read("target", "status"), read("target", "expires_at")), Dependencies: []string{"SignatureRequest", "OnboardingCase"}, Effects: []product.ProgramEffectPermission{permission("set_properties", "SignatureRequest", "status"), permission("set_properties", "OnboardingCase", "status"), permission("emit", signatureChanged)}, MaxEffects: 3, MaxValueBytes: 8192}, AllowedFor: yes, AllowedIf: policy(algebra.And(pending, algebra.Compare(algebra.CompareGTE, algebra.BasisTime(), algebra.FieldRef("target", "expires_at")))), RequiresReview: no}),		product.NewAction(product.Action{Name: "CancelSignatureRequest", Label: "Cancel signature request", Target: "SignatureRequest", Programs: deferred("cancel_signature"), Ceiling: product.ProgramCeiling{Reads: []product.ProgramRead{read("target", "request_id"), read("target", "case_id"), read("target", "status")}, Dependencies: []string{"SignatureRequest", "OnboardingCase"}, Effects: []product.ProgramEffectPermission{permission("set_properties", "SignatureRequest", "status"), permission("set_properties", "OnboardingCase", "status"), permission("emit", signatureChanged)}, MaxEffects: 3, MaxValueBytes: 8192}, AllowedFor: yes, AllowedIf: policy(pending), RequiresReview: yes}),		product.NewAction(product.Action{Name: "ActivateSignedAgreement", Label: "Activate signed agreement", Target: "SignatureRequest", Inputs: []product.ActionInput{{Name: "document_revision", Type: "integer"}, {Name: "signature_evidence", Type: "file"}}, Programs: deferred("activate_signed_agreement"), Ceiling: product.ProgramCeiling{Reads: []product.ProgramRead{read("target", "request_id"), read("target", "case_id"), read("target", "supplier_id"), read("target", "status"), read("target", "document_revision"), read("target", "signature_evidence_file_id"), read("input", "document_revision"), read("input", "signature_evidence")}, Dependencies: []string{"SignatureRequest", "OnboardingCase", "Supplier"}, Effects: []product.ProgramEffectPermission{permission("set_properties", "SignatureRequest", "status"), permission("set_properties", "OnboardingCase", "status"), permission("set_properties", "Supplier", "is_active")}, MaxEffects: 3, MaxValueBytes: 16384}, AllowedFor: yes, AllowedIf: policy(algebra.And(algebra.Compare(algebra.CompareEq, algebra.FieldRef("target", "status"), algebra.Literal(text("signed"))), algebra.Compare(algebra.CompareEq, algebra.FieldRef("target", "document_revision"), algebra.FieldRef("input", "document_revision")), algebra.Compare(algebra.CompareEq, algebra.FieldRef("target", "signature_evidence_file_id"), algebra.FieldRef("input", "signature_evidence")))), RequiresReview: no}),	}} func signatureReads(reads ...product.ProgramRead) []product.ProgramRead {	return append(reads, read("basis", "basis.time"))

An Action commits its accepted platform effects atomically. Delivery to an external system happens through the outbound lifecycle; a queued request is not proof that the destination has applied it.

Read the capability reference

Connect the next part of the process.

Bring us a process.
We'll build it with you.

A business process, the systems it touches, and the rules it needs to follow.