Back to Blog

Palantir's Actions and Rules: Bridging Data Insight to Business Operations

Everyone who has used a BI tool has experienced this scenario:

CoomiaPublished on June 12, 202522 min read
Share this articleTwitter / X

Palantir's Actions and Rules: Bridging Data Insight to Business Operations

Series: S1 Palantir Decoded · Article 11 | Level: Beginner | Reading Time: 15 min

#TL;DR

  • Palantir Actions are the core mechanism for turning data insights into business operations -- each Action is an atomic, auditable, permission-controlled business operation unit with parameter validation, preconditions, side-effect declarations, and permission constraints.
  • The Rules engine implements automated decision-making through a "condition -> trigger -> action chain" pattern, enabling systems to not just "see problems" but "automatically handle them" -- this is the fundamental difference between Palantir and every BI platform.
  • coomia-dip implements this complete closed loop through ActionEngine (10 executor types) and ReasoningEngine (rules engine), with FunctionRuntime supporting Python/TypeScript/Groovy/WASM/Kotlin sandboxed execution.

#Introduction: The Ultimate BI Dilemma -- "I Can See It, Now What?"

Everyone who has used a BI tool has experienced this scenario:

Code
Traditional BI platform workflow:

Step 1: See the report
+--------------------------------------+
|  Inventory Alert Dashboard            |
|                                        |
|  Material A-2047: Stock 12 (below safety stock of 50)
|  Material B-1193: Stock 0  (out of stock!)
|  Material C-0872: Stock 8  (below safety stock of 30)
|                                        |
|  [Export to Excel]                     |
+--------------------------------------+

Step 2: Open email client, write email to procurement
Step 3: Procurement reads email, opens ERP system
Step 4: Look up supplier information in ERP
Step 5: Create purchase order
Step 6: Wait for approval
Step 7: Approval granted, send to supplier
Step 8: Track delivery status...

The entire process involves 4 systems, 3 people, at least 2 days.
Meanwhile, the stockout costs $7,000 per day.

The root cause: Traditional BI only solves "seeing," not "doing."

Palantir's Actions and Rules exist precisely to bridge this gap.

Code
Palantir's closed-loop workflow:

+--------------------------------------+
|  Inventory Alert Dashboard            |
|                                        |
|  Material A-2047: Stock 12             |
|  [Restock]  [Switch Supplier]  [Pause Line]
|                                        |
|  > Rules auto-triggered:              |
|    - Restock request sent to          |
|      preferred supplier               |
|    - Warehouse manager notified       |
|    - Production schedule priority     |
|      adjusted                         |
+--------------------------------------+

Same scenario: 0 extra systems, 0 emails, 30 seconds.

This is the "data-to-action closed loop" -- one of Palantir's core competitive advantages.

#Part 1: Anatomy of an Action

#1.1 What Is an Action?

In Palantir Foundry, an Action is a structured business operation unit. It is not a simple API call, but a complete semantic description of an operation:

Code
Complete Action structure:

+-----------------------------------------------+
|  ActionType: "Restock Order"                   |
|                                                 |
|  +-------------------------------------------+ |
|  | Parameters                                 | |
|  |  - materialId: ObjectReference<Material>   | |
|  |  - quantity: Integer (min: 1, max: 10000)  | |
|  |  - supplierId: ObjectReference<Supplier>   | |
|  |  - urgency: Enum(NORMAL, URGENT, CRITICAL) | |
|  |  - notes: String (optional)                | |
|  +-------------------------------------------+ |
|                                                 |
|  +-------------------------------------------+ |
|  | Preconditions                              | |
|  |  - material.status != DISCONTINUED         | |
|  |  - supplier.status == ACTIVE               | |
|  |  - user.role IN [BUYER, MANAGER]           | |
|  |  - quantity <= material.maxOrderQuantity    | |
|  +-------------------------------------------+ |
|                                                 |
|  +-------------------------------------------+ |
|  | Side Effects (declared)                    | |
|  |  - CREATE PurchaseOrder                    | |
|  |  - UPDATE Material.lastOrderDate           | |
|  |  - CREATE Notification -> warehouse_mgr    | |
|  +-------------------------------------------+ |
|                                                 |
|  +-------------------------------------------+ |
|  | Permissions                                | |
|  |  - REQUIRES: procurement:order:create      | |
|  |  - REQUIRES: material:read                 | |
|  |  - IF urgency == CRITICAL:                 | |
|  |      REQUIRES: procurement:emergency       | |
|  +-------------------------------------------+ |
|                                                 |
|  +-------------------------------------------+ |
|  | Validation Rules                           | |
|  |  - totalCost <= user.approvalLimit         | |
|  |  - supplier NOT IN blacklist               | |
|  |  - delivery_date within fiscal_year        | |
|  +-------------------------------------------+ |
+-----------------------------------------------+

