Command Transitions

Command Transitions – The Complete Guide to Shell Execution in Agentic Nets

The Command transition enables Petri nets to execute shell commands, scripts, and file system operations through the agentic-net-executor service. While LLM transitions process AI prompts and Agent transitions enable autonomous reasoning, Command transitions provide direct system execution – running bash commands, scripts, and file operations with full result capture.

In this comprehensive guide, we’ll explore every capability of Command transitions:

  • Bash execution – single commands, multi-line scripts, environment variables
  • File system operations – readFile, writeFile, listDir, exists, mkdir, delete, stat
  • Batch processing – multiple commands executed together with aggregated results
  • Result capture – stdout, stderr, exit codes, execution duration
  • Timeout handling – configurable per-command timeouts with graceful termination
  • Error routing – conditional emit based on success/failure status
  • Security controls – command blacklisting for dangerous operations

What Makes Command Transitions Different?

Unlike LLM/Agent transitions that process natural language, Command transitions execute concrete system operations. They:

  1. Execute directly – run bash commands or file operations via ProcessBuilder
  2. Capture full output – stdout, stderr, exit code, and execution timing
  3. Support multiple executors – bash for shell commands, fs for file operations
  4. Batch operations – group multiple commands by executor for efficient execution
  5. Return structured results – standardized CommandResult format with metadata

This makes Command transitions ideal for automation tasks, CI/CD pipelines, system administration, and external tool integration.

Architecture Overview

Command transitions run on the agentic-net-executor service (port 8084), separate from agentic-net-master:

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│  agentic-net-node  │    │ agentic-net-executor│    │   System Shell  │
│    (port 8080)  │───▶│   (port 8084)    │───▶│   bash / fs     │
│   Token Store   │    │ Command Handler  │    │   Operations    │
└─────────────────┘    └──────────────────┘    └─────────────────┘
         │                      │
         │                      ▼
         │              ┌──────────────────┐
         └──────────────│  Result Tokens   │
                        └──────────────────┘

Command Token Schema

Every Command token follows this standardized schema:

{
  "kind": "command",           // Always "command" for command tokens
  "id": "unique-cmd-id",       // Unique command identifier (required)
  "executor": "bash",          // Target executor: "bash" or "fs"
  "command": "exec",           // Command type: "exec", "script", "readFile", etc.
  "args": {                    // Command-specific arguments
    "command": "echo Hello",   // For bash: the actual shell command
    "workingDir": "/path/to/dir",
    "timeoutMs": 60000,        // Default 60s, max 600000 (10 min)
    "captureStderr": true,     // Merge stderr into stdout (default true)
    "env": {"KEY": "value"}    // Optional environment variables
  },
  "expect": "text",            // Expected return format: "json", "text", "binary"
  "meta": {                    // Optional metadata for correlation
    "correlationId": "req-001"
  }
}

Required Fields

Field Type Description
kind string Must be "command"
id string Unique identifier for this command
executor string Executor type: "bash" or "fs"
command string Operation type (executor-specific)
args object Command arguments

Supported Executors

Bash Executor

The bash executor runs shell commands via ProcessBuilder("bash", "-c", command):

Command Types

  • exec – Execute a single shell command
  • script – Execute a multi-line shell script

Bash Args Structure

{
  "command": "ls -la /tmp",           // The shell command to execute
  "workingDir": "/home/user",         // Working directory (optional)
  "timeoutMs": 30000,                 // Timeout in milliseconds
  "captureStderr": true,              // Merge stderr into stdout
  "env": {                            // Additional environment variables
    "MY_VAR": "value",
    "PATH": "/custom/bin:$PATH"
  }
}

Example: Simple Echo Command

{
  "kind": "command",
  "id": "echo-001",
  "executor": "bash",
  "command": "exec",
  "args": {
    "command": "echo 'Hello from AgenticOS!'",
    "timeoutMs": 10000
  },
  "expect": "text"
}

Example: Script with Multiple Lines

{
  "kind": "command",
  "id": "script-001",
  "executor": "bash",
  "command": "script",
  "args": {
    "command": "#!/bin/bash\nfor i in 1 2 3; do\n  echo \"Iteration $i\"\ndone",
    "timeoutMs": 30000
  },
  "expect": "text"
}

Example: Environment Variables

{
  "kind": "command",
  "id": "env-001",
  "executor": "bash",
  "command": "exec",
  "args": {
    "command": "echo \"User: $MY_USER, App: $MY_APP\"",
    "env": {
      "MY_USER": "alice",
      "MY_APP": "agenticos"
    },
    "timeoutMs": 10000
  },
  "expect": "text"
}

File System Executor

The fs executor provides file system operations without shell command parsing:

