CI/CD Pipeline – A Complete Agentic Net Example with Error Handling
This guide demonstrates a real-world CI/CD Pipeline built as an Agentic Net. Unlike the simple linear showcase, this example includes error paths, conditional routing, and multiple postsets – showing how production agentic processes handle success, failure, and decision branches.
You’ll see all six transition types working together with proper error handling:
- PASS – Conditional routing based on branch type
- MAP – Transform commit data into build payload
- HTTP – Call CI service with success/failure paths
- LLM – AI quality analysis with pass/fail routing
- AGENT – Intelligent deployment decisions with review option
- COMMAND – Execute deployment with success/failure handling
Pipeline Overview
A code commit flows through validation, building, testing, quality analysis, deployment decision, and execution – with proper error handling at each stage:

Place Structure
Main Flow (y=200)
| Place | X | Purpose | Initial Tokens |
|---|---|---|---|
p-commit |
50 | Incoming code commits | 1 (sample commit) |
p-feature-build |
250 | Feature branch commits (y=150) | 0 |
p-main-build |
250 | Main branch commits (y=250) | 0 |
p-build-payload |
400 | Normalized build configuration | 0 |
p-test-results |
600 | Successful test results | 0 |
p-quality-report |
800 | Quality analysis passed | 0 |
p-deploy-decision |
1000 | Approved for deployment | 0 |
p-deployed |
1200 | Successfully deployed | 0 |
Error Paths (y=350)
| Place | X | Purpose | Triggered By |
|---|---|---|---|
p-build-failed |
550 | Build or test failures | t-build-test (error) |
p-quality-failed |
800 | Quality issues detected | t-analyze (quality fail) |
p-manual-review |
1000 | Needs human review | t-decide (uncertain) |
p-deploy-failed |
1200 | Deployment failed | t-deploy (error) |
Transition Details
1. t-route (PASS) – Branch-Based Routing
Routes commits to different build paths based on branch type. Demonstrates conditional emit with multiple postsets.
{
"id": "t-route",
"kind": "pass",
"mode": "SINGLE",
"presets": {
"commit": {
"placeId": "p-commit",
"host": "default@localhost:8080",
"arcql": "FROM $ LIMIT 1",
"take": "FIRST",
"consume": true
}
},
"postsets": {
"feature": { "placeId": "p-feature-build", "host": "default@localhost:8080" },
"main": { "placeId": "p-main-build", "host": "default@localhost:8080" }
},
"action": { "type": "pass" },
"emit": [
{ "to": "feature", "from": "@input.data", "when": "branch == 'feature'" },
{ "to": "main", "from": "@input.data", "when": "branch == 'main'" }
]
}
Key Pattern: Multiple postsets with when conditions route tokens to different places based on data.
2. t-prepare (MAP) – Build Configuration
Transforms raw commit data into a structured build payload with computed fields.
{
"id": "t-prepare",
"kind": "map",
"mode": "SINGLE",
"presets": {
"feature": {
"placeId": "p-feature-build",
"host": "default@localhost:8080",
"arcql": "FROM $ LIMIT 1",
"take": "FIRST",
"consume": true
},
"main": {
"placeId": "p-main-build",
"host": "default@localhost:8080",
"arcql": "FROM $ LIMIT 1",
"take": "FIRST",
"consume": true
}
},
"postsets": {
"payload": { "placeId": "p-build-payload", "host": "default@localhost:8080" }
},
"action": {
"type": "map",
"template": {
"buildId": "BUILD-${input.data.commitId}",
"commitId": "${input.data.commitId}",
"branch": "${input.data.branch}",
"author": "${input.data.author}",
"message": "${input.data.message}",
"files": "${input.data.files}",
"buildConfig": {
"priority": "${input.data.branch == 'main' ? 'high' : 'normal'}",
"runTests": true,
"coverage": true
},
"status": "pending",
"createdAt": "${input.data.timestamp}"
}
},
"emit": [
{ "to": "payload", "from": "@response", "when": "success" }
]
}
Key Pattern: Multiple presets (feature + main) converge into single output with enriched structure.
3. t-build-test (HTTP) – CI Service Call
Calls external CI service with success/error routing to different postsets.
{
"id": "t-build-test",
"kind": "task",
"mode": "SINGLE",
"presets": {
"payload": {
"placeId": "p-build-payload",
"host": "default@localhost:8080",
"arcql": "FROM $ LIMIT 1",
"take": "FIRST",
"consume": true
}
},
"postsets": {
"success": { "placeId": "p-test-results", "host": "default@localhost:8080" },
"failed": { "placeId": "p-build-failed", "host": "default@localhost:8080" }
},
"action": {
"type": "http",
"method": "POST",
"url": "https://ci-service.example.com/builds",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer ${env.CI_TOKEN}"
},
"body": {
"buildId": "${payload.data.buildId}",
"commitId": "${payload.data.commitId}",
"branch": "${payload.data.branch}",
"config": "${payload.data.buildConfig}"
},
"timeout": 300000,
"retry": {
"maxAttempts": 3,
"backoffMs": 5000
}
},
"emit": [
{ "to": "success", "from": "@response", "when": "success" },
{ "to": "failed", "from": "@response", "when": "error" }
]
}
Key Pattern: when: "success" and when: "error" route HTTP results to appropriate places.
4. t-analyze (LLM) – AI Quality Analysis
Uses AI to analyze test results and code quality, routing to pass/fail based on analysis.
{
"id": "t-analyze",
"kind": "task",
"mode": "SINGLE",
"presets": {
"results": {
"placeId": "p-test-results",
"host": "default@localhost:8080",
"arcql": "FROM $ LIMIT 1",
"take": "FIRST",
"consume": true
}
},
"postsets": {
"passed": { "placeId": "p-quality-report", "host": "default@localhost:8080" },
"failed": { "placeId": "p-quality-failed", "host": "default@localhost:8080" }
},
"action": {
"type": "llm",
"nl": "Analyze these test results and determine code quality. Return JSON with: quality ('pass' or 'fail'), score (0-100), issues (array of problems), and summary.",
"system": "You are a senior code quality analyst. Be strict about test coverage (>80%) and code quality. Return valid JSON only."
},
"emit": [
{ "to": "passed", "from": "@response", "when": "quality == 'pass'" },
{ "to": "failed", "from": "@response", "when": "quality == 'fail'" }
]
}
Key Pattern: LLM output field (quality) determines routing via when condition.
5. t-decide (AGENT) – Deployment Decision
Autonomous AI agent makes deployment decisions with three-way routing: approve, review, or reject.
{
"id": "t-decide",
"kind": "agent",
"mode": "SINGLE",
"presets": {
"report": {
"placeId": "p-quality-report",
"host": "default@localhost:8080",
"arcql": "FROM $ LIMIT 1",
"take": "FIRST",
"consume": true
}
},
"postsets": {
"approved": { "placeId": "p-deploy-decision", "host": "default@localhost:8080" },
"review": { "placeId": "p-manual-review", "host": "default@localhost:8080" }
},
"action": {
"type": "agent",
"nl": "Review this quality report and decide: 1) 'approved' if quality score >= 85 and no critical issues, 2) 'review' if score 70-84 or minor concerns, 3) 'rejected' if score < 70. Create a deployment decision token with: decision, reason, riskLevel, and recommendations.",
"maxIterations": 5
},
"emit": [
{ "to": "approved", "from": "@response", "when": "decision == 'approved'" },
{ "to": "review", "from": "@response", "when": "decision == 'review'" }
]
}
Key Pattern: Agent’s decision field drives conditional routing to different paths.
6. t-deploy (COMMAND) – Execute Deployment
Executes deployment scripts with success/failure error handling.
{
"id": "t-deploy",
"kind": "command",
"mode": "SINGLE",
"presets": {
"decision": {
"placeId": "p-deploy-decision",
"host": "default@localhost:8080",
"arcql": "FROM $ LIMIT 1",
"take": "FIRST",
"consume": true
}
},
"postsets": {
"success": { "placeId": "p-deployed", "host": "default@localhost:8080" },
"failed": { "placeId": "p-deploy-failed", "host": "default@localhost:8080" }
},
"action": {
"type": "command",
"inputPlace": "decision",
"dispatch": [{ "executor": "bash", "channel": "default" }],
"await": "ALL",
"timeoutMs": 600000
},
"emit": [
{ "to": "success", "from": "@result", "when": "success" },
{ "to": "failed", "from": "@result", "when": "error" }
]
}
Key Pattern: Command execution results route to success or failure places.
Sample Token Flow
Initial Commit Token
{
"commitId": "abc123def",
"branch": "main",
"author": "developer@company.com",
"message": "feat: add user authentication",
"files": ["src/auth.ts", "src/login.ts", "tests/auth.test.ts"],
"timestamp": "2026-01-06T10:30:00Z"
}
After MAP (Build Payload)
{
"buildId": "BUILD-abc123def",
"commitId": "abc123def",
"branch": "main",
"author": "developer@company.com",
"message": "feat: add user authentication",
"files": ["src/auth.ts", "src/login.ts", "tests/auth.test.ts"],
"buildConfig": {
"priority": "high",
"runTests": true,
"coverage": true
},
"status": "pending",
"createdAt": "2026-01-06T10:30:00Z"
}
After LLM Analysis
{
"quality": "pass",
"score": 92,
"issues": [],
"summary": "All tests passing with 94% coverage. Code follows best practices.",
"testResults": {
"passed": 47,
"failed": 0,
"skipped": 2
},
"coverage": 94.2
}
After AGENT Decision
{
"decision": "approved",
"reason": "Quality score 92% exceeds threshold. No critical issues detected.",
"riskLevel": "low",
"recommendations": [
"Consider adding integration tests for auth flow"
],
"approvedAt": "2026-01-06T10:35:00Z"
}
Error Handling Patterns
Pattern 1: HTTP Success/Error Split
"emit": [
{ "to": "success-place", "from": "@response", "when": "success" },
{ "to": "error-place", "from": "@response", "when": "error" }
]
Pattern 2: Field-Based Routing
"emit": [
{ "to": "high-priority", "from": "@response", "when": "priority == 'high'" },
{ "to": "normal-priority", "from": "@response", "when": "priority == 'normal'" },
{ "to": "low-priority", "from": "@response", "when": "priority == 'low'" }
]
Pattern 3: Threshold-Based Routing
"emit": [
{ "to": "approved", "from": "@response", "when": "score >= 85" },
{ "to": "review", "from": "@response", "when": "score >= 70 && score < 85" },
{ "to": "rejected", "from": "@response", "when": "score < 70" }
]
Complete PNML
{
"net": {
"places": {
"p-commit": { "id": "p-commit", "x": 50, "y": 200, "tokens": 1, "label": "Commit" },
"p-feature-build": { "id": "p-feature-build", "x": 250, "y": 150, "tokens": 0, "label": "Feature" },
"p-main-build": { "id": "p-main-build", "x": 250, "y": 250, "tokens": 0, "label": "Main" },
"p-build-payload": { "id": "p-build-payload", "x": 400, "y": 200, "tokens": 0, "label": "Payload" },
"p-test-results": { "id": "p-test-results", "x": 600, "y": 200, "tokens": 0, "label": "Tests" },
"p-quality-report": { "id": "p-quality-report", "x": 800, "y": 200, "tokens": 0, "label": "Quality" },
"p-deploy-decision": { "id": "p-deploy-decision", "x": 1000, "y": 200, "tokens": 0, "label": "Decision" },
"p-deployed": { "id": "p-deployed", "x": 1200, "y": 200, "tokens": 0, "label": "Deployed" },
"p-build-failed": { "id": "p-build-failed", "x": 550, "y": 350, "tokens": 0, "label": "Build Failed" },
"p-quality-failed": { "id": "p-quality-failed", "x": 800, "y": 350, "tokens": 0, "label": "Quality Failed" },
"p-manual-review": { "id": "p-manual-review", "x": 1000, "y": 350, "tokens": 0, "label": "Manual Review" },
"p-deploy-failed": { "id": "p-deploy-failed", "x": 1200, "y": 350, "tokens": 0, "label": "Deploy Failed" }
},
"transitions": {
"t-route": { "id": "t-route", "x": 150, "y": 200, "label": "PASS" },
"t-prepare": { "id": "t-prepare", "x": 325, "y": 200, "label": "MAP" },
"t-build-test": { "id": "t-build-test", "x": 500, "y": 200, "label": "HTTP" },
"t-analyze": { "id": "t-analyze", "x": 700, "y": 200, "label": "LLM" },
"t-decide": { "id": "t-decide", "x": 900, "y": 200, "label": "AGENT" },
"t-deploy": { "id": "t-deploy", "x": 1100, "y": 200, "label": "COMMAND" }
},
"arcs": {
"a1": { "id": "a1", "source": "p-commit", "target": "t-route" },
"a2": { "id": "a2", "source": "t-route", "target": "p-feature-build" },
"a3": { "id": "a3", "source": "t-route", "target": "p-main-build" },
"a4": { "id": "a4", "source": "p-feature-build", "target": "t-prepare" },
"a5": { "id": "a5", "source": "p-main-build", "target": "t-prepare" },
"a6": { "id": "a6", "source": "t-prepare", "target": "p-build-payload" },
"a7": { "id": "a7", "source": "p-build-payload", "target": "t-build-test" },
"a8": { "id": "a8", "source": "t-build-test", "target": "p-test-results" },
"a9": { "id": "a9", "source": "t-build-test", "target": "p-build-failed" },
"a10": { "id": "a10", "source": "p-test-results", "target": "t-analyze" },
"a11": { "id": "a11", "source": "t-analyze", "target": "p-quality-report" },
"a12": { "id": "a12", "source": "t-analyze", "target": "p-quality-failed" },
"a13": { "id": "a13", "source": "p-quality-report", "target": "t-decide" },
"a14": { "id": "a14", "source": "t-decide", "target": "p-deploy-decision" },
"a15": { "id": "a15", "source": "t-decide", "target": "p-manual-review" },
"a16": { "id": "a16", "source": "p-deploy-decision", "target": "t-deploy" },
"a17": { "id": "a17", "source": "t-deploy", "target": "p-deployed" },
"a18": { "id": "a18", "source": "t-deploy", "target": "p-deploy-failed" }
}
}
}
Key Takeaways
- Multiple postsets enable branching agentic processes with error paths
- Conditional emit (
when) routes tokens based on data values - success/error built-in conditions handle HTTP and command failures
- Field-based routing lets AI outputs drive agentic process decisions
- Error places (y=350) create clear visual separation from success path
- All 6 transitions work together in a realistic production agentic process
This CI/CD Pipeline demonstrates how Agentic Nets handle real-world complexity with proper error handling, conditional routing, and intelligent decision-making.
Related Guides
- Building Blocks Overview – Introduction to all transition types
- PASS Transitions – Conditional routing patterns
- HTTP Transitions – Error handling for API calls
- AGENT Transitions – Autonomous decision-making