#1.2 The Six Components of an ActionType

ComponentPurposeExample
ParametersDefine required inputsMaterial ID, quantity, supplier
PreconditionsConditions that must be met before executionMaterial not discontinued, supplier active
Side EffectsDeclare what the operation will changeCreate order, update inventory
PermissionsRequired permission setBuyer or manager role
ValidationBusiness rule checksAmount within approval limit
Audit ConfigAudit configurationRecord operator, timestamp, change details

#1.3 Why "Side Effect Declarations" Matter So Much

In traditional systems, knowing what an API call does requires reading the code. Palantir Actions explicitly declare all side effects:

Code
Traditional API:                    Palantir Action:

POST /api/restock                   ActionType: Restock
Body: {materialId, qty}             Side Effects:
                                      - CREATE PurchaseOrder
Returns: {success: true}              - UPDATE Material.lastOrderDate
                                      - UPDATE Material.pendingQty
// What did it actually do?           - CREATE AuditLog
// Who knows...                       - SEND Notification -> buyer
// Read 500 lines of code
                                    // Everything is visible at a glance

This enables:

  • Permission systems to know exactly which objects and permissions to check
  • Audit systems to precisely record every change
  • Rollback mechanisms to know which operations to reverse
  • Impact analysis to show users what will happen before execution

#Part 2: Action Execution Lifecycle

#2.1 From Button Click to Operation Complete

Code
User clicks [Restock]
      |
      v
+--------------+
| 1. Parameter |  <-- Form popup: enter quantity, select supplier
|    Collection|  <-- Real-time validation: quantity range, supplier status
|    & Validate|
+------+-------+
       |
       v
+--------------+
| 2. Precondi- |  <-- Check if material is orderable
|    tion Check|  <-- Check if supplier is active
+------+-------+
       | Conditions met
       v
+--------------+
| 3. Permission|  <-- Does user have ordering permission?
|    Check     |  <-- Is amount within approval limit?
+------+-------+
       | Permission granted
       v
+--------------+
| 4. Impact    |  <-- "This will create 1 purchase order,
|    Preview   |     estimated amount $1,800"
| (Dry Run)    |
+------+-------+
       | User confirms
       v
+--------------+
| 5. Transact- |  <-- Execute all side effects in one transaction
|    ional Exec|  <-- Atomic: all succeed or all rollback
+------+-------+
       |
       v
+--------------+
| 6. Audit     |  <-- Record operator, timestamp, parameters, result
|    Logging   |  <-- Record before/after state snapshots
+------+-------+
       |
       v
+--------------+
| 7. Post-exec |  <-- Trigger associated Rules
|    Triggers  |  <-- Send notifications
+--------------+

#2.2 The Dry Run Mechanism

Palantir's Dry Run is an extraordinarily powerful feature -- previewing the full impact of an operation without actually executing it:

Python
# Dry Run preview response
{
    "action": "Restock",
    "preview": {
        "objects_created": [
            {"type": "PurchaseOrder", "properties": {
                "supplier": "ABC Electronics",
                "total_amount": 12500,
                "expected_delivery": "2026-04-10"
            }}
        ],
        "objects_modified": [
            {"type": "Material", "id": "A-2047", "changes": {
                "pending_quantity": {"before": 0, "after": 100},
                "last_order_date": {"before": "2026-02-15", "after": "2026-03-24"}
            }}
        ],
        "notifications": [
            {"to": "warehouse_mgr", "template": "new_order_placed"}
        ],
        "estimated_cost": 12500,
        "requires_approval": False
    }
}

