ActionType Explained: Making Business Ops Platform-Native
In traditional architectures, business operations are scattered across services:
CoomiaPublished on August 9, 202514 min read
Share this articleTwitter / X
ActionType Explained: Making Business Ops Platform-Native
“Series: S4 Ontology Modeling · Article 5 | Level: Intermediate | Reading Time: 18 min
#TL;DR
- ActionType elevates "business operations" from scattered code to first-class Schema citizens — approvals, assignments, computations, and notifications become discoverable, auditable, and reusable platform-native capabilities, ending the chaos of "business logic scattered across a hundred microservices."
- 10 executor types (Function / Webhook / gRPC / Workflow / SQL / Script / Notification / Approval / Schedule / Composite) cover every scenario from simple field updates to multi-step approval flows.
- Parameter validation + idempotency guarantees + audit logging form a triple defense line ensuring every operation is trustworthy, traceable, and safely retryable.
#1. Why ActionType Is Needed
In traditional architectures, business operations are scattered across services:
Code
Traditional Approach (Scattered Operations):
User clicks "Approve Order" →
Frontend calls POST /api/orders/{id}/approve →
Backend has a pile of logic →
Update status + Send notification + Write log + Deduct inventory + ...
Problems:
├── Every operation is a custom API, no unified management
├── Parameter validation logic duplicated (frontend once, backend once)
├── No unified audit trail (some operations logged, some not)
├── Retry safety unknown (double-deducted inventory? double notifications?)
├── New team members can't see what business operations exist
└── Permission granularity at API level, not business operation level
coomia-dip Approach (ActionType):
User clicks "Approve Order" →
SDK calls executeAction("ApproveOrder", params) →
Platform handles uniformly:
├── 1. Parameter validation (Schema-defined rules)
├── 2. Permission check (RBAC + ABAC)
├── 3. Executor execution (one of 10 types)
├── 4. Audit logging (automatic)
├── 5. Idempotency check (prevent duplicate execution)
└── 6. Event publishing (notify downstream systems)
#2. ActionType Data Model
#2.1 Core Definition
Python
from ontology_sdk import OntologyClient
client = OntologyClient(base_url="http://localhost:8080")
# Create a complete ActionType
action = client.schema.create_action_type({
"apiName": "ApproveOrder",
"displayName": "Approve Order",
"description": "Manager approves pending orders; upon approval, auto-assigns warehouse and logistics",
# Bound ObjectType
"objectType": "Order",
# Parameter definitions
"parameters": {
"orderId": {
"type": "STRING",
"required": True,
"description": "Order ID",
},
"approved": {
"type": "BOOLEAN",
"required": True,
"description": "Whether to approve",
},
"comment": {
"type": "STRING",
"required": False,
"maxLength": 500,
"description": "Approval comment",
},
"priority": {
"type": "ENUM",
"enumValues": ["LOW", "NORMAL", "HIGH", "URGENT"],
"defaultValue": "NORMAL",
},
},
# Executor configuration
"executor": {
"type": "FUNCTION",
"functionId": "approve-order-fn",
"timeout": 30000, # 30-second timeout
"retryPolicy": {
"maxRetries": 3,
"backoffMs": 1000,
},
},
# Idempotency configuration
"idempotency": {
"enabled": True,
"keyExpression": "orderId + '-' + executorUserId",
"ttlSeconds": 3600, # No re-execution within 1 hour
},
# Preconditions
"preconditions": [
{
"type": "OBJECT_STATE",
"field": "status",
"operator": "eq",
"value": "PENDING_APPROVAL",
"errorMessage": "Only orders in PENDING_APPROVAL status can be approved",
},
{
"type": "PERMISSION",
"requiredRole": "ORDER_APPROVER",
},
],
# Side effects
"sideEffects": [
{
"type": "UPDATE_OBJECT",
"updates": {
"status": "${approved ? 'APPROVED' : 'REJECTED'}",
"approvedBy": "${currentUser.id}",
"approvedAt": "${now()}",
},
},
{
"type": "SEND_NOTIFICATION",
"template": "order-approval-result",
"recipients": ["${object.createdBy}"],
},
],
})
#2.2 Protobuf Schema
PROTOBUF
message ActionType {
string api_name = 1;
string display_name = 2;
string description = 3;
string object_type = 4;
map<string, ParameterDef> parameters = 5;
ExecutorConfig executor = 6;
IdempotencyConfig idempotency = 7;
repeated Precondition preconditions = 8;
repeated SideEffect side_effects = 9;
LifecycleState lifecycle = 10;
AuditInfo audit = 11;
}
message ParameterDef {
string type = 1;
bool required = 2;
string description = 3;
string default_value = 4;
repeated ValidationRule validations = 5;
}
message ExecutorConfig {
ExecutorType type = 1;
string function_id = 2;
string webhook_url = 3;
string grpc_service = 4;
int32 timeout_ms = 5;
RetryPolicy retry_policy = 6;
}
enum ExecutorType {
FUNCTION = 0;
WEBHOOK = 1;
GRPC = 2;
WORKFLOW = 3;
SQL = 4;
SCRIPT = 5;
NOTIFICATION = 6;
APPROVAL = 7;
SCHEDULE = 8;
COMPOSITE = 9;
}
#3. 10 Executor Types Explained
#3.1 FUNCTION — Function Executor
Code
The most common executor type, calling platform-registered Functions
┌──────────┐ ┌──────────────────┐ ┌──────────┐
│ Action │─────►│ Function Runtime │─────►│ Result │
│ Request │ │ (Python/Java) │ │ │
└──────────┘ └──────────────────┘ └──────────┘
Python
# Register a Function
client.functions.register({
"functionId": "calculate-risk-score",
"runtime": "python3.11",
"handler": "risk_module.calculate_score",
"timeout": 60000,
})
# Create an ActionType using the Function executor
client.schema.create_action_type({
"apiName": "CalculateRiskScore",
"objectType": "Customer",
"parameters": {
"customerId": {"type": "STRING", "required": True},
"includeHistory": {"type": "BOOLEAN", "defaultValue": "true"},
},
"executor": {
"type": "FUNCTION",
"functionId": "calculate-risk-score",
},
})
#3.2 WEBHOOK — HTTP Callback Executor
Python
# Call an external system's Webhook
client.schema.create_action_type({
"apiName": "SyncToERP",
"objectType": "Order",
"executor": {
"type": "WEBHOOK",
"webhookUrl": "https://erp.company.com/api/sync-order",
"method": "POST",
"headers": {
"Authorization": "Bearer ${secrets.ERP_TOKEN}",
"Content-Type": "application/json",
},
"bodyTemplate": {
"orderId": "${params.orderId}",
"items": "${object.lineItems}",
},
"successCodes": [200, 201, 202],
"timeout": 15000,
},
})
#3.3 GRPC — gRPC Service Call
Python
# Call an internal gRPC service
client.schema.create_action_type({
"apiName": "AllocateWarehouse",
"objectType": "Order",
"executor": {
"type": "GRPC",
"grpcService": "warehouse-service",
"grpcMethod": "AllocateWarehouse",
"protoMessage": "AllocateWarehouseRequest",
"fieldMapping": {
"order_id": "${params.orderId}",
"region": "${object.shippingRegion}",
"weight_kg": "${object.totalWeight}",
},
},
})
#3.4 WORKFLOW — Workflow Executor
Python
# Trigger a multi-step workflow (Temporal-based)
client.schema.create_action_type({
"apiName": "OnboardNewEmployee",
"objectType": "Employee",
"executor": {
"type": "WORKFLOW",
"workflowId": "employee-onboarding",
"taskQueue": "hr-workflows",
"steps": [
{"name": "create_accounts", "timeout": 60000},
{"name": "assign_equipment", "timeout": 120000},
{"name": "schedule_training", "timeout": 30000},
{"name": "notify_team", "timeout": 10000},
],
},
})
#3.5 SQL — Database Operation Executor
Python
# Execute SQL directly (suitable for batch updates)
client.schema.create_action_type({
"apiName": "BatchUpdatePrices",
"objectType": "Product",
"executor": {
"type": "SQL",
"dataSource": "doris-main",
"sqlTemplate": """
UPDATE products
SET price = price * (1 + :adjustmentPercent / 100.0),
updated_at = NOW()
WHERE category = :category
AND price BETWEEN :minPrice AND :maxPrice
""",
"parameterMapping": {
"adjustmentPercent": "${params.adjustmentPercent}",
"category": "${params.category}",
"minPrice": "${params.minPrice}",
"maxPrice": "${params.maxPrice}",
},
},
})
#3.6 SCRIPT — Script Executor
Python
# Run a Python script snippet
client.schema.create_action_type({
"apiName": "GenerateReport",
"objectType": "Project",
"executor": {
"type": "SCRIPT",
"language": "python",
"script": """
import pandas as pd
from datetime import datetime
project = context.get_object("Project", params["projectId"])
tasks = context.traverse(project, "Project_hasTasks_Task")
df = pd.DataFrame([t.to_dict() for t in tasks])
summary = {
"total": len(df),
"completed": len(df[df.status == "DONE"]),
"overdue": len(df[(df.status != "DONE") & (df.due_date < datetime.now())]),
"completion_rate": f"{len(df[df.status == 'DONE']) / len(df) * 100:.1f}%",
}
context.update_object(project, {"lastReport": summary})
return {"success": True, "summary": summary}
""",
"timeout": 120000,
},
})
#3.7 NOTIFICATION — Notification Executor
Python
# Send multi-channel notifications
client.schema.create_action_type({
"apiName": "SendAlertNotification",
"objectType": "Equipment",
"executor": {
"type": "NOTIFICATION",
"channels": ["email", "sms", "webhook"],
"template": "equipment-alert",
"recipientExpression": """
object.assignedTechnicians
+ object.factoryManager
""",
"variables": {
"equipmentName": "${object.name}",
"alertType": "${params.alertType}",
"severity": "${params.severity}",
},
},
})
#3.8 APPROVAL — Approval Executor
Python
# Multi-level approval chain
client.schema.create_action_type({
"apiName": "ApprovePurchaseRequest",
"objectType": "PurchaseRequest",
"executor": {
"type": "APPROVAL",
"approvalChain": [
{
"level": 1,
"approverExpression": "${object.departmentManager}",
"condition": "params.amount < 10000",
"autoApproveAfterHours": 48,
},
{
"level": 2,
"approverExpression": "${object.financeDirector}",
"condition": "params.amount >= 10000 && params.amount < 100000",
"autoApproveAfterHours": 72,
},
{
"level": 3,
"approverExpression": "${getCEO()}",
"condition": "params.amount >= 100000",
},
],
"onApproved": {
"type": "FUNCTION",
"functionId": "create-purchase-order",
},
"onRejected": {
"type": "NOTIFICATION",
"template": "purchase-rejected",
},
},
})
#3.9 SCHEDULE — Scheduled Executor
Python
# Scheduled or delayed execution
client.schema.create_action_type({
"apiName": "ScheduleMaintenanceReminder",
"objectType": "Equipment",
"executor": {
"type": "SCHEDULE",
"scheduleExpression": "0 8 * * MON", # Every Monday at 8 AM
"action": {
"type": "FUNCTION",
"functionId": "check-maintenance-due",
},
},
})
#3.10 COMPOSITE — Composite Executor
Python
# Execute multiple sub-operations sequentially or in parallel
client.schema.create_action_type({
"apiName": "ProcessNewOrder",
"objectType": "Order",
"executor": {
"type": "COMPOSITE",
"strategy": "SEQUENTIAL", # SEQUENTIAL or PARALLEL
"steps": [
{
"name": "validate_inventory",
"executor": {"type": "FUNCTION", "functionId": "check-inventory"},
"onFailure": "ABORT", # Abort on failure
},
{
"name": "charge_payment",
"executor": {"type": "GRPC", "grpcService": "payment-service", "grpcMethod": "Charge"},
"onFailure": "COMPENSATE", # Compensate on failure
"compensateAction": "RefundPayment",
},
{
"name": "allocate_warehouse",
"executor": {"type": "FUNCTION", "functionId": "allocate-warehouse"},
"onFailure": "COMPENSATE",
"compensateAction": "ReleaseWarehouse",
},
{
"name": "notify_customer",
"executor": {"type": "NOTIFICATION", "template": "order-confirmed"},
"onFailure": "IGNORE", # Notification failure doesn't block main flow
},
],
},
})
#4. Parameter Validation System
#4.1 Built-in Validation Rules
Python
# Rich parameter validation
client.schema.create_action_type({
"apiName": "TransferFunds",
"objectType": "Account",
"parameters": {
"sourceAccountId": {
"type": "STRING",
"required": True,
"validations": [
{"rule": "pattern", "value": "^ACC-[0-9]{10}$", "message": "Invalid account ID format"},
],
},
"targetAccountId": {
"type": "STRING",
"required": True,
"validations": [
{"rule": "pattern", "value": "^ACC-[0-9]{10}$"},
{"rule": "notEqual", "referenceParam": "sourceAccountId", "message": "Cannot transfer to yourself"},
],
},
"amount": {
"type": "DOUBLE",
"required": True,
"validations": [
{"rule": "min", "value": 0.01, "message": "Amount must be greater than 0"},
{"rule": "max", "value": 1000000, "message": "Single transfer cannot exceed 1,000,000"},
],
},
"currency": {
"type": "ENUM",
"enumValues": ["CNY", "USD", "EUR", "GBP", "JPY"],
"defaultValue": "CNY",
},
"memo": {
"type": "STRING",
"required": False,
"validations": [
{"rule": "maxLength", "value": 200},
{"rule": "noScript", "message": "Memo must not contain script code"},
],
},
},
})
#4.2 Custom Validation Functions
Python
# Register a custom validator
client.schema.create_action_type({
"apiName": "ChangeEquipmentStatus",
"objectType": "Equipment",
"parameters": {
"equipmentId": {"type": "STRING", "required": True},
"newStatus": {"type": "ENUM", "enumValues": ["RUNNING", "MAINTENANCE", "STOPPED", "DECOMMISSIONED"]},
},
"validationFunction": "validate-status-transition",
})
# Validation function code
# def validate_status_transition(params, object, context):
# valid_transitions = {
# "RUNNING": ["MAINTENANCE", "STOPPED"],
# "MAINTENANCE": ["RUNNING", "STOPPED"],
# "STOPPED": ["RUNNING", "MAINTENANCE", "DECOMMISSIONED"],
# "DECOMMISSIONED": [], # Terminal state, no transitions
# }
# current = object.status
# target = params["newStatus"]
# if target not in valid_transitions.get(current, []):
# raise ValidationError(f"Cannot transition from {current} to {target}")
#5. Idempotency Guarantees
#5.1 Idempotency Mechanism
Code
Idempotency guarantee flow:
Request arrives → Compute idempotency key → Query idempotency store
│
┌─────────┴─────────┐
▼ ▼
Key exists Key absent
(already executed) (first execution)
│ │
▼ ▼
Return previous Execute Action
result │
▼
Store idempotency key + result
│
▼
Return result
Python
# Idempotent execution example
result1 = client.actions.execute("ApproveOrder", {
"orderId": "order-001",
"approved": True,
"comment": "Approved",
}, idempotency_key="approval-order-001-user-admin")
# Same idempotency key — will not re-execute
result2 = client.actions.execute("ApproveOrder", {
"orderId": "order-001",
"approved": True,
"comment": "Approved",
}, idempotency_key="approval-order-001-user-admin")
assert result1.execution_id == result2.execution_id # Same execution
assert result2.was_deduplicated == True # Marked as deduplicated
#5.2 Idempotency Key Strategies
Code
┌─────────────────────────────────────────────────────┐
│ Idempotency Key Generation Strategies │
├─────────────────────────────────────────────────────┤
│ │
│ 1. Client-specified (most flexible): │
│ idempotency_key = "user-123-approve-order-456" │
│ │
│ 2. Parameter-derived (auto-computed): │
│ keyExpression = "orderId + '-' + userId" │
│ → "order-456-user-123" │
│ │
│ 3. Business-rule-based (semantic level): │
│ keyExpression = "orderId + '-approve'" │
│ → Same order can only be approved once │
│ │
│ TTL Strategies: │
│ ├── Short-term (1 hour): Prevent double-clicks │
│ ├── Medium-term (24 hours): Prevent same-day dupes │
│ └── Permanent (no expiry): Business-once operations │
└─────────────────────────────────────────────────────┘
#6. Audit Logging
#6.1 Automatic Auditing
Python
# Every Action execution automatically generates an audit log
result = client.actions.execute("ApproveOrder", {
"orderId": "order-001",
"approved": True,
})
# Query audit logs
audit_logs = client.audit.query({
"actionType": "ApproveOrder",
"objectType": "Order",
"objectId": "order-001",
"timeRange": {"from": "2026-03-01", "to": "2026-03-24"},
})
for log in audit_logs:
print(f"[{log.timestamp}] {log.user} executed {log.action_type}")
print(f" Parameters: {log.parameters}")
print(f" Result: {log.result_status}")
print(f" Duration: {log.duration_ms} ms")
print(f" Changes: {log.object_changes}")
#6.2 Audit Log Structure
Code
┌───────────────────────────────────────────────┐
│ Audit Log Entry │
├───────────────────────────────────────────────┤
│ execution_id : "exec-uuid-001" │
│ action_type : "ApproveOrder" │
│ object_type : "Order" │
│ object_id : "order-001" │
│ user_id : "user-admin" │
│ timestamp : "2026-03-24T10:30:00Z" │
│ parameters : {orderId, approved, ...} │
│ result_status : "SUCCESS" │
│ duration_ms : 245 │
│ idempotency_key : "approval-order-001-..." │
│ was_deduplicated: false │
│ object_before : {status: "PENDING"} │
│ object_after : {status: "APPROVED"} │
│ side_effects : ["notification-sent"] │
│ ip_address : "192.168.1.100" │
│ user_agent : "onto-sdk/1.0" │
└───────────────────────────────────────────────┘
#7. Action Permission Control
Python
# ActionType permission model
client.schema.create_action_type({
"apiName": "DeleteCustomer",
"objectType": "Customer",
"permissions": {
# RBAC: Role-level permissions
"requiredRoles": ["CUSTOMER_ADMIN"],
# ABAC: Attribute-level permissions
"attributeRules": [
{
"description": "Can only delete customers in own region",
"expression": "user.region == object.region",
},
{
"description": "VIP customers require director approval",
"expression": "object.tier != 'VIP' || user.role == 'DIRECTOR'",
},
],
# Data-level permissions
"fieldAccess": {
"params.reason": "ALL", # Everyone can provide a reason
"params.force": "ADMIN_ONLY", # Only admins can force-delete
},
},
})
#8. Action Execution Lifecycle
Code
Action execution state machine:
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ SUBMITTED│───►│VALIDATING│───►│ EXECUTING│───►│COMPLETED │
└──────────┘ └─────┬────┘ └─────┬────┘ └──────────┘
│ │
▼ ▼
┌──────────┐ ┌──────────┐
│VALIDATION│ │ FAILED │
│_FAILED │ │ │
└──────────┘ └─────┬────┘
│
▼
┌──────────┐
│ RETRYING │──► EXECUTING (retry)
└──────────┘
Responsibilities at each stage:
├── SUBMITTED → Accept request, assign execution_id
├── VALIDATING → Parameter validation + precondition check + permission check
├── EXECUTING → Invoke executor
├── COMPLETED → Execution succeeded, trigger side effects
├── FAILED → Execution failed, decide whether to retry based on policy
└── RETRYING → Backoff wait, then re-execute
Python
# Async execution for long-running Actions
execution = client.actions.execute_async("OnboardNewEmployee", {
"employeeId": "emp-new-001",
"department": "engineering",
"startDate": "2026-04-01",
})
print(f"Execution ID: {execution.id}")
print(f"Status: {execution.status}") # SUBMITTED
# Poll execution status
import time
while execution.status not in ["COMPLETED", "FAILED"]:
time.sleep(2)
execution = client.actions.get_execution(execution.id)
print(f"Status: {execution.status}, Progress: {execution.progress}%")
# Check execution result
if execution.status == "COMPLETED":
print(f"Result: {execution.result}")
else:
print(f"Error: {execution.error}")
#9. Batch Operations
Python
# Batch execute Actions
batch_result = client.actions.batch_execute("UpdateEquipmentStatus", [
{"equipmentId": "equip-001", "newStatus": "MAINTENANCE"},
{"equipmentId": "equip-002", "newStatus": "MAINTENANCE"},
{"equipmentId": "equip-003", "newStatus": "MAINTENANCE"},
{"equipmentId": "equip-004", "newStatus": "STOPPED"},
], batch_options={
"concurrency": 5, # Parallelism
"stopOnFirstError": False, # Don't stop on individual failure
"transactional": False, # Non-transactional (independent)
})
print(f"Total: {batch_result.total}")
print(f"Succeeded: {batch_result.success_count}")
print(f"Failed: {batch_result.failure_count}")
for failure in batch_result.failures:
print(f" {failure.params['equipmentId']}: {failure.error}")
#10. ActionType and Event-Driven Architecture
Python
# Action execution auto-publishes events
client.schema.create_action_type({
"apiName": "UpdateInventory",
"objectType": "Product",
"executor": {
"type": "FUNCTION",
"functionId": "update-inventory",
},
"events": {
"onSuccess": {
"topic": "inventory.updated",
"payload": {
"productId": "${params.productId}",
"oldQuantity": "${before.quantity}",
"newQuantity": "${after.quantity}",
"delta": "${params.quantityDelta}",
},
},
"onFailure": {
"topic": "inventory.update-failed",
"payload": {
"productId": "${params.productId}",
"error": "${error.message}",
},
},
},
})
# Other systems can subscribe to these events
client.events.subscribe("inventory.updated", handler=lambda event:
print(f"Inventory changed: {event.productId} from {event.oldQuantity} to {event.newQuantity}")
)
#11. Real-World Case: Manufacturing Equipment Inspection
Python
# Complete equipment inspection ActionType
# 1. Start Inspection
client.schema.create_action_type({
"apiName": "StartInspection",
"objectType": "Equipment",
"displayName": "Start Inspection",
"parameters": {
"equipmentId": {"type": "STRING", "required": True},
"inspectorId": {"type": "STRING", "required": True},
"inspectionType": {
"type": "ENUM",
"enumValues": ["ROUTINE", "SPECIAL", "EMERGENCY"],
"required": True,
},
},
"preconditions": [
{"type": "OBJECT_STATE", "field": "status", "operator": "in", "value": ["RUNNING", "STOPPED"]},
],
"executor": {
"type": "COMPOSITE",
"strategy": "SEQUENTIAL",
"steps": [
{
"name": "create_inspection_record",
"executor": {"type": "FUNCTION", "functionId": "create-inspection"},
},
{
"name": "update_equipment_status",
"executor": {
"type": "SQL",
"sqlTemplate": "UPDATE equipment SET inspection_status = 'IN_PROGRESS' WHERE id = :equipmentId",
},
},
{
"name": "notify_maintenance_team",
"executor": {"type": "NOTIFICATION", "template": "inspection-started"},
"onFailure": "IGNORE",
},
],
},
"idempotency": {
"enabled": True,
"keyExpression": "equipmentId + '-' + inspectorId + '-' + today()",
"ttlSeconds": 86400,
},
})
# 2. Record Inspection Result
client.schema.create_action_type({
"apiName": "RecordInspectionResult",
"objectType": "Equipment",
"displayName": "Record Inspection Result",
"parameters": {
"inspectionId": {"type": "STRING", "required": True},
"overallStatus": {"type": "ENUM", "enumValues": ["PASS", "WARNING", "FAIL"], "required": True},
"checkItems": {
"type": "ARRAY",
"itemType": "STRUCT",
"structFields": {
"itemName": {"type": "STRING"},
"result": {"type": "ENUM", "enumValues": ["OK", "ABNORMAL", "CRITICAL"]},
"note": {"type": "STRING"},
"photoUrls": {"type": "ARRAY", "itemType": "STRING"},
},
},
"recommendations": {"type": "STRING", "maxLength": 2000},
},
"executor": {
"type": "FUNCTION",
"functionId": "process-inspection-result",
},
})
# Usage example
result = client.actions.execute("StartInspection", {
"equipmentId": "equip-CNC-001",
"inspectorId": "tech-zhang",
"inspectionType": "ROUTINE",
})
print(f"Inspection started: {result.data['inspectionId']}")
#Key Takeaways
- ActionType is the Schema-level expression of business operations — every operation has explicit parameters, executors, permissions, and audit trails, making business capabilities discoverable, manageable, and reusable.
- 10 executor types cover everything from simple function calls to complex multi-step approval flows, with the COMPOSITE executor supporting Saga-pattern distributed transaction compensation.
- Parameter validation is pushed to the Schema layer — type checking, range validation, regex matching, and custom validation functions, defined once and enforced uniformly across frontend and backend.
- Idempotency is a hard requirement for production systems — through idempotency keys and TTL mechanisms, network jitter and user retries are guaranteed to never cause duplicate execution.
- Full audit logs are auto-generated — who did what to which object at what time, with complete input/output records, forming the foundation for compliance and troubleshooting.
#Next Article
The next article, S4-06 InterfaceType and StructType, will explore advanced features of the Ontology type system — how interface inheritance enables polymorphic queries and how struct nesting builds complex value objects.
#ontology #action-type #executor #idempotency #audit-log #parameter-validation #workflow