Command Types

Command Description Args
readFile Read file contents path, encoding
writeFile Write file contents path, content, encoding
listDir List directory contents path, recursive
exists Check if path exists path
mkdir Create directory path, recursive
delete Delete file/directory path, recursive
stat Get file/directory stats path

Example: Read File

{
  "kind": "command",
  "id": "read-001",
  "executor": "fs",
  "command": "readFile",
  "args": {
    "path": "/etc/hosts",
    "encoding": "utf-8"
  },
  "expect": "text"
}

Example: List Directory

{
  "kind": "command",
  "id": "list-001",
  "executor": "fs",
  "command": "listDir",
  "args": {
    "path": "/tmp",
    "recursive": false
  },
  "expect": "json"
}

Example: Check File Exists

{
  "kind": "command",
  "id": "exists-001",
  "executor": "fs",
  "command": "exists",
  "args": {
    "path": "/var/log/syslog"
  },
  "expect": "json"
}

Command Result Schema

Every command execution returns a structured CommandResult:

{
  "id": "echo-001",              // Matches input command ID
  "status": "SUCCESS",           // SUCCESS, FAILED, TIMEOUT, SKIPPED
  "output": {
    "exitCode": 0,               // Process exit code (bash only)
    "stdout": "Hello from AgenticOS!",
    "stderr": "",
    "success": true,
    "command": "echo 'Hello from AgenticOS!'"
  },
  "error": null,                 // Error message if failed
  "durationMs": 15,              // Execution time in milliseconds
  "completedAt": "2026-01-06T10:00:00Z",
  "meta": {                      // Echoed from input
    "correlationId": "req-001"
  }
}

Status Values

Status Description
SUCCESS Command completed successfully (exit code 0)
FAILED Command failed (non-zero exit code or error)
TIMEOUT Command exceeded configured timeout
SKIPPED Command was skipped (validation failure)

Anatomy of a Command Transition Inscription

Every Command transition inscription follows this structure:

{
  "id": "t-execute-commands",
  "kind": "command",
  "mode": "SINGLE",

  "presets": {
    "commands": {
      "placeId": "command-queue",
      "host": "myModel@localhost:8080",
      "arcql": "FROM $ WHERE $.kind==\"command\"",
      "take": "ALL",
      "consume": true
    }
  },

  "postsets": {
    "results": {
      "placeId": "results-queue",
      "host": "myModel@localhost:8080"
    }
  },

  "action": {
    "type": "command",
    "inputPlace": "commands",
    "groupBy": "executor",
    "dispatch": [
      { "executor": "bash", "channel": "default" },
      { "executor": "fs", "channel": "default" }
    ],
    "await": "ALL",
    "timeoutMs": 300000
  },

  "emit": [
    { "to": "results", "from": "@response", "when": "success" }
  ]
}

Key Inscription Fields

Field Description
kind: "command" Identifies this as a Command transition
action.type: "command" Specifies the Command action handler
action.inputPlace Name of preset containing command tokens
action.groupBy Group commands by executor type
action.dispatch Routing rules for each executor
action.await "ALL" to wait for all commands
action.timeoutMs Overall transition timeout

Batch Result Structure

When multiple commands are executed, results are aggregated into a BatchResult:

{
  "batchPrefix": "t-execute-commands-1704542400000",
  "batchResults": [
    {
      "executor": "bash",
      "results": [
        { "id": "cmd-1", "status": "SUCCESS", "output": {...}, "durationMs": 15 },
        { "id": "cmd-2", "status": "SUCCESS", "output": {...}, "durationMs": 23 }
      ],
      "totalCount": 2,
      "successCount": 2,
      "failedCount": 0
    },
    {
      "executor": "fs",
      "results": [
        { "id": "cmd-3", "status": "SUCCESS", "output": {...}, "durationMs": 5 }
      ],
      "totalCount": 1,
      "successCount": 1,
      "failedCount": 0
    }
  ],
  "success": true
}

Real-World Use Cases

1. CI/CD Pipeline Automation

Execute build, test, and deployment commands as agentic process steps:

// Build step command token
{
  "kind": "command",
  "id": "build-step",
  "executor": "bash",
  "command": "exec",
  "args": {
    "command": "npm run build",
    "workingDir": "/app/project",
    "timeoutMs": 300000,
    "env": { "NODE_ENV": "production" }
  },
  "expect": "text",
  "meta": { "pipeline": "release-v2.1", "step": "build" }
}

2. Log File Analysis

Read and analyze log files for error patterns:

{
  "kind": "command",
  "id": "analyze-logs",
  "executor": "bash",
  "command": "exec",
  "args": {
    "command": "grep -c 'ERROR' /var/log/app.log",
    "timeoutMs": 30000
  },
  "expect": "text"
}