Users can see every change that will occur before confirming -- something nearly impossible in traditional systems.

#Part 3: The Rules Engine -- Automated Decision Making

#3.1 From "Humans Find Problems" to "Systems Handle Problems"

Rules are Palantir's automated decision engine. The core pattern is:

Code
Condition -----> Trigger -----> Action Chain

Example:

+---------------------------+
| Rule: Auto-Restock        |
+---------------------------+
|                             |
| WHEN:                       |
|   material.stock_level      |
|   < material.safety_stock   |
|   AND material.status       |
|   == ACTIVE                 |
|                             |
| THEN:                       |
|   1. Calculate restock qty  |
|      (EOQ formula)          |
|   2. Select optimal supplier|
|      (price+lead time+score)|
|   3. Create purchase order  |
|   4. Notify warehouse mgr   |
|   5. Update demand forecast |
|                             |
| UNLESS:                     |
|   Open restock order exists |
|   OR material being phased  |
|   out                       |
|                             |
| THROTTLE:                   |
|   Same material: max 1      |
|   trigger per 24 hours      |
+---------------------------+

#3.2 Three Rule Triggering Modes

ModeWhen TriggeredUse CaseExample
Event-drivenOn object state changeReal-time responseRestock when inventory drops below threshold
ScheduledBy Cron expressionPeriodic checksDaily check for expiring contracts
ManualUser-initiatedBatch processingQuarterly supplier review

#3.3 Rule Chains -- Orchestrating Complex Scenarios

Real business scenarios rarely involve a single rule. Palantir supports Rule Chains:

Code
Rule Chain Example: Equipment Anomaly Handling

Event: Sensor temperature > threshold
         |
         v
+----------------------+
| Rule 1: Initial      |
|   Assessment         |
| IF temp > 80C        |
| AND duration > 5min  |
| THEN: Create alert   |
|   severity = WARN    |
+----------+-----------+
           | Alert created event
           v
+----------------------+
| Rule 2: Escalation   |
| IF temp > 95C        |
| OR same device has    |
|   3 alerts in 24h    |
| THEN: Escalate to    |
|   CRITICAL           |
|   Notify shift mgr   |
+----------+-----------+
           | Escalation event
           v
+----------------------+
| Rule 3: Auto-Response|
| IF severity ==       |
|   CRITICAL           |
| AND device supports  |
|   remote control     |
| THEN: Reduce power   |
|   to 50%             |
|   Create repair order|
|   Notify maintenance |
+----------+-----------+
           | Repair order created
           v
+----------------------+
| Rule 4: Line Adjust  |
| IF critical device   |
|   goes offline       |
| THEN: Reschedule     |
|   production         |
|   Notify downstream  |
|   Update delivery    |
|   forecast           |
+----------------------+

These four rules are defined independently but automatically chained through events. This is the power of a rule engine -- each rule stays simple, but composed together they handle extremely complex scenarios.

#Part 4: Functions -- User-Defined Logic

#4.1 Where Functions Fit

When built-in Actions and Rules are not enough, users can write custom Functions:

Code
Complexity spectrum:

Simple <-------------------------------------> Complex

[Built-in Action] [Rules]  [Functions]  [Pipeline]
  Click button     Auto-     Custom       Data
  to execute       trigger   logic        pipeline
                             Coding       Design
                             required     required

#4.2 Writing Functions

Palantir supports Functions in TypeScript and Python:

TypeScript
// TypeScript Function: Select optimal supplier
import { Function, OntologyObject } from "@palantir/functions-api";

