{"id":"94ca5dde-45f8-4ade-9ba9-5c9aa8f36c39","shortId":"JA9UHJ","kind":"skill","title":"saga-orchestration","tagline":"Patterns for managing distributed transactions and long-running business processes.","description":"# Saga Orchestration\n\nPatterns for managing distributed transactions and long-running business processes.\n\n## Do not use this skill when\n\n- The task is unrelated to saga orchestration\n- You need a different domain or tool outside this scope\n\n## Instructions\n\n- Clarify goals, constraints, and required inputs.\n- Apply relevant best practices and validate outcomes.\n- Provide actionable steps and verification.\n- If detailed examples are required, open `resources/implementation-playbook.md`.\n\n## Use this skill when\n\n- Coordinating multi-service transactions\n- Implementing compensating transactions\n- Managing long-running business workflows\n- Handling failures in distributed systems\n- Building order fulfillment processes\n- Implementing approval workflows\n\n## Core Concepts\n\n### 1. Saga Types\n\n```\nChoreography                    Orchestration\n┌─────┐  ┌─────┐  ┌─────┐     ┌─────────────┐\n│Svc A│─►│Svc B│─►│Svc C│     │ Orchestrator│\n└─────┘  └─────┘  └─────┘     └──────┬──────┘\n   │        │        │               │\n   ▼        ▼        ▼         ┌─────┼─────┐\n Event    Event    Event       ▼     ▼     ▼\n                            ┌────┐┌────┐┌────┐\n                            │Svc1││Svc2││Svc3│\n                            └────┘└────┘└────┘\n```\n\n### 2. Saga Execution States\n\n| State            | Description                    |\n| ---------------- | ------------------------------ |\n| **Started**      | Saga initiated                 |\n| **Pending**      | Waiting for step completion    |\n| **Compensating** | Rolling back due to failure    |\n| **Completed**    | All steps succeeded            |\n| **Failed**       | Saga failed after compensation |\n\n## Templates\n\n### Template 1: Saga Orchestrator Base\n\n```python\nfrom abc import ABC, abstractmethod\nfrom dataclasses import dataclass, field\nfrom enum import Enum\nfrom typing import List, Dict, Any, Optional\nfrom datetime import datetime\nimport uuid\n\nclass SagaState(Enum):\n    STARTED = \"started\"\n    PENDING = \"pending\"\n    COMPENSATING = \"compensating\"\n    COMPLETED = \"completed\"\n    FAILED = \"failed\"\n\n\n@dataclass\nclass SagaStep:\n    name: str\n    action: str\n    compensation: str\n    status: str = \"pending\"\n    result: Optional[Dict] = None\n    error: Optional[str] = None\n    executed_at: Optional[datetime] = None\n    compensated_at: Optional[datetime] = None\n\n\n@dataclass\nclass Saga:\n    saga_id: str\n    saga_type: str\n    state: SagaState\n    data: Dict[str, Any]\n    steps: List[SagaStep]\n    current_step: int = 0\n    created_at: datetime = field(default_factory=datetime.utcnow)\n    updated_at: datetime = field(default_factory=datetime.utcnow)\n\n\nclass SagaOrchestrator(ABC):\n    \"\"\"Base class for saga orchestrators.\"\"\"\n\n    def __init__(self, saga_store, event_publisher):\n        self.saga_store = saga_store\n        self.event_publisher = event_publisher\n\n    @abstractmethod\n    def define_steps(self, data: Dict) -> List[SagaStep]:\n        \"\"\"Define the saga steps.\"\"\"\n        pass\n\n    @property\n    @abstractmethod\n    def saga_type(self) -> str:\n        \"\"\"Unique saga type identifier.\"\"\"\n        pass\n\n    async def start(self, data: Dict) -> Saga:\n        \"\"\"Start a new saga.\"\"\"\n        saga = Saga(\n            saga_id=str(uuid.uuid4()),\n            saga_type=self.saga_type,\n            state=SagaState.STARTED,\n            data=data,\n            steps=self.define_steps(data)\n        )\n        await self.saga_store.save(saga)\n        await self._execute_next_step(saga)\n        return saga\n\n    async def handle_step_completed(self, saga_id: str, step_name: str, result: Dict):\n        \"\"\"Handle successful step completion.\"\"\"\n        saga = await self.saga_store.get(saga_id)\n\n        # Update step\n        for step in saga.steps:\n            if step.name == step_name:\n                step.status = \"completed\"\n                step.result = result\n                step.executed_at = datetime.utcnow()\n                break\n\n        saga.current_step += 1\n        saga.updated_at = datetime.utcnow()\n\n        # Check if saga is complete\n        if saga.current_step >= len(saga.steps):\n            saga.state = SagaState.COMPLETED\n            await self.saga_store.save(saga)\n            await self._on_saga_completed(saga)\n        else:\n            saga.state = SagaState.PENDING\n            await self.saga_store.save(saga)\n            await self._execute_next_step(saga)\n\n    async def handle_step_failed(self, saga_id: str, step_name: str, error: str):\n        \"\"\"Handle step failure - start compensation.\"\"\"\n        saga = await self.saga_store.get(saga_id)\n\n        # Mark step as failed\n        for step in saga.steps:\n            if step.name == step_name:\n                step.status = \"failed\"\n                step.error = error\n                break\n\n        saga.state = SagaState.COMPENSATING\n        saga.updated_at = datetime.utcnow()\n        await self.saga_store.save(saga)\n\n        # Start compensation from current step backwards\n        await self._compensate(saga)\n\n    async def _execute_next_step(self, saga: Saga):\n        \"\"\"Execute the next step in the saga.\"\"\"\n        if saga.current_step >= len(saga.steps):\n            return\n\n        step = saga.steps[saga.current_step]\n        step.status = \"executing\"\n        await self.saga_store.save(saga)\n\n        # Publish command to execute step\n        await self.event_publisher.publish(\n            step.action,\n            {\n                \"saga_id\": saga.saga_id,\n                \"step_name\": step.name,\n                **saga.data\n            }\n        )\n\n    async def _compensate(self, saga: Saga):\n        \"\"\"Execute compensation for completed steps.\"\"\"\n        # Compensate in reverse order\n        for i in range(saga.current_step - 1, -1, -1):\n            step = saga.steps[i]\n            if step.status == \"completed\":\n                step.status = \"compensating\"\n                await self.saga_store.save(saga)\n\n                await self.event_publisher.publish(\n                    step.compensation,\n                    {\n                        \"saga_id\": saga.saga_id,\n                        \"step_name\": step.name,\n                        \"original_result\": step.result,\n                        **saga.data\n                    }\n                )\n\n    async def handle_compensation_completed(self, saga_id: str, step_name: str):\n        \"\"\"Handle compensation completion.\"\"\"\n        saga = await self.saga_store.get(saga_id)\n\n        for step in saga.steps:\n            if step.name == step_name:\n                step.status = \"compensated\"\n                step.compensated_at = datetime.utcnow()\n                break\n\n        # Check if all compensations complete\n        all_compensated = all(\n            s.status in (\"compensated\", \"pending\", \"failed\")\n            for s in saga.steps\n        )\n\n        if all_compensated:\n            saga.state = SagaState.FAILED\n            await self._on_saga_failed(saga)\n\n        await self.saga_store.save(saga)\n\n    async def _on_saga_completed(self, saga: Saga):\n        \"\"\"Called when saga completes successfully.\"\"\"\n        await self.event_publisher.publish(\n            f\"{self.saga_type}Completed\",\n            {\"saga_id\": saga.saga_id, **saga.data}\n        )\n\n    async def _on_saga_failed(self, saga: Saga):\n        \"\"\"Called when saga fails after compensation.\"\"\"\n        await self.event_publisher.publish(\n            f\"{self.saga_type}Failed\",\n            {\"saga_id\": saga.saga_id, \"error\": \"Saga failed\", **saga.data}\n        )\n```\n\n### Template 2: Order Fulfillment Saga\n\n```python\nclass OrderFulfillmentSaga(SagaOrchestrator):\n    \"\"\"Orchestrates order fulfillment across services.\"\"\"\n\n    @property\n    def saga_type(self) -> str:\n        return \"OrderFulfillment\"\n\n    def define_steps(self, data: Dict) -> List[SagaStep]:\n        return [\n            SagaStep(\n                name=\"reserve_inventory\",\n                action=\"InventoryService.ReserveItems\",\n                compensation=\"InventoryService.ReleaseReservation\"\n            ),\n            SagaStep(\n                name=\"process_payment\",\n                action=\"PaymentService.ProcessPayment\",\n                compensation=\"PaymentService.RefundPayment\"\n            ),\n            SagaStep(\n                name=\"create_shipment\",\n                action=\"ShippingService.CreateShipment\",\n                compensation=\"ShippingService.CancelShipment\"\n            ),\n            SagaStep(\n                name=\"send_confirmation\",\n                action=\"NotificationService.SendOrderConfirmation\",\n                compensation=\"NotificationService.SendCancellationNotice\"\n            )\n        ]\n\n\n# Usage\nasync def create_order(order_data: Dict):\n    saga = OrderFulfillmentSaga(saga_store, event_publisher)\n    return await saga.start({\n        \"order_id\": order_data[\"order_id\"],\n        \"customer_id\": order_data[\"customer_id\"],\n        \"items\": order_data[\"items\"],\n        \"payment_method\": order_data[\"payment_method\"],\n        \"shipping_address\": order_data[\"shipping_address\"]\n    })\n\n\n# Event handlers in each service\nclass InventoryService:\n    async def handle_reserve_items(self, command: Dict):\n        try:\n            # Reserve inventory\n            reservation = await self.reserve(\n                command[\"items\"],\n                command[\"order_id\"]\n            )\n            # Report success\n            await self.event_publisher.publish(\n                \"SagaStepCompleted\",\n                {\n                    \"saga_id\": command[\"saga_id\"],\n                    \"step_name\": \"reserve_inventory\",\n                    \"result\": {\"reservation_id\": reservation.id}\n                }\n            )\n        except InsufficientInventoryError as e:\n            await self.event_publisher.publish(\n                \"SagaStepFailed\",\n                {\n                    \"saga_id\": command[\"saga_id\"],\n                    \"step_name\": \"reserve_inventory\",\n                    \"error\": str(e)\n                }\n            )\n\n    async def handle_release_reservation(self, command: Dict):\n        # Compensating action\n        await self.release_reservation(\n            command[\"original_result\"][\"reservation_id\"]\n        )\n        await self.event_publisher.publish(\n            \"SagaCompensationCompleted\",\n            {\n                \"saga_id\": command[\"saga_id\"],\n                \"step_name\": \"reserve_inventory\"\n            }\n        )\n```\n\n### Template 3: Choreography-Based Saga\n\n```python\nfrom dataclasses import dataclass\nfrom typing import Dict, Any\nimport asyncio\n\n@dataclass\nclass SagaContext:\n    \"\"\"Passed through choreographed saga events.\"\"\"\n    saga_id: str\n    step: int\n    data: Dict[str, Any]\n    completed_steps: list\n\n\nclass OrderChoreographySaga:\n    \"\"\"Choreography-based saga using events.\"\"\"\n\n    def __init__(self, event_bus):\n        self.event_bus = event_bus\n        self._register_handlers()\n\n    def _register_handlers(self):\n        self.event_bus.subscribe(\"OrderCreated\", self._on_order_created)\n        self.event_bus.subscribe(\"InventoryReserved\", self._on_inventory_reserved)\n        self.event_bus.subscribe(\"PaymentProcessed\", self._on_payment_processed)\n        self.event_bus.subscribe(\"ShipmentCreated\", self._on_shipment_created)\n\n        # Compensation handlers\n        self.event_bus.subscribe(\"PaymentFailed\", self._on_payment_failed)\n        self.event_bus.subscribe(\"ShipmentFailed\", self._on_shipment_failed)\n\n    async def _on_order_created(self, event: Dict):\n        \"\"\"Step 1: Order created, reserve inventory.\"\"\"\n        await self.event_bus.publish(\"ReserveInventory\", {\n            \"saga_id\": event[\"order_id\"],\n            \"order_id\": event[\"order_id\"],\n            \"items\": event[\"items\"]\n        })\n\n    async def _on_inventory_reserved(self, event: Dict):\n        \"\"\"Step 2: Inventory reserved, process payment.\"\"\"\n        await self.event_bus.publish(\"ProcessPayment\", {\n            \"saga_id\": event[\"saga_id\"],\n            \"order_id\": event[\"order_id\"],\n            \"amount\": event[\"total_amount\"],\n            \"reservation_id\": event[\"reservation_id\"]\n        })\n\n    async def _on_payment_processed(self, event: Dict):\n        \"\"\"Step 3: Payment done, create shipment.\"\"\"\n        await self.event_bus.publish(\"CreateShipment\", {\n            \"saga_id\": event[\"saga_id\"],\n            \"order_id\": event[\"order_id\"],\n            \"payment_id\": event[\"payment_id\"]\n        })\n\n    async def _on_shipment_created(self, event: Dict):\n        \"\"\"Step 4: Complete - send confirmation.\"\"\"\n        await self.event_bus.publish(\"OrderFulfilled\", {\n            \"saga_id\": event[\"saga_id\"],\n            \"order_id\": event[\"order_id\"],\n            \"tracking_number\": event[\"tracking_number\"]\n        })\n\n    # Compensation handlers\n    async def _on_payment_failed(self, event: Dict):\n        \"\"\"Payment failed - release inventory.\"\"\"\n        await self.event_bus.publish(\"ReleaseInventory\", {\n            \"saga_id\": event[\"saga_id\"],\n            \"reservation_id\": event[\"reservation_id\"]\n        })\n        await self.event_bus.publish(\"OrderFailed\", {\n            \"order_id\": event[\"order_id\"],\n            \"reason\": \"Payment failed\"\n        })\n\n    async def _on_shipment_failed(self, event: Dict):\n        \"\"\"Shipment failed - refund payment and release inventory.\"\"\"\n        await self.event_bus.publish(\"RefundPayment\", {\n            \"saga_id\": event[\"saga_id\"],\n            \"payment_id\": event[\"payment_id\"]\n        })\n        await self.event_bus.publish(\"ReleaseInventory\", {\n            \"saga_id\": event[\"saga_id\"],\n            \"reservation_id\": event[\"reservation_id\"]\n        })\n```\n\n### Template 4: Saga with Timeouts\n\n```python\nclass TimeoutSagaOrchestrator(SagaOrchestrator):\n    \"\"\"Saga orchestrator with step timeouts.\"\"\"\n\n    def __init__(self, saga_store, event_publisher, scheduler):\n        super().__init__(saga_store, event_publisher)\n        self.scheduler = scheduler\n\n    async def _execute_next_step(self, saga: Saga):\n        if saga.current_step >= len(saga.steps):\n            return\n\n        step = saga.steps[saga.current_step]\n        step.status = \"executing\"\n        step.timeout_at = datetime.utcnow() + timedelta(minutes=5)\n        await self.saga_store.save(saga)\n\n        # Schedule timeout check\n        await self.scheduler.schedule(\n            f\"saga_timeout_{saga.saga_id}_{step.name}\",\n            self._check_timeout,\n            {\"saga_id\": saga.saga_id, \"step_name\": step.name},\n            run_at=step.timeout_at\n        )\n\n        await self.event_publisher.publish(\n            step.action,\n            {\"saga_id\": saga.saga_id, \"step_name\": step.name, **saga.data}\n        )\n\n    async def _check_timeout(self, data: Dict):\n        \"\"\"Check if step has timed out.\"\"\"\n        saga = await self.saga_store.get(data[\"saga_id\"])\n        step = next(s for s in saga.steps if s.name == data[\"step_name\"])\n\n        if step.status == \"executing\":\n            # Step timed out - fail it\n            await self.handle_step_failed(\n                data[\"saga_id\"],\n                data[\"step_name\"],\n                \"Step timed out\"\n            )\n```\n\n## Durable Execution Alternative\n\nThe templates above build saga infrastructure from scratch — saga stores, event publishers, compensation tracking. **Durable execution frameworks** (like DBOS) eliminate much of this boilerplate: the workflow runtime automatically persists state to a database, retries failed steps, and resumes from the last checkpoint after crashes. Instead of building a `SagaOrchestrator` base class, you write a workflow function with steps — the framework handles persistence, crash recovery, and exactly-once execution semantics. Consider durable execution when you want saga-like reliability without managing the coordination infrastructure yourself.\n\n## Best Practices\n\n### Do's\n\n- **Make steps idempotent** - Safe to retry\n- **Design compensations carefully** - They must work\n- **Use correlation IDs** - For tracing across services\n- **Implement timeouts** - Don't wait forever\n- **Log everything** - For debugging failures\n\n### Don'ts\n\n- **Don't assume instant completion** - Sagas take time\n- **Don't skip compensation testing** - Most critical part\n- **Don't couple services** - Use async messaging\n- **Don't ignore partial failures** - Handle gracefully\n\n## Related Skills\n\nWorks well with: `event-sourcing-architect`, `workflow-automation`, `dbos-*`\n\n## Resources\n\n- [Saga Pattern](https://microservices.io/patterns/data/saga.html)\n- [Designing Data-Intensive Applications](https://dataintensive.net/)\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["saga","orchestration","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows"],"capabilities":["skill","source-sickn33","skill-saga-orchestration","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/saga-orchestration","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34583 github stars · SKILL.md body (16,841 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T18:52:09.669Z","embedding":null,"createdAt":"2026-04-18T21:43:46.101Z","updatedAt":"2026-04-22T18:52:09.669Z","lastSeenAt":"2026-04-22T18:52:09.669Z","tsv":"'-1':555,556 '/)':1511 '/patterns/data/saga.html)':1503 '0':254 '1':109,158,398,554,986 '2':127,697,1016 '3':898,1052 '4':1084,1186 '5':1240 'abc':164,166,271 'abstractmethod':167,292,307 'across':708,1440 'action':66,208,731,739,747,755,876 'address':799,803 'altern':1332 'amount':1034,1037 'appli':58 'applic':1508 'approv':105 'architect':1493 'ask':1545 'assum':1457 'async':318,355,429,487,533,582,644,668,760,811,867,977,1007,1043,1075,1108,1144,1215,1278,1476 'asyncio':914 'autom':1496 'automat':1360 'await':347,350,374,414,417,423,426,449,475,484,514,522,565,568,598,638,641,657,682,774,823,832,852,877,885,991,1021,1057,1088,1120,1133,1159,1172,1241,1247,1267,1292,1317 'b':117 'back':143 'backward':483 'base':161,272,901,939,1382 'best':60,1419 'boilerpl':1356 'boundari':1553 'break':395,469,615 'build':100,1336,1379 'bus':947,949,951 'busi':13,26,93 'c':119 'call':652,676 'care':1431 'check':402,616,1246,1280,1285 'checkpoint':1374 'choreograph':920 'choreographi':112,900,938 'choreography-bas':899,937 'clarif':1547 'clarifi':52 'class':190,204,234,269,273,702,809,916,935,1191,1383 'clear':1520 'command':518,817,825,827,837,857,873,880,890 'compens':87,141,155,197,198,210,228,447,479,535,540,544,564,585,595,611,619,622,626,635,681,733,741,749,757,875,969,1106,1345,1430,1466 'complet':140,147,199,200,359,372,389,406,542,562,586,596,620,648,655,662,932,1085,1459 'concept':108 'confirm':754,1087 'consid':1403 'constraint':54 'coordin':81,1416 'core':107 'correl':1436 'coupl':1473 'crash':1376,1395 'creat':255,745,762,981,988,1055,1079 'createship':1059 'criteria':1556 'critic':1469 'current':251,481 'custom':782,786 'data':244,297,322,341,342,346,722,765,779,785,790,795,801,928,1283,1294,1306,1321,1324,1506 'data-intens':1505 'databas':1365 'dataclass':169,171,203,233,905,907,915 'dataintensive.net':1510 'dataintensive.net/)':1509 'datetim':185,187,226,231,257,264 'datetime.utcnow':261,268,394,401,474,614,1237 'dbos':1351,1497 'debug':1451 'def':277,293,308,319,356,430,488,534,583,645,669,711,718,761,812,868,943,953,978,1008,1044,1076,1109,1145,1199,1216,1279 'default':259,266 'defin':294,301,719 'describ':1524 'descript':132 'design':1429,1504 'detail':71 'dict':181,217,245,298,323,368,723,766,818,874,911,929,984,1014,1050,1082,1115,1151,1284 'differ':44 'distribut':7,20,98 'domain':45 'done':1054 'due':144 'durabl':1330,1347,1404 'e':851,866 'elimin':1352 'els':420 'enum':174,176,192 'environ':1536 'environment-specif':1535 'error':219,441,468,692,864 'event':121,122,123,282,290,771,804,922,942,946,950,983,996,1001,1005,1013,1026,1031,1035,1040,1049,1062,1067,1072,1081,1093,1098,1103,1114,1125,1130,1138,1150,1164,1169,1177,1182,1204,1211,1343,1491 'event-sourcing-architect':1490 'everyth':1449 'exact':1399 'exactly-onc':1398 'exampl':72 'except':848 'execut':129,223,489,495,513,520,539,1217,1234,1311,1331,1348,1401,1405 'expert':1541 'f':659,684,1249 'factori':260,267 'fail':151,153,201,202,433,456,466,628,672,679,687,694,1112,1117,1143,1148,1153,1315,1320,1367 'failur':96,146,445,1452,1482 'field':172,258,265 'forev':1447 'framework':1349,1392 'fulfil':102,699,707 'function':1388 'goal':53 'grace':1484 'handl':95,357,369,431,443,584,594,813,869,1393,1483 'handler':805,955,970,1107 'id':237,332,362,377,436,452,526,528,572,574,589,601,664,666,689,691,777,781,783,787,829,836,839,846,856,859,884,889,892,924,995,998,1000,1003,1025,1028,1030,1033,1039,1042,1061,1064,1066,1069,1071,1074,1092,1095,1097,1100,1124,1127,1129,1132,1137,1140,1163,1166,1168,1171,1176,1179,1181,1184,1253,1257,1259,1271,1273,1296,1323,1437 'idempot':1425 'identifi':316 'ignor':1480 'implement':86,104,1442 'import':165,170,175,179,186,188,906,910,913 'infrastructur':1338,1417 'init':278,944,1200,1208 'initi':135 'input':57,1550 'instant':1458 'instead':1377 'instruct':51 'insufficientinventoryerror':849 'int':253,927 'intens':1507 'inventori':730,821,843,863,896,990,1010,1017,1119,1158 'inventoryreserv':961 'inventoryservic':810 'inventoryservice.releasereservation':734 'inventoryservice.reserveitems':732 'item':788,791,815,826,1004,1006 'last':1373 'len':410,505,1226 'like':1350,1411 'limit':1512 'list':180,249,299,724,934 'log':1448 'long':11,24,91 'long-run':10,23,90 'make':1423 'manag':6,19,89,1414 'mark':453 'match':1521 'messag':1477 'method':793,797 'microservices.io':1502 'microservices.io/patterns/data/saga.html)':1501 'minut':1239 'miss':1558 'much':1353 'multi':83 'multi-servic':82 'must':1433 'name':206,365,387,439,464,530,576,592,609,728,736,744,752,841,861,894,1261,1275,1308,1326 'need':42 'new':327 'next':490,497,1218,1298 'none':218,222,227,232 'notificationservice.sendcancellationnotice':758 'notificationservice.sendorderconfirmation':756 'number':1102,1105 'open':75 'option':183,216,220,225,230 'orchestr':3,16,40,113,120,160,276,705,1195 'order':101,547,698,706,763,764,776,778,780,784,789,794,800,828,980,987,997,999,1002,1029,1032,1065,1068,1096,1099,1136,1139 'orderchoreographysaga':936 'ordercr':958 'orderfail':1135 'orderfulfil':717,1090 'orderfulfillmentsaga':703,768 'origin':578,881 'outcom':64 'output':1530 'outsid':48 'part':1470 'partial':1481 'pass':305,317,918 'pattern':4,17,1500 'payment':738,792,796,1020,1046,1053,1070,1073,1111,1116,1142,1155,1167,1170 'paymentfail':972 'paymentprocess':964 'paymentservice.processpayment':740 'paymentservice.refundpayment':742 'pend':136,195,196,214,627 'permiss':1551 'persist':1361,1394 'practic':61,1420 'process':14,27,103,737,1019,1047 'processpay':1023 'properti':306,710 'provid':65 'publish':283,289,291,517,772,1205,1212,1344 'python':162,701,903,1190 'rang':551 'reason':1141 'recoveri':1396 'refund':1154 'refundpay':1161 'regist':954 'relat':1485 'releas':870,1118,1157 'releaseinventori':1122,1174 'relev':59 'reliabl':1412 'report':830 'requir':56,74,1549 'reserv':729,814,820,822,842,845,862,871,879,883,895,989,1011,1018,1038,1041,1128,1131,1180,1183 'reservation.id':847 'reserveinventori':993 'resourc':1498 'resources/implementation-playbook.md':76 'result':215,367,391,579,844,882 'resum':1370 'retri':1366,1428 'return':353,507,716,726,773,1228 'revers':546 'review':1542 'roll':142 'run':12,25,92,1263 'runtim':1359 's.name':1305 's.status':624 'safe':1426 'safeti':1552 'saga':2,15,39,110,128,134,152,159,235,236,239,275,280,286,303,309,314,324,328,329,330,331,335,349,352,354,361,373,376,404,416,419,425,428,435,448,451,477,486,493,494,501,516,525,537,538,567,571,588,597,600,640,643,647,650,651,654,663,671,674,675,678,688,693,700,712,767,769,835,838,855,858,888,891,902,921,923,940,994,1024,1027,1060,1063,1091,1094,1123,1126,1162,1165,1175,1178,1187,1194,1202,1209,1221,1222,1243,1250,1256,1270,1291,1295,1322,1337,1341,1410,1460,1499 'saga-lik':1409 'saga-orchestr':1 'saga.current':396,408,503,510,552,1224,1231 'saga.data':532,581,667,695,1277 'saga.saga':527,573,665,690,1252,1258,1272 'saga.start':775 'saga.state':412,421,470,636 'saga.steps':383,411,460,506,509,558,605,632,1227,1230,1303 'saga.updated':399,472 'sagacompensationcomplet':887 'sagacontext':917 'sagaorchestr':270,704,1193,1381 'sagast':191,243 'sagastate.compensating':471 'sagastate.completed':413 'sagastate.failed':637 'sagastate.pending':422 'sagastate.started':340 'sagastep':205,250,300,725,727,735,743,751 'sagastepcomplet':834 'sagastepfail':854 'schedul':1206,1214,1244 'scope':50,1523 'scratch':1340 'self':279,296,311,321,360,434,492,536,587,649,673,714,721,816,872,945,956,982,1012,1048,1080,1113,1149,1201,1220,1282 'self._check_timeout':1255 'self._compensate':485 'self._execute_next_step':351,427 'self._on_inventory_reserved':962 'self._on_order_created':959 'self._on_payment_failed':973 'self._on_payment_processed':965 'self._on_saga_completed':418 'self._on_saga_failed':639 'self._on_shipment_created':968 'self._on_shipment_failed':976 'self._register_handlers':952 'self.define':344 'self.event':288,948 'self.event_bus.publish':992,1022,1058,1089,1121,1134,1160,1173 'self.event_bus.subscribe':957,960,963,966,971,974 'self.event_publisher.publish':523,569,658,683,833,853,886,1268 'self.handle':1318 'self.release':878 'self.reserve':824 'self.saga':284,337,660,685 'self.saga_store.get':375,450,599,1293 'self.saga_store.save':348,415,424,476,515,566,642,1242 'self.scheduler':1213 'self.scheduler.schedule':1248 'semant':1402 'send':753,1086 'servic':84,709,808,1441,1474 'ship':798,802 'shipment':746,1056,1078,1147,1152 'shipmentcr':967 'shipmentfail':975 'shippingservice.cancelshipment':750 'shippingservice.createshipment':748 'skill':32,79,1486,1515 'skill-saga-orchestration' 'skip':1465 'sourc':1492 'source-sickn33' 'specif':1537 'start':133,193,194,320,325,446,478 'state':130,131,242,339,1362 'status':212 'step':67,139,149,248,252,295,304,343,345,358,364,371,379,381,386,397,409,432,438,444,454,458,463,482,491,498,504,508,511,521,529,543,553,557,575,591,603,608,720,840,860,893,926,933,985,1015,1051,1083,1197,1219,1225,1229,1232,1260,1274,1287,1297,1307,1312,1319,1325,1327,1368,1390,1424 'step.action':524,1269 'step.compensated':612 'step.compensation':570 'step.error':467 'step.executed':392 'step.name':385,462,531,577,607,1254,1262,1276 'step.result':390,580 'step.status':388,465,512,561,563,610,1233,1310 'step.timeout':1235,1265 'stop':1543 'store':281,285,287,770,1203,1210,1342 'str':207,209,211,213,221,238,241,246,312,333,363,366,437,440,442,590,593,715,865,925,930 'substitut':1533 'succeed':150 'success':370,656,831,1555 'super':1207 'svc':114,116,118 'svc1':124 'svc2':125 'svc3':126 'system':99 'take':1461 'task':35,1519 'templat':156,157,696,897,1185,1334 'test':1467,1539 'time':1289,1313,1328,1462 'timedelta':1238 'timeout':1189,1198,1245,1251,1281,1443 'timeoutsagaorchestr':1192 'tool':47 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'total':1036 'trace':1439 'track':1101,1104,1346 'transact':8,21,85,88 'treat':1528 'tri':819 'ts':1454 'type':111,178,240,310,315,336,338,661,686,713,909 'uniqu':313 'unrel':37 'updat':262,378 'usag':759 'use':30,77,941,1435,1475,1513 'uuid':189 'uuid.uuid4':334 'valid':63,1538 'verif':69 'wait':137,1446 'want':1408 'well':1488 'without':1413 'work':1434,1487 'workflow':94,106,1358,1387,1495 'workflow-autom':1494 'write':1385","prices":[{"id":"79920af9-9ccd-46dd-bb8f-5f4a7ca7ec44","listingId":"94ca5dde-45f8-4ade-9ba9-5c9aa8f36c39","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:43:46.101Z"}],"sources":[{"listingId":"94ca5dde-45f8-4ade-9ba9-5c9aa8f36c39","source":"github","sourceId":"sickn33/antigravity-awesome-skills/saga-orchestration","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/saga-orchestration","isPrimary":false,"firstSeenAt":"2026-04-18T21:43:46.101Z","lastSeenAt":"2026-04-22T18:52:09.669Z"}],"details":{"listingId":"94ca5dde-45f8-4ade-9ba9-5c9aa8f36c39","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"saga-orchestration","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34583,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-22T06:40:00Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"d111da9d5b45756bdc4a09c09c1f2c03be092562","skill_md_path":"skills/saga-orchestration/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/saga-orchestration"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"saga-orchestration","description":"Patterns for managing distributed transactions and long-running business processes."},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/saga-orchestration"},"updatedAt":"2026-04-22T18:52:09.669Z"}}