3. System Health Checks

Monitor disk space, memory, and process status:

{
  "kind": "command",
  "id": "health-check",
  "executor": "bash",
  "command": "exec",
  "args": {
    "command": "df -h / | tail -1 | awk '{print $5}'",
    "timeoutMs": 10000
  },
  "expect": "text",
  "meta": { "check": "disk-usage" }
}

4. Database Backup

Execute database dump operations with proper credentials:

{
  "kind": "command",
  "id": "db-backup",
  "executor": "bash",
  "command": "exec",
  "args": {
    "command": "pg_dump $DB_NAME | gzip > /backups/db-$(date +%Y%m%d).sql.gz",
    "env": {
      "DB_NAME": "production",
      "PGPASSWORD": "${secrets.db_password}"
    },
    "timeoutMs": 600000
  },
  "expect": "text"
}

5. AI CLI Tool Integration

Invoke Claude Code or other AI CLIs from agentic processes:

{
  "kind": "command",
  "id": "claude-analysis",
  "executor": "bash",
  "command": "exec",
  "args": {
    "command": "export PATH=$HOME/.local/bin:$PATH && claude -p 'Analyze this file for security issues' --no-session-persistence < /dev/null",
    "workingDir": "/project",
    "timeoutMs": 180000,
    "env": { "HOME": "/Users/developer" }
  },
  "expect": "text"
}

Important: Always redirect stdin with < /dev/null when running interactive CLIs to prevent blocking.

Security Considerations

The BashCommandHandler includes a security blacklist to prevent dangerous operations:

Blacklisted Commands

  • rm -rf / – Recursive deletion of root
  • sudo – Privilege escalation
  • mkfs – Filesystem formatting
  • dd if=/dev/zero – Disk overwriting
  • :(){ :|:& };: – Fork bomb

Commands matching blacklist patterns are rejected with SKIPPED status.

Best Practices

  1. Use absolute paths – Avoid path traversal vulnerabilities
  2. Validate inputs – Sanitize any user-provided data in commands
  3. Set timeouts – Always configure appropriate timeouts
  4. Limit permissions – Run executor service with minimal privileges
  5. Audit logging – Enable logging for command execution audit trail

API Reference

Register Transition

POST http://localhost:8084/api/pnml/transitions
Content-Type: application/json

{
  "transitionId": "my-command-transition",
  "inscription": { ... },
  "autoStart": true,
  "tags": { "type": "command" }
}

Fire Transition Manually

POST http://localhost:8084/api/pnml/transitions/{transitionId}/fireOnce
Content-Type: application/json

{
  "modelId": "my-model",
  "boundTokens": {
    "commands": [
      {
        "kind": "command",
        "id": "test-001",
        "executor": "bash",
        "command": "exec",
        "args": { "command": "echo Hello", "timeoutMs": 30000 },
        "expect": "text"
      }
    ]
  }
}

Delete Transition

DELETE http://localhost:8084/api/pnml/transitions/{transitionId}

Error Handling Patterns

Conditional Emit Based on Status

{
  "emit": [
    { "to": "success-queue", "from": "@response", "when": "success" },
    { "to": "error-queue", "from": "@response", "when": "error" }
  ]
}

Handling Timeouts

Commands that exceed their timeoutMs are terminated and return:

{
  "id": "slow-cmd",
  "status": "TIMEOUT",
  "output": null,
  "error": "Command timed out after 10000ms",
  "durationMs": 10000
}

Handling Non-Zero Exit Codes

Failed commands return with FAILED status:

{
  "id": "failing-cmd",
  "status": "FAILED",
  "output": {
    "exitCode": 1,
    "stdout": "",
    "stderr": "Error: File not found",
    "success": false
  },
  "error": null,
  "durationMs": 15
}

Integration with Other Transitions

Command transitions work seamlessly with other transition types:

  • Agent → Command: Agent creates command tokens, Command executes them
  • Command → LLM: Command output analyzed by LLM for insights
  • MAP → Command: Transform data into command tokens
  • Command → HTTP: Command results sent to external webhooks

Summary

Command transitions provide direct system execution within Agentic Nets. Key capabilities:

  • Shell execution via bash executor with full environment control
  • File operations via fs executor without shell parsing
  • Batch processing with grouped results by executor
  • Complete output capture including stdout, stderr, exit codes
  • Timeout handling with configurable per-command limits
  • Security controls via command blacklisting
  • Integration patterns with other transition types

For automation, CI/CD, system administration, and external tool integration, Command transitions are the essential building block in your Agentic Agentic nets.

Leave a Reply

Your email address will not be published. Required fields are marked *