@Function()
export function selectOptimalSupplier(
    material: OntologyObject<"Material">,
    requiredQuantity: number
): OntologyObject<"Supplier"> {
    // Get all active suppliers for this material
    const suppliers = material.suppliers
        .filter(s => s.status === "ACTIVE")
        .filter(s => s.available_capacity >= requiredQuantity);

    if (suppliers.length === 0) {
        throw new UserFacingError(
            "No available supplier can fulfill this order quantity"
        );
    }

    // Sort by composite score: price 40% + lead time 30% + quality 30%
    return suppliers.sort((a, b) => {
        const scoreA = a.unit_price * 0.4
                     + a.avg_delivery_days * 0.3
                     + (5 - a.quality_rating) * 0.3;
        const scoreB = b.unit_price * 0.4
                     + b.avg_delivery_days * 0.3
                     + (5 - b.quality_rating) * 0.3;
        return scoreA - scoreB;
    })[0];
}
Python
# Python Function: Anomaly detection
from palantir.functions import function
from palantir.ontology import ObjectSet

@function()
def detect_anomalies(
    equipment_id: str,
    lookback_hours: int = 24
) -> list[dict]:
    """Detect anomaly patterns in equipment sensor data."""
    readings = Objects.search("SensorReading") \
        .filter(equipment_id=equipment_id) \
        .filter(timestamp__gte=now() - hours(lookback_hours)) \
        .order_by("timestamp") \
        .all()

    anomalies = []
    window_size = 10

    for i in range(window_size, len(readings)):
        window = readings[i - window_size:i]
        mean = sum(r.value for r in window) / window_size
        std = (sum((r.value - mean) ** 2
               for r in window) / window_size) ** 0.5

        if abs(readings[i].value - mean) > 3 * std:
            anomalies.append({
                "timestamp": readings[i].timestamp,
                "value": readings[i].value,
                "expected_range": [mean - 3*std, mean + 3*std],
                "severity": "HIGH"
                    if abs(readings[i].value - mean) > 5 * std
                    else "MEDIUM"
            })

    return anomalies

#4.3 The Function Security Sandbox

Functions do not run on the user's machine -- they execute in Palantir's secure sandbox:

Code
Function Execution Environment:

+----------------------------------------------+
|  Palantir Function Runtime                    |
|                                                |
|  +------------------------------------------+ |
|  |  Security Sandbox                         | |
|  |  +--------------------------------------+ | |
|  |  |  User Function Code                  | | |
|  |  |  - Can only access declared Ontology  | | |
|  |  |    objects                            | | |
|  |  |  - No direct network/filesystem      | | |
|  |  |    access                             | | |
|  |  |  - Execution time limit (default 30s)| | |
|  |  |  - Memory limit (default 256MB)      | | |
|  |  +--------------------------------------+ | |
|  |                                            | |
|  |  +--------------------------------------+ | |
|  |  |  Ontology API (restricted interface) | | |
|  |  |  - Objects.search()                  | | |
|  |  |  - Objects.get()                     | | |
|  |  |  - Actions.apply()                   | | |
|  |  +--------------------------------------+ | |
|  +------------------------------------------+ |
|                                                |
|  Permissions inherited from caller             |
|  <-- Critical security design                  |
+----------------------------------------------+

#Part 5: Webhook Integration and Batch Operations

#5.1 Webhooks -- Connecting the Outside World

Actions can not only manipulate objects within the Ontology but also connect to external systems through Webhooks:

Code
Webhook Action Flow:

+----------+     +--------------+     +--------------+
| Palantir |     |  Webhook     |     |  External    |
| Action   |---->|  Gateway     |---->|  System      |
|          |     |  - Signature |     |  (ERP/CRM/   |
|          |     |    verify    |     |   MES/...)   |
|          |     |  - Retry     |     |              |
|          |     |  - Timeout   |     |              |
+----------+     +------+-------+     +------+-------+
                        |                     |
                        |   Callback confirm  |
                        |<--------------------+
                        |
                        v
                 +--------------+
                 | Update status|
                 | Write audit  |
                 +--------------+

Webhook configuration example:

JSON
{
    "actionType": "sync_order_to_erp",
    "webhook": {
        "url": "https://erp.company.com/api/v2/purchase-orders",
        "method": "POST",
        "headers": {
            "Authorization": "Bearer ${secrets.erp_token}",
            "Content-Type": "application/json"
        },
        "body_template": {
            "order_id": "${action.params.orderId}",
            "material_code": "${object.Material.code}",
            "quantity": "${action.params.quantity}",
            "supplier_code": "${object.Supplier.erp_code}"
        },
        "retry": {
            "max_attempts": 3,
            "backoff": "exponential",
            "initial_delay_ms": 1000
        },
        "timeout_ms": 30000,
        "success_condition": "response.status == 201"
    }
}

#5.2 Batch Actions

When dealing with large-scale data, executing Actions one by one is too slow. Palantir supports batch operations:

Code
Batch Action Execution:

Input: 2,847 orders needing status updates

+------------------------------------------+
|  Batch Action: Bulk Update Order Status   |
|                                            |
|  Batch Strategy: 100 per batch            |
|                                            |
|  Batch 1:  [###########] 100/100  Done    |
|  Batch 2:  [###########] 100/100  Done    |
|  Batch 3:  [###########] 100/100  Done    |
|  ...                                       |
|  Batch 28: [###########] 100/100  Done    |
|  Batch 29: [#######    ]  47/100  Done    |
|                                            |
|  Result: 2,841 succeeded / 6 failed       |
|  Failure reasons:                          |
|    - 3: Order modified by another user    |
|    - 2: Supplier deactivated              |
|    - 1: Insufficient permissions           |
|                                            |
|  [Retry Failed] [Export Report] [Details]  |
+------------------------------------------+

Key design principles for batch operations:

PrincipleDescription
Partial failure toleranceSingle record failure does not affect others
Progress visibilityReal-time progress display
Selective retryOnly retry failed records
Complete auditEach record audited independently
Concurrency controlOptimistic locking prevents conflicts

#Part 6: The Action Audit Trail

#6.1 Why Audit Matters

In regulated industries like finance, healthcare, and government, "who did what when" is not optional -- it is a legal requirement.

Code
Action Audit Record Structure:

+----------------------------------------------------+
|  Audit Entry                                        |
|                                                      |
|  Action ID:    act_20260324_143052_a7b3c             |
|  Action Type:  UpdateOrderStatus                     |
|  Timestamp:    2026-03-24T14:30:52.847Z              |
|  User:         zhang.wei@company.com                 |
|  User Role:    procurement_manager                   |
|  IP Address:   10.0.12.47                            |
|  Session:      sess_x8k2m                            |
|                                                      |
|  Parameters:                                         |
|    orderId:    PO-2026-00847                          |
|    newStatus:  APPROVED                              |
|    comment:    "Price confirmed, purchase approved"   |
|                                                      |
|  Affected Objects:                                   |
|    PurchaseOrder/PO-2026-00847:                       |
|      status:       PENDING -> APPROVED               |
|      approved_by:  null -> zhang.wei                  |
|      approved_at:  null -> 2026-03-24T14:30:52Z      |
|                                                      |
|  Triggered Rules:                                    |
|    - rule_auto_notify_supplier (SUCCESS)              |
|    - rule_update_budget_consumed (SUCCESS)            |
|                                                      |
|  Execution Time:  127ms                              |
|  Result:          SUCCESS                            |
+----------------------------------------------------+

#6.2 Immutability of Audit Logs

Code
Audit Log Storage Architecture:

Action Execution
    |
    v
+------------+    +------------+    +------------+
| Synchronous|    | Async      |    | Compliance |
| Write to   |--->| Archive to |--->| Periodic   |
| Append-Only|    | Object     |    | Audit      |
| Database   |    | Storage    |    | Report     |
+------------+    | (Immutable)|    | Generation |
      |           +------------+    +------------+
      |
      | Integrity guarantee
      v
+------------+
| Hash chain |
| Each record|
| hash incl. |
| previous   |
| record hash|
+------------+

#Part 7: How coomia-dip Implements Actions and Rules

#7.1 ActionEngine's 10 Executor Types

coomia-dip ActionEngine provides 10 executor types covering all common business operation scenarios:

Code
coomia-dip ActionEngine Architecture:

                    +--------------+
                    | ActionEngine |
                    |  (Dispatcher)|
                    +------+-------+
                           |
           +---------------+---------------+
           |               |               |
     +-----+-----+  +-----+-----+  +-----+-----+
     | Object Ops |  | Relation  |  | Extended  |
     +-----+-----+  |   Ops     |  |   Ops     |
           |         +-----+-----+  +-----+-----+
    +------+------+   +---+---+    +------+----------+
    |      |      |   |       |    |      |      |   |
    v      v      v   v       v    v      v      v   v
  Create Update Delete Create Delete Invoke Web- Noti- Simple Compo-
  Object Object Object Rela.  Rela.  Func.  hook fic.  Op     site
ExecutorFunctionExample
CreateObjectCreate Ontology objectCreate purchase order
UpdateObjectUpdate object propertiesChange order status
DeleteObjectDelete object (soft delete)Cancel voided order
CreateRelationCreate inter-object relationLink order to supplier
DeleteRelationRemove inter-object relationUnbind supplier
InvokeFunctionCall custom functionRun pricing logic
WebhookCall external HTTP endpointSync data to ERP
NotificationSend notificationEmail/SMS/in-app message
SimpleOpSimple expression operationField assignment, math
CompositeOpCompose multiple operationsOrchestrate complex workflows

#7.2 CompositeOp -- Operation Orchestration

CompositeOp is the most powerful executor type, composing multiple operations into a single transaction:

Python
# coomia-dip CompositeOp definition example
from ontology_sdk import ActionBuilder, CompositeOp

restock_action = ActionBuilder("restock_material") \
    .parameter("material_id", type="object_ref",
               object_type="Material") \
    .parameter("quantity", type="integer", min=1) \
    .precondition("material.status == 'ACTIVE'") \
    .precondition(
        "material.stock_level < material.safety_stock") \
    .composite_op([
        CompositeOp.invoke_function(
            "select_optimal_supplier",
            args={"material_id": "${params.material_id}",
                  "quantity": "${params.quantity}"},
            output_as="selected_supplier"
        ),
        CompositeOp.create_object(
            "PurchaseOrder",
            properties={
                "material_id": "${params.material_id}",
                "supplier_id":
                    "${steps.selected_supplier.id}",
                "quantity": "${params.quantity}",
                "status": "PENDING",
                "created_by": "${context.user.id}"
            },
            output_as="new_order"
        ),
        CompositeOp.update_object(
            "${params.material_id}",
            updates={
                "pending_quantity":
                    "${object.pending_quantity"
                    " + params.quantity}",
                "last_order_date": "${now()}"
            }
        ),
        CompositeOp.notification(
            template="new_order_created",
            recipients=["warehouse_manager"],
            data={"order_id": "${steps.new_order.id}"}
        )
    ]) \
    .build()

#7.3 ReasoningEngine -- Rules Engine Implementation

coomia-dip ReasoningEngine is the core of the rules engine, implementing complete condition evaluation and action triggering:

Code
coomia-dip ReasoningEngine Architecture:

+---------------------------------------------------+
|  ReasoningEngine                                   |
|                                                     |
|  +---------------+     +------------------------+ |
|  | Event Bus     |---->| Rule Matcher            | |
|  |               |     | Match trigger conditions| |
|  | - ObjectChanged|     |                        | |
|  | - TimerFired   |     | Condition Evaluator:   | |
|  | - ActionDone   |     | - Property comparisons | |
|  | - ExternalEvent|     | - Aggregation checks   | |
|  +---------------+     | - Time-based conditions | |
|                         | - Cross-object queries  | |
|                         +-----------+------------+ |
|                                     |               |
|                                     v               |
|                         +------------------------+ |
|                         | Action Chain Executor   | |
|                         | Execute actions in order| |
|                         |                          | |
|                         | Step 1 -> Step 2 -> ... | |
|                         |                          | |
|                         | Supports:                | |
|                         | - Conditional branching  | |
|                         | - Parallel execution     | |
|                         | - Error handling         | |
|                         | - Retry strategies       | |
|                         +------------------------+ |
+---------------------------------------------------+

#7.4 FunctionRuntime -- Multi-Language Sandbox

coomia-dip FunctionRuntime supports secure sandboxed execution in five languages:

Code
FunctionRuntime Multi-Language Support:

+----------------------------------------------+
|  FunctionRuntime                              |
|                                                |
|  +----------+  +----------+  +----------+    |
|  | Python   |  |TypeScript|  | Groovy   |    |
|  | Sandbox  |  | Sandbox  |  | Sandbox  |    |
|  |          |  |          |  |          |    |
|  | CPython  |  | Deno     |  | GraalVM  |    |
|  | 3.11+    |  | Runtime  |  | Sandbox  |    |
|  +----------+  +----------+  +----------+    |
|                                                |
|  +----------+  +----------+                   |
|  | WASM     |  | Kotlin   |                   |
|  | Sandbox  |  | Sandbox  |                   |
|  |          |  |          |                   |
|  | Wasmtime |  | Kotlin   |                   |
|  | Runtime  |  | Script   |                   |
|  +----------+  +----------+                   |
|                                                |
|  Common Capability Layer:                      |
|  +------------------------------------------+ |
|  | - Ontology API access (permission-gated)  | |
|  | - Execution time limit (default 30s)      | |
|  | - Memory limit (default 256MB)            | |
|  | - CPU limit (single core, configurable)   | |
|  | - Network access control (default deny)   | |
|  | - Filesystem isolation (read-only tmpdir) | |
|  +------------------------------------------+ |
+----------------------------------------------+

Suitable scenarios for each language sandbox:

LanguageBest ForAdvantage
PythonData analysis, ML inference, scientific computingRich data science ecosystem
TypeScriptFrontend logic, API integration, string processingType safety, rich ecosystem
GroovyRule expressions, dynamic scriptingJVM ecosystem, DSL-friendly
WASMHigh-performance computing, cross-languageNear-native performance, secure isolation
KotlinJVM integration, Android extensionsJava interoperability

#Part 8: End-to-End Business Closed Loop in Practice

#8.1 Scenario: Intelligent Procurement Workflow

Let us use a complete example to connect Actions, Rules, and Functions:

Code
+--------------------------------------------------------+
|  Complete Closed Loop: Intelligent Procurement          |
|                                                          |
|  (1) Sensor data -> Inventory system updates stock qty  |
|        |                                                 |
|        v                                                 |
|  (2) Rule triggers: stock < safety stock                |
|        |                                                 |
|        v                                                 |
|  (3) Function executes: selectOptimalSupplier()         |
|     - Compare 3 suppliers on price, lead time, score    |
|     - Check annual contract remaining budget            |
|     - Return recommended supplier + suggested qty       |
|        |                                                 |
|        v                                                 |
|  (4) Action executes: Create PO (CompositeOp)          |
|     - CreateObject: PurchaseOrder                       |
|     - CreateRelation: PO -> Supplier                    |
|     - UpdateObject: Material.pendingQty                 |
|     - Notification -> procurement manager               |
|        |                                                 |
|        v                                                 |
|  (5) Rule triggers: order amount > $7,000               |
|        |                                                 |
|        v                                                 |
|  (6) Action executes: Create approval task              |
|     - Route to department director                      |
|     - Set 48-hour approval SLA                          |
|        |                                                 |
|        v                                                 |
|  (7) Director approves (manual Action: ApproveOrder)    |
|        |                                                 |
|        v                                                 |
|  (8) Rule triggers: order status -> APPROVED            |
|     - Webhook -> ERP system sync                        |
|     - Webhook -> Supplier portal notification           |
|     - UpdateObject: Budget consumed amount              |
|                                                          |
|  Full process: 7 auto steps + 1 manual = 2 days -> 2h  |
+--------------------------------------------------------+

#8.2 Implementation with coomia-dip SDK

Python
from ontology_sdk import OntoPlatform, ActionBuilder, RuleBuilder

platform = OntoPlatform(endpoint="grpc://localhost:9090")

# Define Rule: Auto-restock when below safety stock
low_stock_rule = RuleBuilder("auto_restock") \
    .description("Auto-trigger restock when inventory"
                 " drops below safety stock") \
    .when("Material") \
    .condition("object.stock_level < object.safety_stock") \
    .condition("object.status == 'ACTIVE'") \
    .unless("object.pending_quantity > 0") \
    .throttle(hours=24, per="object.id") \
    .then_action("restock_material", {
        "material_id": "${trigger.object.id}",
        "quantity": "${trigger.object.safety_stock"
                    " - trigger.object.stock_level}"
    }) \
    .build()

# Define Rule: Auto-route large orders for approval
approval_rule = RuleBuilder("auto_approval_routing") \
    .description("Route purchase orders above threshold"
                 " for approval") \
    .when("PurchaseOrder") \
    .condition("object.status == 'PENDING'") \
    .condition("object.total_amount > 50000") \
    .then_action("create_approval_task", {
        "order_id": "${trigger.object.id}",
        "approver_role": "department_director",
        "sla_hours": 48
    }) \
    .build()

# Register rules
platform.reasoning.register_rule(low_stock_rule)
platform.reasoning.register_rule(approval_rule)

# Execute Action (manual trigger)
result = platform.actions.execute(
    action_type="restock_material",
    params={
        "material_id": "MAT-A2047",
        "quantity": 100
    },
    dry_run=True  # Preview first
)
print(f"Preview: Will create "
      f"{len(result.preview.objects_created)} objects")
print(f"Estimated cost: ${result.preview.estimated_cost}")

# Confirm execution
result = platform.actions.execute(
    action_type="restock_material",
    params={
        "material_id": "MAT-A2047",
        "quantity": 100
    },
    dry_run=False  # Actually execute
)
print(f"Result: {result.status}")
print(f"Audit ID: {result.audit_id}")

#Part 9: Actions vs. Traditional Approaches

#9.1 Comparison with REST APIs

DimensionREST APIPalantir Actions
SemanticsTechnical ops (POST/PUT/DELETE)Business ops (restock/approve/transfer)
Parameter validationHand-codedDeclaratively defined
PermissionsMiddleware interceptionBuilt into Action definition
AuditSeparate implementationAutomatic recording
Impact previewNot supportedBuilt-in Dry Run
Batch operationsBuild yourselfFramework support
Side effectsImplicit (read the code)Explicitly declared

#9.2 Comparison with Workflow Engines

Code
Traditional Workflow Engine (Camunda/Activiti):

+----------+     +----------+     +----------+
| Workflow |---->| External |---->| Database |
| BPMN     |     | Services |     | (SQL)    |
| Diagram  |     | (REST)   |     |          |
+----------+     +----------+     +----------+
  Process def     Business logic   Data storage
  (Three separate layers requiring extensive glue code)

Palantir Actions + Rules:

+------------------------------------------+
|              Ontology                     |
|                                            |
|  Objects <--> Actions <--> Rules          |
|  (Data)       (Operations)  (Logic)       |
|                                            |
|  All unified under Ontology semantics     |
|  (Zero glue code)                         |
+------------------------------------------+

#Key Takeaways

  1. The core value of Actions lies in "side effect declarations" -- each Action explicitly declares which objects it will create, modify, or delete. This enables automatic permission checking, audit logging, impact preview, and rollback mechanisms without manual coding. This is the fundamental design difference between Palantir and traditional APIs.

  2. The Rules engine implements the "see-to-do" automation loop -- through the "condition -> trigger -> action chain" pattern, systems can automatically execute a series of operations when business conditions are detected. Each individual rule stays simple, but through event chaining they can handle extremely complex business scenarios.

  3. coomia-dip provides ActionEngine with 10 executor types, ReasoningEngine for rules, and FunctionRuntime with 5 language sandboxes -- these three components together cover everything from simple button clicks to complex automated decision chains. The CompositeOp executor allows composing multiple operations into atomic transactions, which is the key to implementing enterprise-grade business processes.

#Next Article Preview

Article 12: Palantir's Security Model -- Why Governments Trust It with Classified Data

Actions and Rules enable systems to automatically execute operations, but who has permission to execute what? Data security is Palantir's foundation. Next, we will dive deep into Palantir's multi-layered security model: from military-grade information compartmentalization to fine-grained row-and-column-level access control, revealing why the world's most sensitive organizations trust Palantir with their most classified data.

#palantir #actions #rules #functions #automation #ontology #coomia-dip #closed-loop