application · active

Blog

Governed editorial workspace for drafts, immutable revisions, publication scheduling, media, SEO metadata, and public headless article delivery.

Documentation map

  • Blog — Write, schedule, publish, and distribute governed articles.

Authority and runtime

System ID
topolo-blog
App IDs
app_topolo_blog
Owners
platform-engineering
Repositories
apps/TopoloBlog
Hosts
https://blog.topolo.app, https://blog.stg.topolo.us, https://blog.topolo.dev
Dependencies
topolo-auth, topolo-nexus, topolo-platform

Security and data ownership

Risk tier
internal
Tenant isolation
organization_scoped
Privacy classification
confidential
Storage
d1, r2, queue, workflow
Export and deletion
implemented
Enterprise ready
no

Source-derived capability inventory

Source revisions: apps/TopoloBlog@ea26b09a5159a13506f1bc6b020273fb1a9396a1

Declared actions: 42 · API routes: 5 · UI routes: 12

{
  "id": "topolo-blog",
  "name": "Blog",
  "slug": "topolo-blog",
  "kind": "application",
  "visibility": "public",
  "repo_paths": [
    "apps/TopoloBlog"
  ],
  "source_revisions": [
    {
      "source_path": "apps/TopoloBlog",
      "repository": "apps/TopoloBlog",
      "revision": "ea26b09a5159a13506f1bc6b020273fb1a9396a1",
      "ref": "origin/staging"
    }
  ],
  "source_counts": {
    "source_files": 68,
    "test_files": 31,
    "test_cases": 0,
    "migration_files": 4,
    "database_tables": 0,
    "manifests": 1,
    "deploy_targets": 2,
    "actions": 42,
    "mobile_contracts": 0,
    "notifications": 1,
    "package_manifests": 1,
    "deployment_configs": 0
  },
  "manifests": [
    {
      "source_path": "apps/TopoloBlog/topolo.app.json",
      "service_slug": "topolo-blog",
      "name": "topolo-blog",
      "app_id": "app_topolo_blog",
      "compatibility_date": "2026-05-05",
      "primary_target": null,
      "environments": [
        "development",
        "production",
        "staging"
      ],
      "targets": [
        {
          "name": "api",
          "kind": "worker",
          "directory": "apps/api",
          "main": "src/worker.ts",
          "worker_name": "topolo-blog-api",
          "subdomain": null,
          "healthcheck_path": "/api/health",
          "variable_names": [
            "AUTH_BASE_URL",
            "INSIGHTS_API_URL",
            "INSIGHTS_WORKSPACE_ID",
            "NEXUS_GATEWAY_URL",
            "TOPOLO_NOTIFY_URL",
            "TOPOLO_ONE_REVALIDATE_URL"
          ],
          "secret_names": [],
          "bindings": [
            {
              "kind": "d1",
              "binding": "BLOG_CORE_DB",
              "target": null
            },
            {
              "kind": "r2",
              "binding": "APP_ASSETS",
              "target": null
            },
            {
              "kind": "workflows",
              "binding": "APP_WORKFLOW",
              "target": null
            }
          ]
        },
        {
          "name": "web",
          "kind": "worker",
          "directory": "apps/web",
          "main": "src/worker.ts",
          "worker_name": "topolo-blog",
          "subdomain": "blog",
          "healthcheck_path": "/api/health",
          "variable_names": [
            "INSIGHTS_SITE_KEY"
          ],
          "secret_names": [],
          "bindings": [
            {
              "kind": "services",
              "binding": "API",
              "target": null
            }
          ]
        }
      ],
      "notifications": [
        "blog.article.published"
      ],
      "notification_contract": {
        "source_path": "topolo.notification-contracts.json",
        "role": "producer",
        "schema_version": 1,
        "owner_app_id": "app_topolo_blog",
        "events": [
          {
            "type": "blog.article.published",
            "version": 1,
            "description": "A persisted article revision became publicly readable from a TopoloBlog publication.",
            "status": "published",
            "payloadSchema": {
              "type": "object",
              "required": [
                "title",
                "body",
                "object_id",
                "occurred_at",
                "article_id",
                "publication_key",
                "canonical_url",
                "revision_number"
              ],
              "properties": {
                "title": {
                  "type": "string",
                  "minLength": 1
                },
                "body": {
                  "type": "string",
                  "minLength": 1
                },
                "surface": {
                  "enum": [
                    "notification",
                    "action"
                  ]
                },
                "priority": {
                  "enum": [
                    "low",
                    "normal",
                    "high",
                    "urgent"
                  ]
                },
                "severity": {
                  "enum": [
                    "info",
                    "success",
                    "warning",
                    "critical"
                  ]
                },
                "category": {
                  "type": "string"
                },
                "object_type": {
                  "type": "string"
                },
                "object_id": {
                  "type": "string",
                  "minLength": 1
                },
                "cta_url": {
                  "type": "string",
                  "format": "uri"
                },
                "cta_label": {
                  "type": "string"
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "article_id": {
                  "type": "string",
                  "minLength": 1
                },
                "publication_key": {
                  "type": "string",
                  "minLength": 1
                },
                "canonical_url": {
                  "type": "string",
                  "format": "uri"
                },
                "revision_number": {
                  "type": "integer",
                  "minimum": 1
                }
              },
              "additionalProperties": false
            },
            "examples": [
              {
                "title": "Published: Agent-native business software",
                "body": "The article is now publicly available.",
                "surface": "notification",
                "priority": "normal",
                "severity": "success",
                "category": "blog",
                "object_type": "blog_article",
                "object_id": "article_agent_native_business_software",
                "cta_url": "https://topolo.io/blog/agent-native-business-software",
                "cta_label": "View article",
                "occurred_at": "2026-08-09T00:00:00.000Z",
                "article_id": "article_agent_native_business_software",
                "publication_key": "topolo",
                "canonical_url": "https://topolo.io/blog/agent-native-business-software",
                "revision_number": 3
              }
            ],
            "dataClassification": "public",
            "recipients": {
              "modes": [
                "workspace_member"
              ],
              "externalAddress": "forbidden"
            },
            "idempotency": {
              "required": true,
              "pattern": "^blog:article:published:"
            },
            "sensitiveFields": []
          }
        ]
      },
      "actions": [
        {
          "name": "widget.get",
          "title": "Get widget summary",
          "description": "Get the TopoloBlog widget summary.",
          "method": "GET",
          "path": "/api/widget",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "success": {
                "type": "boolean"
              },
              "widgets": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string"
                    },
                    "snapshot": {
                      "type": "object",
                      "properties": {
                        "summary": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "summary"
                      ],
                      "additionalProperties": {}
                    },
                    "actions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          },
                          "link": {
                            "type": "string"
                          },
                          "primary": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "label",
                          "link"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "appId": {
                      "type": "string"
                    },
                    "serviceName": {
                      "type": "string"
                    },
                    "lastUpdated": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "type",
                    "snapshot",
                    "actions",
                    "appId",
                    "serviceName",
                    "lastUpdated"
                  ],
                  "additionalProperties": {}
                }
              }
            },
            "required": [
              "success",
              "widgets"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=widget.get",
            "resource": {
              "kind": "widget",
              "idPath": "$.id"
            },
            "effects": [
              "Reads widget data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {},
                "expected": "A response matching the published outputSchema for widget.get."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {},
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/widget",
              "body": null
            },
            "effects": "Reads widget data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=widget.get",
            "resource": {
              "kind": "widget",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/widget",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "workspace.bootstrap",
          "title": "Get workspace bootstrap",
          "description": "Get the signed TopoloBlog workspace bootstrap payload.",
          "method": "GET",
          "path": "/api/bootstrap",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "user": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  }
                },
                "required": [
                  "id"
                ],
                "additionalProperties": {}
              },
              "organization": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "slug": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "id",
                      "name",
                      "slug"
                    ],
                    "additionalProperties": {}
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "user",
              "organization"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=workspace.bootstrap",
            "resource": {
              "kind": "workspace",
              "idPath": "$.id"
            },
            "effects": [
              "Reads workspace data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {},
                "expected": "A response matching the published outputSchema for workspace.bootstrap."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {},
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/bootstrap",
              "body": null
            },
            "effects": "Reads workspace data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=workspace.bootstrap",
            "resource": {
              "kind": "workspace",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/bootstrap",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "overview.get",
          "title": "Get publishing overview",
          "description": "Get publishing counts, upcoming releases, and recent editorial work.",
          "method": "GET",
          "path": "/api/overview",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "overview": {
                "type": "object",
                "properties": {
                  "counts": {
                    "type": "object",
                    "properties": {
                      "draft": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "scheduled": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "published": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "media": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "publications": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "draft",
                      "scheduled",
                      "published",
                      "media",
                      "publications"
                    ],
                    "additionalProperties": false
                  },
                  "upcoming": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "organizationId": {
                          "type": "string"
                        },
                        "workspaceId": {
                          "type": "string"
                        },
                        "publicationKey": {
                          "type": "string"
                        },
                        "publicationId": {
                          "type": "string"
                        },
                        "publicationName": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "slug": {
                          "type": "string"
                        },
                        "excerpt": {
                          "type": "string"
                        },
                        "body": {
                          "type": "array",
                          "items": {
                            "oneOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "paragraph"
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  }
                                },
                                "required": [
                                  "type",
                                  "text"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "heading"
                                  },
                                  "level": {
                                    "anyOf": [
                                      {
                                        "type": "number",
                                        "const": 2
                                      },
                                      {
                                        "type": "number",
                                        "const": 3
                                      }
                                    ],
                                    "description": "Section level. The article title renders as the H1, so body headings start at 2."
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  }
                                },
                                "required": [
                                  "type",
                                  "level",
                                  "text"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "list"
                                  },
                                  "style": {
                                    "type": "string",
                                    "enum": [
                                      "ordered",
                                      "unordered"
                                    ]
                                  },
                                  "items": {
                                    "minItems": 1,
                                    "type": "array",
                                    "items": {
                                      "type": "string",
                                      "minLength": 1,
                                      "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                    }
                                  }
                                },
                                "required": [
                                  "type",
                                  "style",
                                  "items"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "image"
                                  },
                                  "assetId": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                                  },
                                  "url": {
                                    "type": "string",
                                    "format": "uri"
                                  },
                                  "altText": {
                                    "type": "string",
                                    "maxLength": 320
                                  },
                                  "caption": {
                                    "type": "string",
                                    "maxLength": 320,
                                    "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                                  }
                                },
                                "required": [
                                  "type",
                                  "assetId",
                                  "url",
                                  "altText",
                                  "caption"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "quote"
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  },
                                  "attribution": {
                                    "type": "string",
                                    "maxLength": 160
                                  }
                                },
                                "required": [
                                  "type",
                                  "text",
                                  "attribution"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "divider"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "code"
                                  },
                                  "language": {
                                    "type": "string",
                                    "maxLength": 48
                                  },
                                  "code": {
                                    "type": "string",
                                    "minLength": 1
                                  }
                                },
                                "required": [
                                  "type",
                                  "language",
                                  "code"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "callout"
                                  },
                                  "tone": {
                                    "type": "string",
                                    "enum": [
                                      "info",
                                      "success",
                                      "warning"
                                    ]
                                  },
                                  "title": {
                                    "type": "string",
                                    "maxLength": 120
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  }
                                },
                                "required": [
                                  "type",
                                  "tone",
                                  "title",
                                  "text"
                                ],
                                "additionalProperties": false
                              }
                            ],
                            "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                          }
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "seriesName": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "seriesPosition": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "seoTitle": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "seoDescription": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "ogImageUrl": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "canonicalUrl": {
                          "type": "string"
                        },
                        "authorName": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "scheduled",
                            "published"
                          ]
                        },
                        "reviewStatus": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "in_review",
                            "changes_requested",
                            "approved"
                          ]
                        },
                        "reviewRequestedAt": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "approvedRevisionNumber": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "approvedByUserId": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "approvedAt": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "scheduledFor": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "scheduledRevisionNumber": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "publishedAt": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "publishedRevisionNumber": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "hasUnpublishedChanges": {
                          "type": "boolean"
                        },
                        "revisionNumber": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "createdByUserId": {
                          "type": "string"
                        },
                        "createdAt": {
                          "type": "string"
                        },
                        "updatedAt": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "organizationId",
                        "workspaceId",
                        "publicationKey",
                        "publicationId",
                        "publicationName",
                        "title",
                        "slug",
                        "excerpt",
                        "body",
                        "tags",
                        "seriesName",
                        "seriesPosition",
                        "seoTitle",
                        "seoDescription",
                        "ogImageUrl",
                        "canonicalUrl",
                        "authorName",
                        "status",
                        "reviewStatus",
                        "reviewRequestedAt",
                        "approvedRevisionNumber",
                        "approvedByUserId",
                        "approvedAt",
                        "scheduledFor",
                        "scheduledRevisionNumber",
                        "publishedAt",
                        "publishedRevisionNumber",
                        "hasUnpublishedChanges",
                        "revisionNumber",
                        "createdByUserId",
                        "createdAt",
                        "updatedAt"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "recent": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "organizationId": {
                          "type": "string"
                        },
                        "workspaceId": {
                          "type": "string"
                        },
                        "publicationKey": {
                          "type": "string"
                        },
                        "publicationId": {
                          "type": "string"
                        },
                        "publicationName": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "slug": {
                          "type": "string"
                        },
                        "excerpt": {
                          "type": "string"
                        },
                        "body": {
                          "type": "array",
                          "items": {
                            "oneOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "paragraph"
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  }
                                },
                                "required": [
                                  "type",
                                  "text"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "heading"
                                  },
                                  "level": {
                                    "anyOf": [
                                      {
                                        "type": "number",
                                        "const": 2
                                      },
                                      {
                                        "type": "number",
                                        "const": 3
                                      }
                                    ],
                                    "description": "Section level. The article title renders as the H1, so body headings start at 2."
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  }
                                },
                                "required": [
                                  "type",
                                  "level",
                                  "text"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "list"
                                  },
                                  "style": {
                                    "type": "string",
                                    "enum": [
                                      "ordered",
                                      "unordered"
                                    ]
                                  },
                                  "items": {
                                    "minItems": 1,
                                    "type": "array",
                                    "items": {
                                      "type": "string",
                                      "minLength": 1,
                                      "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                    }
                                  }
                                },
                                "required": [
                                  "type",
                                  "style",
                                  "items"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "image"
                                  },
                                  "assetId": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                                  },
                                  "url": {
                                    "type": "string",
                                    "format": "uri"
                                  },
                                  "altText": {
                                    "type": "string",
                                    "maxLength": 320
                                  },
                                  "caption": {
                                    "type": "string",
                                    "maxLength": 320,
                                    "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                                  }
                                },
                                "required": [
                                  "type",
                                  "assetId",
                                  "url",
                                  "altText",
                                  "caption"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "quote"
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  },
                                  "attribution": {
                                    "type": "string",
                                    "maxLength": 160
                                  }
                                },
                                "required": [
                                  "type",
                                  "text",
                                  "attribution"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "divider"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "code"
                                  },
                                  "language": {
                                    "type": "string",
                                    "maxLength": 48
                                  },
                                  "code": {
                                    "type": "string",
                                    "minLength": 1
                                  }
                                },
                                "required": [
                                  "type",
                                  "language",
                                  "code"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "callout"
                                  },
                                  "tone": {
                                    "type": "string",
                                    "enum": [
                                      "info",
                                      "success",
                                      "warning"
                                    ]
                                  },
                                  "title": {
                                    "type": "string",
                                    "maxLength": 120
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  }
                                },
                                "required": [
                                  "type",
                                  "tone",
                                  "title",
                                  "text"
                                ],
                                "additionalProperties": false
                              }
                            ],
                            "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                          }
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "seriesName": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "seriesPosition": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "seoTitle": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "seoDescription": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "ogImageUrl": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "canonicalUrl": {
                          "type": "string"
                        },
                        "authorName": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "scheduled",
                            "published"
                          ]
                        },
                        "reviewStatus": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "in_review",
                            "changes_requested",
                            "approved"
                          ]
                        },
                        "reviewRequestedAt": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "approvedRevisionNumber": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "approvedByUserId": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "approvedAt": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "scheduledFor": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "scheduledRevisionNumber": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "publishedAt": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "publishedRevisionNumber": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "hasUnpublishedChanges": {
                          "type": "boolean"
                        },
                        "revisionNumber": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "createdByUserId": {
                          "type": "string"
                        },
                        "createdAt": {
                          "type": "string"
                        },
                        "updatedAt": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "organizationId",
                        "workspaceId",
                        "publicationKey",
                        "publicationId",
                        "publicationName",
                        "title",
                        "slug",
                        "excerpt",
                        "body",
                        "tags",
                        "seriesName",
                        "seriesPosition",
                        "seoTitle",
                        "seoDescription",
                        "ogImageUrl",
                        "canonicalUrl",
                        "authorName",
                        "status",
                        "reviewStatus",
                        "reviewRequestedAt",
                        "approvedRevisionNumber",
                        "approvedByUserId",
                        "approvedAt",
                        "scheduledFor",
                        "scheduledRevisionNumber",
                        "publishedAt",
                        "publishedRevisionNumber",
                        "hasUnpublishedChanges",
                        "revisionNumber",
                        "createdByUserId",
                        "createdAt",
                        "updatedAt"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "required": [
                  "counts",
                  "upcoming",
                  "recent"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "overview"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=overview.get",
            "resource": {
              "kind": "workspace",
              "idPath": "$.id"
            },
            "effects": [
              "Reads workspace data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {},
                "expected": "A response matching the published outputSchema for overview.get."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {},
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/overview",
              "body": null
            },
            "effects": "Reads workspace data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=overview.get",
            "resource": {
              "kind": "workspace",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/overview",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "analytics.overview",
          "title": "Get readership analytics",
          "description": "Get the shared Insights readership overview for this editorial workspace.",
          "method": "GET",
          "path": "/api/analytics",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "days": {
                "type": "integer",
                "minimum": 1,
                "maximum": 90
              }
            },
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {},
                "additionalProperties": {}
              }
            },
            "required": [
              "data"
            ],
            "additionalProperties": {}
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=analytics.overview",
            "resource": {
              "kind": "workspace",
              "idPath": "$.id"
            },
            "effects": [
              "Reads workspace data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {
                  "days": 30
                },
                "expected": "A response matching the published outputSchema for analytics.overview."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "days": 30
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/analytics",
              "body": null
            },
            "effects": "Reads workspace data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=analytics.overview",
            "resource": {
              "kind": "workspace",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/analytics",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.list",
          "title": "List articles",
          "description": "Search, filter, sort, and paginate articles in the selected editorial workspace.",
          "method": "GET",
          "path": "/api/articles",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "query": {
                "type": "string",
                "maxLength": 160
              },
              "status": {
                "type": "string",
                "enum": [
                  "all",
                  "draft",
                  "scheduled",
                  "published"
                ]
              },
              "reviewStatus": {
                "type": "string",
                "enum": [
                  "all",
                  "draft",
                  "in_review",
                  "changes_requested",
                  "approved"
                ]
              },
              "sort": {
                "type": "string",
                "enum": [
                  "updatedAt",
                  "title",
                  "publishedAt"
                ]
              },
              "order": {
                "type": "string",
                "enum": [
                  "asc",
                  "desc"
                ]
              },
              "limit": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100
              },
              "cursor": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articles": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "organizationId": {
                      "type": "string"
                    },
                    "workspaceId": {
                      "type": "string"
                    },
                    "publicationKey": {
                      "type": "string"
                    },
                    "publicationId": {
                      "type": "string"
                    },
                    "publicationName": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "slug": {
                      "type": "string"
                    },
                    "excerpt": {
                      "type": "string"
                    },
                    "body": {
                      "type": "array",
                      "items": {
                        "oneOf": [
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "paragraph"
                              },
                              "text": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            },
                            "required": [
                              "type",
                              "text"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "heading"
                              },
                              "level": {
                                "anyOf": [
                                  {
                                    "type": "number",
                                    "const": 2
                                  },
                                  {
                                    "type": "number",
                                    "const": 3
                                  }
                                ],
                                "description": "Section level. The article title renders as the H1, so body headings start at 2."
                              },
                              "text": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            },
                            "required": [
                              "type",
                              "level",
                              "text"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "list"
                              },
                              "style": {
                                "type": "string",
                                "enum": [
                                  "ordered",
                                  "unordered"
                                ]
                              },
                              "items": {
                                "minItems": 1,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                }
                              }
                            },
                            "required": [
                              "type",
                              "style",
                              "items"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "image"
                              },
                              "assetId": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                              },
                              "url": {
                                "type": "string",
                                "format": "uri"
                              },
                              "altText": {
                                "type": "string",
                                "maxLength": 320
                              },
                              "caption": {
                                "type": "string",
                                "maxLength": 320,
                                "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                              }
                            },
                            "required": [
                              "type",
                              "assetId",
                              "url",
                              "altText",
                              "caption"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "quote"
                              },
                              "text": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              },
                              "attribution": {
                                "type": "string",
                                "maxLength": 160
                              }
                            },
                            "required": [
                              "type",
                              "text",
                              "attribution"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "divider"
                              }
                            },
                            "required": [
                              "type"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "code"
                              },
                              "language": {
                                "type": "string",
                                "maxLength": 48
                              },
                              "code": {
                                "type": "string",
                                "minLength": 1
                              }
                            },
                            "required": [
                              "type",
                              "language",
                              "code"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "callout"
                              },
                              "tone": {
                                "type": "string",
                                "enum": [
                                  "info",
                                  "success",
                                  "warning"
                                ]
                              },
                              "title": {
                                "type": "string",
                                "maxLength": 120
                              },
                              "text": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            },
                            "required": [
                              "type",
                              "tone",
                              "title",
                              "text"
                            ],
                            "additionalProperties": false
                          }
                        ],
                        "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                      }
                    },
                    "tags": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "seriesName": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "seriesPosition": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "seoTitle": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "seoDescription": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "ogImageUrl": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "canonicalUrl": {
                      "type": "string"
                    },
                    "authorName": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "draft",
                        "scheduled",
                        "published"
                      ]
                    },
                    "reviewStatus": {
                      "type": "string",
                      "enum": [
                        "draft",
                        "in_review",
                        "changes_requested",
                        "approved"
                      ]
                    },
                    "reviewRequestedAt": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "approvedRevisionNumber": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "approvedByUserId": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "approvedAt": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "scheduledFor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "scheduledRevisionNumber": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "publishedAt": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "publishedRevisionNumber": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "hasUnpublishedChanges": {
                      "type": "boolean"
                    },
                    "revisionNumber": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "createdByUserId": {
                      "type": "string"
                    },
                    "createdAt": {
                      "type": "string"
                    },
                    "updatedAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "organizationId",
                    "workspaceId",
                    "publicationKey",
                    "publicationId",
                    "publicationName",
                    "title",
                    "slug",
                    "excerpt",
                    "body",
                    "tags",
                    "seriesName",
                    "seriesPosition",
                    "seoTitle",
                    "seoDescription",
                    "ogImageUrl",
                    "canonicalUrl",
                    "authorName",
                    "status",
                    "reviewStatus",
                    "reviewRequestedAt",
                    "approvedRevisionNumber",
                    "approvedByUserId",
                    "approvedAt",
                    "scheduledFor",
                    "scheduledRevisionNumber",
                    "publishedAt",
                    "publishedRevisionNumber",
                    "hasUnpublishedChanges",
                    "revisionNumber",
                    "createdByUserId",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                }
              },
              "total": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "nextCursor": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "articles",
              "total",
              "nextCursor"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.list",
            "resource": {
              "kind": "article",
              "idPath": "$.items[].id"
            },
            "effects": [
              "Reads article data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {},
                "expected": "A response matching the published outputSchema for articles.list."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {},
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/articles",
              "body": null
            },
            "effects": "Reads article data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.list",
            "resource": {
              "kind": "article",
              "idPath": "$.items[].id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/articles",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.preview",
          "title": "Preview article",
          "description": "Render an unsaved article draft to the same HTML used by the published reader surface.",
          "method": "POST",
          "path": "/api/articles/preview",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "title": {
                "type": "string",
                "minLength": 1,
                "maxLength": 160,
                "description": "Article headline; renders as the page H1 and seeds the slug when slug is omitted."
              },
              "slug": {
                "description": "URL path segment. Omit to derive it from the title.",
                "type": "string",
                "maxLength": 120
              },
              "publicationId": {
                "description": "Target publication id from publications.list. Omit to use the workspace default publication.",
                "type": "string",
                "minLength": 1
              },
              "excerpt": {
                "type": "string",
                "maxLength": 320
              },
              "body": {
                "description": "Ordered article content as typed blocks (paragraph, heading, list, image, quote, divider, code, callout). Text fields accept inline markdown: **bold**, *italic*, `code`, [label](https://…).",
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "paragraph"
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "text"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "heading"
                        },
                        "level": {
                          "anyOf": [
                            {
                              "type": "number",
                              "const": 2
                            },
                            {
                              "type": "number",
                              "const": 3
                            }
                          ],
                          "description": "Section level. The article title renders as the H1, so body headings start at 2."
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "level",
                        "text"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "list"
                        },
                        "style": {
                          "type": "string",
                          "enum": [
                            "ordered",
                            "unordered"
                          ]
                        },
                        "items": {
                          "minItems": 1,
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                          }
                        }
                      },
                      "required": [
                        "type",
                        "style",
                        "items"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "image"
                        },
                        "assetId": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                        },
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "altText": {
                          "type": "string",
                          "maxLength": 320
                        },
                        "caption": {
                          "type": "string",
                          "maxLength": 320,
                          "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                        }
                      },
                      "required": [
                        "type",
                        "assetId",
                        "url",
                        "altText",
                        "caption"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "quote"
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        },
                        "attribution": {
                          "type": "string",
                          "maxLength": 160
                        }
                      },
                      "required": [
                        "type",
                        "text",
                        "attribution"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "divider"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "code"
                        },
                        "language": {
                          "type": "string",
                          "maxLength": 48
                        },
                        "code": {
                          "type": "string",
                          "minLength": 1
                        }
                      },
                      "required": [
                        "type",
                        "language",
                        "code"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "callout"
                        },
                        "tone": {
                          "type": "string",
                          "enum": [
                            "info",
                            "success",
                            "warning"
                          ]
                        },
                        "title": {
                          "type": "string",
                          "maxLength": 120
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "tone",
                        "title",
                        "text"
                      ],
                      "additionalProperties": false
                    }
                  ],
                  "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                }
              },
              "tags": {
                "maxItems": 12,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 48
                }
              },
              "seriesName": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "seriesPosition": {
                "anyOf": [
                  {
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "seoTitle": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "seoDescription": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "ogImageUrl": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "canonicalUrl": {
                "type": "string",
                "format": "uri"
              },
              "authorName": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              }
            },
            "required": [
              "title"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "bodyHtml": {
                "type": "string"
              }
            },
            "required": [
              "bodyHtml"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.preview",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Reads article data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {
                  "title": "Preview article",
                  "body": [
                    {
                      "type": "paragraph",
                      "text": "Preview body."
                    }
                  ]
                },
                "expected": "A response matching the published outputSchema for articles.preview."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "title": "Preview article",
              "body": [
                {
                  "type": "paragraph",
                  "text": "Preview body."
                }
              ]
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/preview",
              "body": {
                "title": "Preview article",
                "body": [
                  {
                    "type": "paragraph",
                    "text": "Preview body."
                  }
                ]
              }
            },
            "effects": "Reads article data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.preview",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/articles/preview",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.get",
          "title": "Get article",
          "description": "Get one article from the selected editorial workspace.",
          "method": "GET",
          "path": "/api/articles/{articleId}",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.get",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Reads article data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example"
                },
                "expected": "A response matching the published outputSchema for articles.get."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/articles/article_example",
              "body": null
            },
            "effects": "Reads article data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.get",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/articles/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.revisions.list",
          "title": "List article revisions",
          "description": "List the immutable revisions for an article.",
          "method": "GET",
          "path": "/api/articles/{articleId}/revisions",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "revisions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "articleId": {
                      "type": "string"
                    },
                    "revisionNumber": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "snapshot": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "organizationId": {
                          "type": "string"
                        },
                        "workspaceId": {
                          "type": "string"
                        },
                        "publicationKey": {
                          "type": "string"
                        },
                        "publicationId": {
                          "type": "string"
                        },
                        "publicationName": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "slug": {
                          "type": "string"
                        },
                        "excerpt": {
                          "type": "string"
                        },
                        "body": {
                          "type": "array",
                          "items": {
                            "oneOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "paragraph"
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  }
                                },
                                "required": [
                                  "type",
                                  "text"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "heading"
                                  },
                                  "level": {
                                    "anyOf": [
                                      {
                                        "type": "number",
                                        "const": 2
                                      },
                                      {
                                        "type": "number",
                                        "const": 3
                                      }
                                    ],
                                    "description": "Section level. The article title renders as the H1, so body headings start at 2."
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  }
                                },
                                "required": [
                                  "type",
                                  "level",
                                  "text"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "list"
                                  },
                                  "style": {
                                    "type": "string",
                                    "enum": [
                                      "ordered",
                                      "unordered"
                                    ]
                                  },
                                  "items": {
                                    "minItems": 1,
                                    "type": "array",
                                    "items": {
                                      "type": "string",
                                      "minLength": 1,
                                      "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                    }
                                  }
                                },
                                "required": [
                                  "type",
                                  "style",
                                  "items"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "image"
                                  },
                                  "assetId": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                                  },
                                  "url": {
                                    "type": "string",
                                    "format": "uri"
                                  },
                                  "altText": {
                                    "type": "string",
                                    "maxLength": 320
                                  },
                                  "caption": {
                                    "type": "string",
                                    "maxLength": 320,
                                    "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                                  }
                                },
                                "required": [
                                  "type",
                                  "assetId",
                                  "url",
                                  "altText",
                                  "caption"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "quote"
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  },
                                  "attribution": {
                                    "type": "string",
                                    "maxLength": 160
                                  }
                                },
                                "required": [
                                  "type",
                                  "text",
                                  "attribution"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "divider"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "code"
                                  },
                                  "language": {
                                    "type": "string",
                                    "maxLength": 48
                                  },
                                  "code": {
                                    "type": "string",
                                    "minLength": 1
                                  }
                                },
                                "required": [
                                  "type",
                                  "language",
                                  "code"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "callout"
                                  },
                                  "tone": {
                                    "type": "string",
                                    "enum": [
                                      "info",
                                      "success",
                                      "warning"
                                    ]
                                  },
                                  "title": {
                                    "type": "string",
                                    "maxLength": 120
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                  }
                                },
                                "required": [
                                  "type",
                                  "tone",
                                  "title",
                                  "text"
                                ],
                                "additionalProperties": false
                              }
                            ],
                            "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                          }
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "seriesName": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "seriesPosition": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "seoTitle": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "seoDescription": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "ogImageUrl": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "canonicalUrl": {
                          "type": "string"
                        },
                        "authorName": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "scheduled",
                            "published"
                          ]
                        },
                        "reviewStatus": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "in_review",
                            "changes_requested",
                            "approved"
                          ]
                        },
                        "reviewRequestedAt": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "approvedRevisionNumber": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "approvedByUserId": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "approvedAt": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "scheduledFor": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "scheduledRevisionNumber": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "publishedAt": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "publishedRevisionNumber": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "hasUnpublishedChanges": {
                          "type": "boolean"
                        },
                        "revisionNumber": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "createdByUserId": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "organizationId",
                        "workspaceId",
                        "publicationKey",
                        "publicationId",
                        "publicationName",
                        "title",
                        "slug",
                        "excerpt",
                        "body",
                        "tags",
                        "seriesName",
                        "seriesPosition",
                        "seoTitle",
                        "seoDescription",
                        "ogImageUrl",
                        "canonicalUrl",
                        "authorName",
                        "status",
                        "reviewStatus",
                        "reviewRequestedAt",
                        "approvedRevisionNumber",
                        "approvedByUserId",
                        "approvedAt",
                        "scheduledFor",
                        "scheduledRevisionNumber",
                        "publishedAt",
                        "publishedRevisionNumber",
                        "hasUnpublishedChanges",
                        "revisionNumber",
                        "createdByUserId"
                      ],
                      "additionalProperties": false
                    },
                    "createdByUserId": {
                      "type": "string"
                    },
                    "createdAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "articleId",
                    "revisionNumber",
                    "snapshot",
                    "createdByUserId",
                    "createdAt"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "revisions"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.revisions.list",
            "resource": {
              "kind": "article",
              "idPath": "$.items[].id"
            },
            "effects": [
              "Reads article data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example"
                },
                "expected": "A response matching the published outputSchema for articles.revisions.list."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/articles/article_example/revisions",
              "body": null
            },
            "effects": "Reads article data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.revisions.list",
            "resource": {
              "kind": "article",
              "idPath": "$.items[].id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/articles/*/revisions",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.revisions.restore",
          "title": "Restore article revision",
          "description": "Restore an immutable revision as a new unpublished article revision.",
          "method": "POST",
          "path": "/api/articles/{articleId}/revisions/{revisionNumber}/restore",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              },
              "revisionNumber": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "articleId",
              "revisionNumber"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.revisions.restore",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example",
                  "revisionNumber": 2
                },
                "expected": "A response matching the published outputSchema for articles.revisions.restore."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example",
              "revisionNumber": 2
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/article_example/revisions/2/restore",
              "body": {
                "articleId": "article_example",
                "revisionNumber": 2
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.revisions.restore",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/articles/*/revisions/*/restore",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.create",
          "title": "Create article",
          "description": "Create a new draft article in the selected editorial workspace. Always yields a draft: to go live, request review, approve, then publish or schedule.",
          "method": "POST",
          "path": "/api/articles",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "title": {
                "type": "string",
                "minLength": 1,
                "maxLength": 160,
                "description": "Article headline; renders as the page H1 and seeds the slug when slug is omitted."
              },
              "slug": {
                "description": "URL path segment. Omit to derive it from the title.",
                "type": "string",
                "maxLength": 120
              },
              "publicationId": {
                "description": "Target publication id from publications.list. Omit to use the workspace default publication.",
                "type": "string",
                "minLength": 1
              },
              "excerpt": {
                "type": "string",
                "maxLength": 320
              },
              "body": {
                "description": "Ordered article content as typed blocks (paragraph, heading, list, image, quote, divider, code, callout). Text fields accept inline markdown: **bold**, *italic*, `code`, [label](https://…).",
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "paragraph"
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "text"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "heading"
                        },
                        "level": {
                          "anyOf": [
                            {
                              "type": "number",
                              "const": 2
                            },
                            {
                              "type": "number",
                              "const": 3
                            }
                          ],
                          "description": "Section level. The article title renders as the H1, so body headings start at 2."
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "level",
                        "text"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "list"
                        },
                        "style": {
                          "type": "string",
                          "enum": [
                            "ordered",
                            "unordered"
                          ]
                        },
                        "items": {
                          "minItems": 1,
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                          }
                        }
                      },
                      "required": [
                        "type",
                        "style",
                        "items"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "image"
                        },
                        "assetId": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                        },
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "altText": {
                          "type": "string",
                          "maxLength": 320
                        },
                        "caption": {
                          "type": "string",
                          "maxLength": 320,
                          "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                        }
                      },
                      "required": [
                        "type",
                        "assetId",
                        "url",
                        "altText",
                        "caption"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "quote"
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        },
                        "attribution": {
                          "type": "string",
                          "maxLength": 160
                        }
                      },
                      "required": [
                        "type",
                        "text",
                        "attribution"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "divider"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "code"
                        },
                        "language": {
                          "type": "string",
                          "maxLength": 48
                        },
                        "code": {
                          "type": "string",
                          "minLength": 1
                        }
                      },
                      "required": [
                        "type",
                        "language",
                        "code"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "callout"
                        },
                        "tone": {
                          "type": "string",
                          "enum": [
                            "info",
                            "success",
                            "warning"
                          ]
                        },
                        "title": {
                          "type": "string",
                          "maxLength": 120
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "tone",
                        "title",
                        "text"
                      ],
                      "additionalProperties": false
                    }
                  ],
                  "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                }
              },
              "tags": {
                "maxItems": 12,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 48
                }
              },
              "seriesName": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "seriesPosition": {
                "anyOf": [
                  {
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "seoTitle": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "seoDescription": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "ogImageUrl": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "canonicalUrl": {
                "type": "string",
                "format": "uri"
              },
              "authorName": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              }
            },
            "required": [
              "title"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.create",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "title": "How we ship every week",
                  "excerpt": "The release habits that keep our team shipping weekly without breaking production.",
                  "body": [
                    {
                      "type": "paragraph",
                      "text": "Shipping weekly is a **habit**, not a heroic effort. This post covers the *three* practices that make it routine."
                    },
                    {
                      "type": "heading",
                      "level": 2,
                      "text": "Keep changes small"
                    },
                    {
                      "type": "list",
                      "style": "unordered",
                      "items": [
                        "**Small diffs:** easier to review and revert.",
                        "**Feature flags:** decouple deploy from release — see [our guide](https://example.com/flags)."
                      ]
                    },
                    {
                      "type": "quote",
                      "text": "If a release is scary, do it more often.",
                      "attribution": "Engineering handbook"
                    },
                    {
                      "type": "code",
                      "language": "bash",
                      "code": "git switch -c release/weekly\ngit push origin release/weekly"
                    },
                    {
                      "type": "callout",
                      "tone": "info",
                      "title": "Draft first",
                      "text": "Creating an article always produces a draft. Request review, approve, then publish or schedule it."
                    },
                    {
                      "type": "divider"
                    },
                    {
                      "type": "heading",
                      "level": 3,
                      "text": "What we measure"
                    },
                    {
                      "type": "paragraph",
                      "text": "Lead time, review latency, and the rollback count — tracked per `release` tag."
                    }
                  ],
                  "tags": [
                    "engineering",
                    "process"
                  ]
                },
                "expected": "A response matching the published outputSchema for articles.create."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata",
            "nextActionIds": [
              "app_topolo_blog.articles.update",
              "app_topolo_blog.media.upload",
              "app_topolo_blog.articles.checks.get",
              "app_topolo_blog.articles.review.request"
            ]
          },
          "documentation": {
            "example_input": {
              "title": "How we ship every week",
              "excerpt": "The release habits that keep our team shipping weekly without breaking production.",
              "body": [
                {
                  "type": "paragraph",
                  "text": "Shipping weekly is a **habit**, not a heroic effort. This post covers the *three* practices that make it routine."
                },
                {
                  "type": "heading",
                  "level": 2,
                  "text": "Keep changes small"
                },
                {
                  "type": "list",
                  "style": "unordered",
                  "items": [
                    "**Small diffs:** easier to review and revert.",
                    "**Feature flags:** decouple deploy from release — see [our guide](https://example.com/flags)."
                  ]
                },
                {
                  "type": "quote",
                  "text": "If a release is scary, do it more often.",
                  "attribution": "Engineering handbook"
                },
                {
                  "type": "code",
                  "language": "bash",
                  "code": "git switch -c release/weekly\ngit push origin release/weekly"
                },
                {
                  "type": "callout",
                  "tone": "info",
                  "title": "Draft first",
                  "text": "Creating an article always produces a draft. Request review, approve, then publish or schedule it."
                },
                {
                  "type": "divider"
                },
                {
                  "type": "heading",
                  "level": 3,
                  "text": "What we measure"
                },
                {
                  "type": "paragraph",
                  "text": "Lead time, review latency, and the rollback count — tracked per `release` tag."
                }
              ],
              "tags": [
                "engineering",
                "process"
              ]
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles",
              "body": {
                "title": "How we ship every week",
                "excerpt": "The release habits that keep our team shipping weekly without breaking production.",
                "body": [
                  {
                    "type": "paragraph",
                    "text": "Shipping weekly is a **habit**, not a heroic effort. This post covers the *three* practices that make it routine."
                  },
                  {
                    "type": "heading",
                    "level": 2,
                    "text": "Keep changes small"
                  },
                  {
                    "type": "list",
                    "style": "unordered",
                    "items": [
                      "**Small diffs:** easier to review and revert.",
                      "**Feature flags:** decouple deploy from release — see [our guide](https://example.com/flags)."
                    ]
                  },
                  {
                    "type": "quote",
                    "text": "If a release is scary, do it more often.",
                    "attribution": "Engineering handbook"
                  },
                  {
                    "type": "code",
                    "language": "bash",
                    "code": "git switch -c release/weekly\ngit push origin release/weekly"
                  },
                  {
                    "type": "callout",
                    "tone": "info",
                    "title": "Draft first",
                    "text": "Creating an article always produces a draft. Request review, approve, then publish or schedule it."
                  },
                  {
                    "type": "divider"
                  },
                  {
                    "type": "heading",
                    "level": 3,
                    "text": "What we measure"
                  },
                  {
                    "type": "paragraph",
                    "text": "Lead time, review latency, and the rollback count — tracked per `release` tag."
                  }
                ],
                "tags": [
                  "engineering",
                  "process"
                ]
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.create",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [
              "app_topolo_blog.articles.update",
              "app_topolo_blog.media.upload",
              "app_topolo_blog.articles.checks.get",
              "app_topolo_blog.articles.review.request"
            ],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/articles",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.update",
          "title": "Update article",
          "description": "Update an article and append an immutable revision. Provided fields replace their previous values (body is replaced whole, not merged), and any edit resets review status to draft.",
          "method": "PATCH",
          "path": "/api/articles/{articleId}",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              },
              "title": {
                "type": "string",
                "minLength": 1,
                "maxLength": 160,
                "description": "Article headline; renders as the page H1 and seeds the slug when slug is omitted."
              },
              "slug": {
                "description": "URL path segment. Omit to derive it from the title.",
                "type": "string",
                "maxLength": 120
              },
              "publicationId": {
                "description": "Target publication id from publications.list. Omit to use the workspace default publication.",
                "type": "string",
                "minLength": 1
              },
              "excerpt": {
                "type": "string",
                "maxLength": 320
              },
              "body": {
                "description": "Ordered article content as typed blocks (paragraph, heading, list, image, quote, divider, code, callout). Text fields accept inline markdown: **bold**, *italic*, `code`, [label](https://…).",
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "paragraph"
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "text"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "heading"
                        },
                        "level": {
                          "anyOf": [
                            {
                              "type": "number",
                              "const": 2
                            },
                            {
                              "type": "number",
                              "const": 3
                            }
                          ],
                          "description": "Section level. The article title renders as the H1, so body headings start at 2."
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "level",
                        "text"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "list"
                        },
                        "style": {
                          "type": "string",
                          "enum": [
                            "ordered",
                            "unordered"
                          ]
                        },
                        "items": {
                          "minItems": 1,
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                          }
                        }
                      },
                      "required": [
                        "type",
                        "style",
                        "items"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "image"
                        },
                        "assetId": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                        },
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "altText": {
                          "type": "string",
                          "maxLength": 320
                        },
                        "caption": {
                          "type": "string",
                          "maxLength": 320,
                          "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                        }
                      },
                      "required": [
                        "type",
                        "assetId",
                        "url",
                        "altText",
                        "caption"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "quote"
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        },
                        "attribution": {
                          "type": "string",
                          "maxLength": 160
                        }
                      },
                      "required": [
                        "type",
                        "text",
                        "attribution"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "divider"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "code"
                        },
                        "language": {
                          "type": "string",
                          "maxLength": 48
                        },
                        "code": {
                          "type": "string",
                          "minLength": 1
                        }
                      },
                      "required": [
                        "type",
                        "language",
                        "code"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "callout"
                        },
                        "tone": {
                          "type": "string",
                          "enum": [
                            "info",
                            "success",
                            "warning"
                          ]
                        },
                        "title": {
                          "type": "string",
                          "maxLength": 120
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "tone",
                        "title",
                        "text"
                      ],
                      "additionalProperties": false
                    }
                  ],
                  "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                }
              },
              "tags": {
                "maxItems": 12,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 48
                }
              },
              "seriesName": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "seriesPosition": {
                "anyOf": [
                  {
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "seoTitle": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "seoDescription": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "ogImageUrl": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "canonicalUrl": {
                "type": "string",
                "format": "uri"
              },
              "authorName": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.update",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example",
                  "title": "Updated title",
                  "body": [
                    {
                      "type": "paragraph",
                      "text": "Replaces the whole body: send the complete block array, not a fragment."
                    }
                  ]
                },
                "expected": "A response matching the published outputSchema for articles.update."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata",
            "nextActionIds": [
              "app_topolo_blog.articles.checks.get",
              "app_topolo_blog.articles.review.request"
            ]
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example",
              "title": "Updated title",
              "body": [
                {
                  "type": "paragraph",
                  "text": "Replaces the whole body: send the complete block array, not a fragment."
                }
              ]
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "PATCH",
              "path": "/api/articles/article_example",
              "body": {
                "articleId": "article_example",
                "title": "Updated title",
                "body": [
                  {
                    "type": "paragraph",
                    "text": "Replaces the whole body: send the complete block array, not a fragment."
                  }
                ]
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.update",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [
              "app_topolo_blog.articles.checks.get",
              "app_topolo_blog.articles.review.request"
            ],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "PATCH /api/articles/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.delete",
          "title": "Delete article",
          "description": "Permanently delete an article and its immutable revisions from the selected editorial workspace.",
          "method": "DELETE",
          "path": "/api/articles/{articleId}",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "deleted": {
                "type": "boolean",
                "const": true
              },
              "articleId": {
                "type": "string"
              }
            },
            "required": [
              "deleted",
              "articleId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": true,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.delete",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example"
                },
                "expected": "A response matching the published outputSchema for articles.delete."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "DELETE",
              "path": "/api/articles/article_example",
              "body": null
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.delete",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "DELETE /api/articles/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.review.request",
          "title": "Request article review",
          "description": "Submit the current article revision for editorial review.",
          "method": "POST",
          "path": "/api/articles/{articleId}/review/request",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.review.request",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example"
                },
                "expected": "A response matching the published outputSchema for articles.review.request."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata",
            "nextActionIds": [
              "app_topolo_blog.articles.review.approve",
              "app_topolo_blog.articles.review.changes.request"
            ]
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/article_example/review/request",
              "body": {
                "articleId": "article_example"
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.review.request",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [
              "app_topolo_blog.articles.review.approve",
              "app_topolo_blog.articles.review.changes.request"
            ],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "declared_unserved",
            "route_key": "POST /api/articles/*/review/request",
            "evidence": "No matching served route was extracted from canonical staging source."
          }
        },
        {
          "name": "articles.review.approve",
          "title": "Approve article revision",
          "description": "Approve the exact article revision currently under review. Approval is a prerequisite for publish and schedule, and is voided by any later edit.",
          "method": "POST",
          "path": "/api/articles/{articleId}/review/approve",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.review.approve",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example"
                },
                "expected": "A response matching the published outputSchema for articles.review.approve."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata",
            "nextActionIds": [
              "app_topolo_blog.articles.publish",
              "app_topolo_blog.articles.schedule"
            ]
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/article_example/review/approve",
              "body": {
                "articleId": "article_example"
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.review.approve",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [
              "app_topolo_blog.articles.publish",
              "app_topolo_blog.articles.schedule"
            ],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "declared_unserved",
            "route_key": "POST /api/articles/*/review/approve",
            "evidence": "No matching served route was extracted from canonical staging source."
          }
        },
        {
          "name": "articles.review.changes.request",
          "title": "Request article changes",
          "description": "Return an article under review to its author with changes requested.",
          "method": "POST",
          "path": "/api/articles/{articleId}/review/changes-requested",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.review.changes.request",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example"
                },
                "expected": "A response matching the published outputSchema for articles.review.changes.request."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/article_example/review/changes-requested",
              "body": {
                "articleId": "article_example"
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.review.changes.request",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "declared_unserved",
            "route_key": "POST /api/articles/*/review/changes-requested",
            "evidence": "No matching served route was extracted from canonical staging source."
          }
        },
        {
          "name": "articles.publish",
          "title": "Publish approved article",
          "description": "Publish the approved current revision immediately while retaining later edits as unpublished changes. Fails with article_not_approved unless the current revision has been approved via the review actions.",
          "method": "POST",
          "path": "/api/articles/{articleId}/publish",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.publish",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example"
                },
                "expected": "A response matching the published outputSchema for articles.publish."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/article_example/publish",
              "body": {
                "articleId": "article_example"
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.publish",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/articles/*/publish",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.schedule",
          "title": "Schedule approved article",
          "description": "Schedule the approved current revision for future publication. Fails with article_not_approved unless the current revision has been approved via the review actions.",
          "method": "POST",
          "path": "/api/articles/{articleId}/schedule",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              },
              "publishAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
                "description": "Future release time as an ISO 8601 UTC datetime, e.g. 2026-08-20T09:00:00.000Z."
              }
            },
            "required": [
              "articleId",
              "publishAt"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.schedule",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example",
                  "publishAt": "2026-08-20T09:00:00.000Z"
                },
                "expected": "A response matching the published outputSchema for articles.schedule."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata",
            "nextActionIds": [
              "app_topolo_blog.articles.reschedule",
              "app_topolo_blog.articles.schedule.cancel"
            ]
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example",
              "publishAt": "2026-08-20T09:00:00.000Z"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/article_example/schedule",
              "body": {
                "articleId": "article_example",
                "publishAt": "2026-08-20T09:00:00.000Z"
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.schedule",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [
              "app_topolo_blog.articles.reschedule",
              "app_topolo_blog.articles.schedule.cancel"
            ],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/articles/*/schedule",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.reschedule",
          "title": "Reschedule article",
          "description": "Replace the release time for the already scheduled revision.",
          "method": "POST",
          "path": "/api/articles/{articleId}/reschedule",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              },
              "publishAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
                "description": "Future release time as an ISO 8601 UTC datetime, e.g. 2026-08-20T09:00:00.000Z."
              }
            },
            "required": [
              "articleId",
              "publishAt"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.reschedule",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example",
                  "publishAt": "2026-08-21T09:00:00.000Z"
                },
                "expected": "A response matching the published outputSchema for articles.reschedule."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example",
              "publishAt": "2026-08-21T09:00:00.000Z"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/article_example/reschedule",
              "body": {
                "articleId": "article_example",
                "publishAt": "2026-08-21T09:00:00.000Z"
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.reschedule",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/articles/*/reschedule",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.schedule.cancel",
          "title": "Cancel article schedule",
          "description": "Cancel the pending scheduled release without changing any currently published revision.",
          "method": "POST",
          "path": "/api/articles/{articleId}/schedule/cancel",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.schedule.cancel",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example"
                },
                "expected": "A response matching the published outputSchema for articles.schedule.cancel."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/article_example/schedule/cancel",
              "body": {
                "articleId": "article_example"
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.schedule.cancel",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/articles/*/schedule/cancel",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.unpublish",
          "title": "Unpublish article",
          "description": "Remove the currently published revision from public delivery while retaining editorial history.",
          "method": "POST",
          "path": "/api/articles/{articleId}/unpublish",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.unpublish",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example"
                },
                "expected": "A response matching the published outputSchema for articles.unpublish."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/article_example/unpublish",
              "body": {
                "articleId": "article_example"
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.unpublish",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/articles/*/unpublish",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.duplicate",
          "title": "Duplicate article",
          "description": "Create a new draft from an existing article without copying its publication state.",
          "method": "POST",
          "path": "/api/articles/{articleId}/duplicate",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "article": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "publicationKey": {
                    "type": "string"
                  },
                  "publicationId": {
                    "type": "string"
                  },
                  "publicationName": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "seriesName": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seriesPosition": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogImageUrl": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "canonicalUrl": {
                    "type": "string"
                  },
                  "authorName": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "reviewRequestedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedByUserId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "approvedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledFor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "publishedRevisionNumber": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "hasUnpublishedChanges": {
                    "type": "boolean"
                  },
                  "revisionNumber": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdByUserId": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "publicationKey",
                  "publicationId",
                  "publicationName",
                  "title",
                  "slug",
                  "excerpt",
                  "body",
                  "tags",
                  "seriesName",
                  "seriesPosition",
                  "seoTitle",
                  "seoDescription",
                  "ogImageUrl",
                  "canonicalUrl",
                  "authorName",
                  "status",
                  "reviewStatus",
                  "reviewRequestedAt",
                  "approvedRevisionNumber",
                  "approvedByUserId",
                  "approvedAt",
                  "scheduledFor",
                  "scheduledRevisionNumber",
                  "publishedAt",
                  "publishedRevisionNumber",
                  "hasUnpublishedChanges",
                  "revisionNumber",
                  "createdByUserId",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "article"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.duplicate",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example"
                },
                "expected": "A response matching the published outputSchema for articles.duplicate."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/article_example/duplicate",
              "body": {
                "articleId": "article_example"
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.duplicate",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/articles/*/duplicate",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.checks.get",
          "title": "Check article readiness",
          "description": "Run SEO completeness, accessibility, and bounded broken-link checks for an article.",
          "method": "GET",
          "path": "/api/articles/{articleId}/checks",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "articleId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "checks": {
                "type": "object",
                "properties": {
                  "checks": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "label": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pass",
                            "warning",
                            "error"
                          ]
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "label",
                        "status",
                        "message"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "links": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "ok",
                            "broken",
                            "blocked"
                          ]
                        },
                        "statusCode": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "url",
                        "status",
                        "statusCode"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "complete": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "checks",
                  "links",
                  "complete"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "checks"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.checks.get",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Reads article data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {
                  "articleId": "article_example"
                },
                "expected": "A response matching the published outputSchema for articles.checks.get."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleId": "article_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/articles/article_example/checks",
              "body": null
            },
            "effects": "Reads article data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.checks.get",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/articles/*/checks",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "articles.bulk",
          "title": "Run bulk article operation",
          "description": "Apply one governed editorial operation to up to 100 selected articles.",
          "method": "POST",
          "path": "/api/articles/bulk",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "articleIds": {
                "minItems": 1,
                "maxItems": 100,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                }
              },
              "operation": {
                "type": "string",
                "enum": [
                  "request_review",
                  "approve",
                  "publish",
                  "unpublish",
                  "delete"
                ]
              }
            },
            "required": [
              "articleIds",
              "operation"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "results": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "articleId": {
                      "type": "string"
                    },
                    "success": {
                      "type": "boolean"
                    },
                    "error": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "articleId",
                    "success",
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "results"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.bulk",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "articleIds": [
                    "article_example"
                  ],
                  "operation": "request_review"
                },
                "expected": "A response matching the published outputSchema for articles.bulk."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "articleIds": [
                "article_example"
              ],
              "operation": "request_review"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/articles/bulk",
              "body": {
                "articleIds": [
                  "article_example"
                ],
                "operation": "request_review"
              }
            },
            "effects": "Changes article state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=articles.bulk",
            "resource": {
              "kind": "article",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/articles/bulk",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "templates.list",
          "title": "List article templates",
          "description": "List reusable article templates in the selected editorial workspace.",
          "method": "GET",
          "path": "/api/templates",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "templates": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "titlePattern": {
                      "type": "string"
                    },
                    "excerpt": {
                      "type": "string"
                    },
                    "body": {
                      "type": "array",
                      "items": {
                        "oneOf": [
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "paragraph"
                              },
                              "text": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            },
                            "required": [
                              "type",
                              "text"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "heading"
                              },
                              "level": {
                                "anyOf": [
                                  {
                                    "type": "number",
                                    "const": 2
                                  },
                                  {
                                    "type": "number",
                                    "const": 3
                                  }
                                ],
                                "description": "Section level. The article title renders as the H1, so body headings start at 2."
                              },
                              "text": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            },
                            "required": [
                              "type",
                              "level",
                              "text"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "list"
                              },
                              "style": {
                                "type": "string",
                                "enum": [
                                  "ordered",
                                  "unordered"
                                ]
                              },
                              "items": {
                                "minItems": 1,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                                }
                              }
                            },
                            "required": [
                              "type",
                              "style",
                              "items"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "image"
                              },
                              "assetId": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                              },
                              "url": {
                                "type": "string",
                                "format": "uri"
                              },
                              "altText": {
                                "type": "string",
                                "maxLength": 320
                              },
                              "caption": {
                                "type": "string",
                                "maxLength": 320,
                                "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                              }
                            },
                            "required": [
                              "type",
                              "assetId",
                              "url",
                              "altText",
                              "caption"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "quote"
                              },
                              "text": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              },
                              "attribution": {
                                "type": "string",
                                "maxLength": 160
                              }
                            },
                            "required": [
                              "type",
                              "text",
                              "attribution"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "divider"
                              }
                            },
                            "required": [
                              "type"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "code"
                              },
                              "language": {
                                "type": "string",
                                "maxLength": 48
                              },
                              "code": {
                                "type": "string",
                                "minLength": 1
                              }
                            },
                            "required": [
                              "type",
                              "language",
                              "code"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "const": "callout"
                              },
                              "tone": {
                                "type": "string",
                                "enum": [
                                  "info",
                                  "success",
                                  "warning"
                                ]
                              },
                              "title": {
                                "type": "string",
                                "maxLength": 120
                              },
                              "text": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            },
                            "required": [
                              "type",
                              "tone",
                              "title",
                              "text"
                            ],
                            "additionalProperties": false
                          }
                        ],
                        "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                      }
                    },
                    "tags": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "createdAt": {
                      "type": "string"
                    },
                    "updatedAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "description",
                    "titlePattern",
                    "excerpt",
                    "body",
                    "tags",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "templates"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=templates.list",
            "resource": {
              "kind": "article_template",
              "idPath": "$.items[].id"
            },
            "effects": [
              "Reads article template data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {},
                "expected": "A response matching the published outputSchema for templates.list."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {},
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/templates",
              "body": null
            },
            "effects": "Reads article template data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=templates.list",
            "resource": {
              "kind": "article_template",
              "idPath": "$.items[].id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/templates",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "templates.create",
          "title": "Create article template",
          "description": "Create a reusable article structure for the selected editorial workspace.",
          "method": "POST",
          "path": "/api/templates",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "description": {
                "type": "string",
                "maxLength": 320
              },
              "titlePattern": {
                "type": "string",
                "maxLength": 160
              },
              "excerpt": {
                "type": "string",
                "maxLength": 320
              },
              "body": {
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "paragraph"
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "text"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "heading"
                        },
                        "level": {
                          "anyOf": [
                            {
                              "type": "number",
                              "const": 2
                            },
                            {
                              "type": "number",
                              "const": 3
                            }
                          ],
                          "description": "Section level. The article title renders as the H1, so body headings start at 2."
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "level",
                        "text"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "list"
                        },
                        "style": {
                          "type": "string",
                          "enum": [
                            "ordered",
                            "unordered"
                          ]
                        },
                        "items": {
                          "minItems": 1,
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                          }
                        }
                      },
                      "required": [
                        "type",
                        "style",
                        "items"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "image"
                        },
                        "assetId": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                        },
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "altText": {
                          "type": "string",
                          "maxLength": 320
                        },
                        "caption": {
                          "type": "string",
                          "maxLength": 320,
                          "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                        }
                      },
                      "required": [
                        "type",
                        "assetId",
                        "url",
                        "altText",
                        "caption"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "quote"
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        },
                        "attribution": {
                          "type": "string",
                          "maxLength": 160
                        }
                      },
                      "required": [
                        "type",
                        "text",
                        "attribution"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "divider"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "code"
                        },
                        "language": {
                          "type": "string",
                          "maxLength": 48
                        },
                        "code": {
                          "type": "string",
                          "minLength": 1
                        }
                      },
                      "required": [
                        "type",
                        "language",
                        "code"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "callout"
                        },
                        "tone": {
                          "type": "string",
                          "enum": [
                            "info",
                            "success",
                            "warning"
                          ]
                        },
                        "title": {
                          "type": "string",
                          "maxLength": 120
                        },
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                        }
                      },
                      "required": [
                        "type",
                        "tone",
                        "title",
                        "text"
                      ],
                      "additionalProperties": false
                    }
                  ],
                  "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                }
              },
              "tags": {
                "maxItems": 12,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 48
                }
              }
            },
            "required": [
              "name"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "template": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "titlePattern": {
                    "type": "string"
                  },
                  "excerpt": {
                    "type": "string"
                  },
                  "body": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "paragraph"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "heading"
                            },
                            "level": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "const": 2
                                },
                                {
                                  "type": "number",
                                  "const": 3
                                }
                              ],
                              "description": "Section level. The article title renders as the H1, so body headings start at 2."
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "level",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "list"
                            },
                            "style": {
                              "type": "string",
                              "enum": [
                                "ordered",
                                "unordered"
                              ]
                            },
                            "items": {
                              "minItems": 1,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                              }
                            }
                          },
                          "required": [
                            "type",
                            "style",
                            "items"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "image"
                            },
                            "assetId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Blog media asset id. Upload the image first with media.upload; its response provides assetId and url."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "altText": {
                              "type": "string",
                              "maxLength": 320
                            },
                            "caption": {
                              "type": "string",
                              "maxLength": 320,
                              "description": "Rendered verbatim below the image; inline markdown is NOT applied here."
                            }
                          },
                          "required": [
                            "type",
                            "assetId",
                            "url",
                            "altText",
                            "caption"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "quote"
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            },
                            "attribution": {
                              "type": "string",
                              "maxLength": 160
                            }
                          },
                          "required": [
                            "type",
                            "text",
                            "attribution"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "divider"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "code"
                            },
                            "language": {
                              "type": "string",
                              "maxLength": 48
                            },
                            "code": {
                              "type": "string",
                              "minLength": 1
                            }
                          },
                          "required": [
                            "type",
                            "language",
                            "code"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "const": "callout"
                            },
                            "tone": {
                              "type": "string",
                              "enum": [
                                "info",
                                "success",
                                "warning"
                              ]
                            },
                            "title": {
                              "type": "string",
                              "maxLength": 120
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Plain text with optional inline markdown: **bold**, *italic*, `code`, and [label](https://…) links. No other markdown is rendered."
                            }
                          },
                          "required": [
                            "type",
                            "tone",
                            "title",
                            "text"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One typed content block. An article body is an ordered array of these blocks — paragraph, heading (levels 2–3), list, image, quote, divider, code, and callout."
                    }
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "name",
                  "description",
                  "titlePattern",
                  "excerpt",
                  "body",
                  "tags",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "template"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=templates.create",
            "resource": {
              "kind": "article_template",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article template state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "name": "Product announcement",
                  "body": [
                    {
                      "type": "paragraph",
                      "text": "Opening."
                    }
                  ]
                },
                "expected": "A response matching the published outputSchema for templates.create."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "name": "Product announcement",
              "body": [
                {
                  "type": "paragraph",
                  "text": "Opening."
                }
              ]
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/templates",
              "body": {
                "name": "Product announcement",
                "body": [
                  {
                    "type": "paragraph",
                    "text": "Opening."
                  }
                ]
              }
            },
            "effects": "Changes article template state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=templates.create",
            "resource": {
              "kind": "article_template",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/templates",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "templates.delete",
          "title": "Delete article template",
          "description": "Delete a reusable article template.",
          "method": "DELETE",
          "path": "/api/templates/{templateId}",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "templateId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "templateId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "deleted": {
                "type": "boolean",
                "const": true
              },
              "templateId": {
                "type": "string"
              }
            },
            "required": [
              "deleted",
              "templateId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": true,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=templates.delete",
            "resource": {
              "kind": "article_template",
              "idPath": "$.id"
            },
            "effects": [
              "Changes article template state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "templateId": "template_example"
                },
                "expected": "A response matching the published outputSchema for templates.delete."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "templateId": "template_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "DELETE",
              "path": "/api/templates/template_example",
              "body": null
            },
            "effects": "Changes article template state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=templates.delete",
            "resource": {
              "kind": "article_template",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "declared_unserved",
            "route_key": "DELETE /api/templates/*",
            "evidence": "No matching served route was extracted from canonical staging source."
          }
        },
        {
          "name": "saved_searches.list",
          "title": "List saved article searches",
          "description": "List saved article search and sorting configurations.",
          "method": "GET",
          "path": "/api/saved-searches",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "searches": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "query": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "all",
                        "draft",
                        "scheduled",
                        "published"
                      ]
                    },
                    "reviewStatus": {
                      "type": "string",
                      "enum": [
                        "all",
                        "draft",
                        "in_review",
                        "changes_requested",
                        "approved"
                      ]
                    },
                    "sort": {
                      "type": "string",
                      "enum": [
                        "updatedAt",
                        "title",
                        "publishedAt"
                      ]
                    },
                    "order": {
                      "type": "string",
                      "enum": [
                        "asc",
                        "desc"
                      ]
                    },
                    "createdAt": {
                      "type": "string"
                    },
                    "updatedAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "query",
                    "status",
                    "reviewStatus",
                    "sort",
                    "order",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "searches"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=saved_searches.list",
            "resource": {
              "kind": "saved_search",
              "idPath": "$.items[].id"
            },
            "effects": [
              "Reads saved search data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {},
                "expected": "A response matching the published outputSchema for saved_searches.list."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {},
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/saved-searches",
              "body": null
            },
            "effects": "Reads saved search data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=saved_searches.list",
            "resource": {
              "kind": "saved_search",
              "idPath": "$.items[].id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/saved-searches",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "saved_searches.create",
          "title": "Create saved article search",
          "description": "Save an article query, workflow filter, and sort order.",
          "method": "POST",
          "path": "/api/saved-searches",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "query": {
                "type": "string",
                "maxLength": 160
              },
              "status": {
                "type": "string",
                "enum": [
                  "all",
                  "draft",
                  "scheduled",
                  "published"
                ]
              },
              "reviewStatus": {
                "type": "string",
                "enum": [
                  "all",
                  "draft",
                  "in_review",
                  "changes_requested",
                  "approved"
                ]
              },
              "sort": {
                "type": "string",
                "enum": [
                  "updatedAt",
                  "title",
                  "publishedAt"
                ]
              },
              "order": {
                "type": "string",
                "enum": [
                  "asc",
                  "desc"
                ]
              }
            },
            "required": [
              "name"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "search": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "query": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "all",
                      "draft",
                      "scheduled",
                      "published"
                    ]
                  },
                  "reviewStatus": {
                    "type": "string",
                    "enum": [
                      "all",
                      "draft",
                      "in_review",
                      "changes_requested",
                      "approved"
                    ]
                  },
                  "sort": {
                    "type": "string",
                    "enum": [
                      "updatedAt",
                      "title",
                      "publishedAt"
                    ]
                  },
                  "order": {
                    "type": "string",
                    "enum": [
                      "asc",
                      "desc"
                    ]
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "name",
                  "query",
                  "status",
                  "reviewStatus",
                  "sort",
                  "order",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "search"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=saved_searches.create",
            "resource": {
              "kind": "saved_search",
              "idPath": "$.id"
            },
            "effects": [
              "Changes saved search state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "name": "Needs approval",
                  "reviewStatus": "in_review"
                },
                "expected": "A response matching the published outputSchema for saved_searches.create."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "name": "Needs approval",
              "reviewStatus": "in_review"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/saved-searches",
              "body": {
                "name": "Needs approval",
                "reviewStatus": "in_review"
              }
            },
            "effects": "Changes saved search state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=saved_searches.create",
            "resource": {
              "kind": "saved_search",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/saved-searches",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "saved_searches.delete",
          "title": "Delete saved article search",
          "description": "Delete a saved article search configuration.",
          "method": "DELETE",
          "path": "/api/saved-searches/{searchId}",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "searchId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "searchId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "deleted": {
                "type": "boolean",
                "const": true
              },
              "searchId": {
                "type": "string"
              }
            },
            "required": [
              "deleted",
              "searchId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": true,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=saved_searches.delete",
            "resource": {
              "kind": "saved_search",
              "idPath": "$.id"
            },
            "effects": [
              "Changes saved search state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "searchId": "search_example"
                },
                "expected": "A response matching the published outputSchema for saved_searches.delete."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "searchId": "search_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "DELETE",
              "path": "/api/saved-searches/search_example",
              "body": null
            },
            "effects": "Changes saved search state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=saved_searches.delete",
            "resource": {
              "kind": "saved_search",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "declared_unserved",
            "route_key": "DELETE /api/saved-searches/*",
            "evidence": "No matching served route was extracted from canonical staging source."
          }
        },
        {
          "name": "publications.list",
          "title": "List publications",
          "description": "List configured publishing destinations for the selected workspace.",
          "method": "GET",
          "path": "/api/publications",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "publications": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "organizationId": {
                      "type": "string"
                    },
                    "workspaceId": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "slug": {
                      "type": "string"
                    },
                    "baseUrl": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "defaultSeoTitle": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "defaultSeoDescription": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "isDefault": {
                      "type": "boolean"
                    },
                    "articleCount": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "createdAt": {
                      "type": "string"
                    },
                    "updatedAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "organizationId",
                    "workspaceId",
                    "name",
                    "slug",
                    "baseUrl",
                    "description",
                    "defaultSeoTitle",
                    "defaultSeoDescription",
                    "isDefault",
                    "articleCount",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "publications"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=publications.list",
            "resource": {
              "kind": "publication",
              "idPath": "$.items[].id"
            },
            "effects": [
              "Reads publication data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {},
                "expected": "A response matching the published outputSchema for publications.list."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {},
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/publications",
              "body": null
            },
            "effects": "Reads publication data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=publications.list",
            "resource": {
              "kind": "publication",
              "idPath": "$.items[].id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/publications",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "publications.create",
          "title": "Create publication",
          "description": "Create a named publishing destination with a canonical base URL.",
          "method": "POST",
          "path": "/api/publications",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "baseUrl": {
                "type": "string",
                "format": "uri"
              },
              "description": {
                "type": "string",
                "maxLength": 320
              },
              "defaultSeoTitle": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "defaultSeoDescription": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "slug": {
                "type": "string",
                "maxLength": 63
              }
            },
            "required": [
              "name",
              "baseUrl"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "publication": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "baseUrl": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "defaultSeoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "defaultSeoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "isDefault": {
                    "type": "boolean"
                  },
                  "articleCount": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "name",
                  "slug",
                  "baseUrl",
                  "description",
                  "defaultSeoTitle",
                  "defaultSeoDescription",
                  "isDefault",
                  "articleCount",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "publication"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=publications.create",
            "resource": {
              "kind": "publication",
              "idPath": "$.id"
            },
            "effects": [
              "Changes publication state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "name": "Company blog",
                  "baseUrl": "https://example.com/blog"
                },
                "expected": "A response matching the published outputSchema for publications.create."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "name": "Company blog",
              "baseUrl": "https://example.com/blog"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/publications",
              "body": {
                "name": "Company blog",
                "baseUrl": "https://example.com/blog"
              }
            },
            "effects": "Changes publication state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=publications.create",
            "resource": {
              "kind": "publication",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/publications",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "publications.update",
          "title": "Update publication",
          "description": "Update a publication name, destination, description, and SEO defaults.",
          "method": "PATCH",
          "path": "/api/publications/{publicationId}",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "publicationId": {
                "type": "string",
                "minLength": 1
              },
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "baseUrl": {
                "type": "string",
                "format": "uri"
              },
              "description": {
                "type": "string",
                "maxLength": 320
              },
              "defaultSeoTitle": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "defaultSeoDescription": {
                "anyOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "publicationId",
              "name",
              "baseUrl"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "publication": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "baseUrl": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "defaultSeoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "defaultSeoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "isDefault": {
                    "type": "boolean"
                  },
                  "articleCount": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "name",
                  "slug",
                  "baseUrl",
                  "description",
                  "defaultSeoTitle",
                  "defaultSeoDescription",
                  "isDefault",
                  "articleCount",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "publication"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=publications.update",
            "resource": {
              "kind": "publication",
              "idPath": "$.id"
            },
            "effects": [
              "Changes publication state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "publicationId": "publication_example",
                  "name": "Company blog",
                  "baseUrl": "https://example.com/blog"
                },
                "expected": "A response matching the published outputSchema for publications.update."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "publicationId": "publication_example",
              "name": "Company blog",
              "baseUrl": "https://example.com/blog"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "PATCH",
              "path": "/api/publications/publication_example",
              "body": {
                "publicationId": "publication_example",
                "name": "Company blog",
                "baseUrl": "https://example.com/blog"
              }
            },
            "effects": "Changes publication state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=publications.update",
            "resource": {
              "kind": "publication",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "PATCH /api/publications/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "publications.default.set",
          "title": "Set default publication",
          "description": "Choose the publication used automatically for new articles.",
          "method": "POST",
          "path": "/api/publications/{publicationId}/default",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "publicationId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "publicationId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "publication": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "organizationId": {
                    "type": "string"
                  },
                  "workspaceId": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "baseUrl": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "defaultSeoTitle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "defaultSeoDescription": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "isDefault": {
                    "type": "boolean"
                  },
                  "articleCount": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "organizationId",
                  "workspaceId",
                  "name",
                  "slug",
                  "baseUrl",
                  "description",
                  "defaultSeoTitle",
                  "defaultSeoDescription",
                  "isDefault",
                  "articleCount",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "publication"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=publications.default.set",
            "resource": {
              "kind": "publication",
              "idPath": "$.id"
            },
            "effects": [
              "Changes publication state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "publicationId": "publication_example"
                },
                "expected": "A response matching the published outputSchema for publications.default.set."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "publicationId": "publication_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/publications/publication_example/default",
              "body": {
                "publicationId": "publication_example"
              }
            },
            "effects": "Changes publication state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=publications.default.set",
            "resource": {
              "kind": "publication",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/publications/*/default",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "publications.delete",
          "title": "Delete publication",
          "description": "Delete an unused non-default publication.",
          "method": "DELETE",
          "path": "/api/publications/{publicationId}",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "publicationId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "publicationId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "deleted": {
                "type": "boolean",
                "const": true
              },
              "publicationId": {
                "type": "string"
              }
            },
            "required": [
              "deleted",
              "publicationId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": true,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=publications.delete",
            "resource": {
              "kind": "publication",
              "idPath": "$.id"
            },
            "effects": [
              "Changes publication state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "publicationId": "publication_example"
                },
                "expected": "A response matching the published outputSchema for publications.delete."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "publicationId": "publication_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "DELETE",
              "path": "/api/publications/publication_example",
              "body": null
            },
            "effects": "Changes publication state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=publications.delete",
            "resource": {
              "kind": "publication",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "DELETE /api/publications/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "media.list",
          "title": "List media",
          "description": "List reusable Blog media assets in the selected workspace.",
          "method": "GET",
          "path": "/api/media",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "assets": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "fileName": {
                      "type": "string"
                    },
                    "contentType": {
                      "type": "string"
                    },
                    "byteSize": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "altText": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    },
                    "usageCount": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991
                    },
                    "createdAt": {
                      "type": "string"
                    },
                    "updatedAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "fileName",
                    "contentType",
                    "byteSize",
                    "altText",
                    "url",
                    "usageCount",
                    "createdAt",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "assets"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=media.list",
            "resource": {
              "kind": "media_asset",
              "idPath": "$.items[].id"
            },
            "effects": [
              "Reads media asset data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {},
                "expected": "A response matching the published outputSchema for media.list."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {},
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/media",
              "body": null
            },
            "effects": "Reads media asset data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=media.list",
            "resource": {
              "kind": "media_asset",
              "idPath": "$.items[].id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/media",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "media.upload",
          "title": "Upload media",
          "description": "Upload a reusable image to the Blog media library. The response asset provides the assetId and url an article image block requires.",
          "method": "POST",
          "path": "/api/media",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "contentBase64": {
                "type": "string",
                "minLength": 1
              },
              "contentType": {
                "type": "string",
                "enum": [
                  "image/gif",
                  "image/jpeg",
                  "image/png",
                  "image/webp"
                ]
              },
              "fileName": {
                "type": "string",
                "minLength": 1,
                "maxLength": 255
              },
              "altText": {
                "type": "string",
                "maxLength": 320
              }
            },
            "required": [
              "contentBase64",
              "contentType",
              "fileName"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "asset": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "fileName": {
                    "type": "string"
                  },
                  "contentType": {
                    "type": "string"
                  },
                  "byteSize": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "altText": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  },
                  "usageCount": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "fileName",
                  "contentType",
                  "byteSize",
                  "altText",
                  "url",
                  "usageCount",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "asset"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=media.upload",
            "resource": {
              "kind": "media_asset",
              "idPath": "$.id"
            },
            "effects": [
              "Changes media asset state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "contentBase64": "iVBORw0KGgo=",
                  "contentType": "image/png",
                  "fileName": "example.png"
                },
                "expected": "A response matching the published outputSchema for media.upload."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata",
            "nextActionIds": [
              "app_topolo_blog.articles.create",
              "app_topolo_blog.articles.update"
            ],
            "upload": {
              "profile": "inline-base64",
              "contentField": "contentBase64",
              "contentTypeField": "contentType",
              "fileNameField": "fileName",
              "maxBytes": 10485760,
              "acceptedContentTypes": [
                "image/gif",
                "image/jpeg",
                "image/png",
                "image/webp"
              ]
            }
          },
          "documentation": {
            "example_input": {
              "contentBase64": "iVBORw0KGgo=",
              "contentType": "image/png",
              "fileName": "example.png"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "POST",
              "path": "/api/media",
              "body": {
                "contentBase64": "iVBORw0KGgo=",
                "contentType": "image/png",
                "fileName": "example.png"
              }
            },
            "effects": "Changes media asset state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=media.upload",
            "resource": {
              "kind": "media_asset",
              "idPath": "$.id"
            },
            "next_action_ids": [
              "app_topolo_blog.articles.create",
              "app_topolo_blog.articles.update"
            ],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "POST /api/media",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "media.update",
          "title": "Update media",
          "description": "Update alternative text for a Blog media asset.",
          "method": "PATCH",
          "path": "/api/media/{assetId}",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "assetId": {
                "type": "string",
                "minLength": 1
              },
              "altText": {
                "type": "string",
                "maxLength": 320
              }
            },
            "required": [
              "assetId",
              "altText"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "asset": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "fileName": {
                    "type": "string"
                  },
                  "contentType": {
                    "type": "string"
                  },
                  "byteSize": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "altText": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  },
                  "usageCount": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "fileName",
                  "contentType",
                  "byteSize",
                  "altText",
                  "url",
                  "usageCount",
                  "createdAt",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "asset"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=media.update",
            "resource": {
              "kind": "media_asset",
              "idPath": "$.id"
            },
            "effects": [
              "Changes media asset state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "assetId": "media_example",
                  "altText": "A useful description"
                },
                "expected": "A response matching the published outputSchema for media.update."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "assetId": "media_example",
              "altText": "A useful description"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "PATCH",
              "path": "/api/media/media_example",
              "body": {
                "assetId": "media_example",
                "altText": "A useful description"
              }
            },
            "effects": "Changes media asset state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=media.update",
            "resource": {
              "kind": "media_asset",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "PATCH /api/media/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "media.delete",
          "title": "Delete media",
          "description": "Permanently delete a Blog media asset.",
          "method": "DELETE",
          "path": "/api/media/{assetId}",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "assetId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "assetId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "deleted": {
                "type": "boolean",
                "const": true
              },
              "assetId": {
                "type": "string"
              }
            },
            "required": [
              "deleted",
              "assetId"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": true,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=media.delete",
            "resource": {
              "kind": "media_asset",
              "idPath": "$.id"
            },
            "effects": [
              "Changes media asset state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "assetId": "media_example"
                },
                "expected": "A response matching the published outputSchema for media.delete."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "assetId": "media_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "DELETE",
              "path": "/api/media/media_example",
              "body": null
            },
            "effects": "Changes media asset state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=media.delete",
            "resource": {
              "kind": "media_asset",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "DELETE /api/media/*",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "settings.get",
          "title": "Get editorial settings",
          "description": "Get workspace-level editorial and SEO defaults.",
          "method": "GET",
          "path": "/api/settings",
          "permission": "workspace:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "settings": {
                "type": "object",
                "properties": {
                  "editorialName": {
                    "type": "string"
                  },
                  "defaultAuthorName": {
                    "type": "string"
                  },
                  "defaultSeoTitle": {
                    "type": "string"
                  },
                  "defaultSeoDescription": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "editorialName",
                  "defaultAuthorName",
                  "defaultSeoTitle",
                  "defaultSeoDescription",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "settings"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=settings.get",
            "resource": {
              "kind": "workspace",
              "idPath": "$.id"
            },
            "effects": [
              "Reads workspace data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {},
                "expected": "A response matching the published outputSchema for settings.get."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {},
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/settings",
              "body": null
            },
            "effects": "Reads workspace data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=settings.get",
            "resource": {
              "kind": "workspace",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/settings",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "settings.update",
          "title": "Update editorial settings",
          "description": "Update workspace-level editorial and SEO defaults.",
          "method": "PUT",
          "path": "/api/settings",
          "permission": "workspace:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "editorialName": {
                "type": "string",
                "maxLength": 100
              },
              "defaultAuthorName": {
                "type": "string",
                "maxLength": 100
              },
              "defaultSeoTitle": {
                "type": "string",
                "maxLength": 160
              },
              "defaultSeoDescription": {
                "type": "string",
                "maxLength": 320
              }
            },
            "required": [
              "editorialName",
              "defaultAuthorName",
              "defaultSeoTitle",
              "defaultSeoDescription"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "settings": {
                "type": "object",
                "properties": {
                  "editorialName": {
                    "type": "string"
                  },
                  "defaultAuthorName": {
                    "type": "string"
                  },
                  "defaultSeoTitle": {
                    "type": "string"
                  },
                  "defaultSeoDescription": {
                    "type": "string"
                  },
                  "updatedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "editorialName",
                  "defaultAuthorName",
                  "defaultSeoTitle",
                  "defaultSeoDescription",
                  "updatedAt"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "settings"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=settings.update",
            "resource": {
              "kind": "workspace",
              "idPath": "$.id"
            },
            "effects": [
              "Changes workspace state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission workspace:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "editorialName": "Editorial team",
                  "defaultAuthorName": "Topolo",
                  "defaultSeoTitle": "Company blog",
                  "defaultSeoDescription": "News and perspectives from the team."
                },
                "expected": "A response matching the published outputSchema for settings.update."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "editorialName": "Editorial team",
              "defaultAuthorName": "Topolo",
              "defaultSeoTitle": "Company blog",
              "defaultSeoDescription": "News and perspectives from the team."
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "PUT",
              "path": "/api/settings",
              "body": {
                "editorialName": "Editorial team",
                "defaultAuthorName": "Topolo",
                "defaultSeoTitle": "Company blog",
                "defaultSeoDescription": "News and perspectives from the team."
              }
            },
            "effects": "Changes workspace state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission workspace:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=settings.update",
            "resource": {
              "kind": "workspace",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "PUT /api/settings",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "organizations.data.export",
          "title": "Export organization data",
          "description": "Export all TopoloBlog articles and immutable revisions for the authenticated organization.",
          "method": "GET",
          "path": "/api/organizations/{organizationId}/data",
          "permission": "privacy:read",
          "authorizationMode": "static",
          "readOnly": true,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "organizationId": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "organizationId"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "organizationId": {
                    "type": "string"
                  },
                  "credentialsIncluded": {
                    "type": "boolean",
                    "const": false
                  },
                  "exportedAt": {
                    "type": "string"
                  },
                  "articles": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "workspace_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "workspace_id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "revisions": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "article_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "article_id"
                      ],
                      "additionalProperties": {}
                    }
                  }
                },
                "required": [
                  "organizationId",
                  "credentialsIncluded",
                  "exportedAt",
                  "articles",
                  "revisions"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "data"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": false,
          "requiresConfirmation": false,
          "agentAccess": "auto",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=organizations.data.export",
            "resource": {
              "kind": "organization",
              "idPath": "$.id"
            },
            "effects": [
              "Reads organization data without changing service state."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission privacy:read and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "examples": [
              {
                "input": {
                  "organizationId": "organization_example"
                },
                "expected": "A response matching the published outputSchema for organizations.data.export."
              }
            ],
            "recovery": {
              "mode": "not_applicable",
              "instructions": "This action does not change service state."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "organizationId": "organization_example"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --json"
            ],
            "http_example": {
              "method": "GET",
              "path": "/api/organizations/organization_example/data",
              "body": null
            },
            "effects": "Reads organization data without changing service state.",
            "verification": [
              "Validate the response against outputSchema and confirm it belongs to the selected resource context."
            ],
            "recovery": [
              {
                "mode": "not_applicable",
                "instructions": "This action does not change service state."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission privacy:read and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=organizations.data.export",
            "resource": {
              "kind": "organization",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "GET /api/organizations/*/data",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        },
        {
          "name": "organizations.data.erase",
          "title": "Erase organization data",
          "description": "Erase all TopoloBlog articles and revisions for the authenticated organization after literal ERASE confirmation.",
          "method": "DELETE",
          "path": "/api/organizations/{organizationId}/data",
          "permission": "privacy:write",
          "authorizationMode": "static",
          "readOnly": false,
          "inputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "organizationId": {
                "type": "string",
                "minLength": 1
              },
              "confirmation": {
                "type": "string",
                "const": "ERASE"
              }
            },
            "required": [
              "organizationId",
              "confirmation"
            ],
            "additionalProperties": false
          },
          "outputSchema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "organizationId": {
                    "type": "string"
                  },
                  "erased": {
                    "type": "boolean",
                    "const": true
                  }
                },
                "required": [
                  "organizationId",
                  "erased"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "data"
            ],
            "additionalProperties": false
          },
          "target": "api",
          "destructive": true,
          "requiresConfirmation": true,
          "agentAccess": "confirm",
          "agentContract": {
            "docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=organizations.data.erase",
            "resource": {
              "kind": "organization",
              "idPath": "$.id"
            },
            "effects": [
              "Changes organization state in the selected Topolo resource context."
            ],
            "errors": [
              {
                "status": 401,
                "code": "authentication_required",
                "recovery": "Authenticate again or provide a valid Topolo API key."
              },
              {
                "status": 403,
                "code": "permission_denied",
                "recovery": "Grant the credential permission privacy:write and the required resource binding."
              },
              {
                "status": 429,
                "code": "rate_limited",
                "recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
              },
              {
                "status": 422,
                "code": "invalid_input",
                "recovery": "Correct the payload using inputSchema, then validate before retrying."
              },
              {
                "status": 503,
                "code": "dependency_unavailable",
                "recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
              },
              {
                "status": 409,
                "code": "state_conflict",
                "recovery": "Read the current resource state, reconcile the intended change, and retry only if still valid."
              }
            ],
            "verify": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "examples": [
              {
                "input": {
                  "organizationId": "organization_example",
                  "confirmation": "ERASE"
                },
                "expected": "A response matching the published outputSchema for organizations.data.erase."
              }
            ],
            "recovery": {
              "mode": "irreversible",
              "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
            },
            "contractSource": "derived-action-metadata"
          },
          "documentation": {
            "example_input": {
              "organizationId": "organization_example",
              "confirmation": "ERASE"
            },
            "cli_example": [
              "topolo actions --service topolo-blog --json",
              "topolo actions get <action-id> --json",
              "topolo actions validate <action-id> --data @payload.json --json",
              "topolo actions plan <action-id> --data @payload.json --json",
              "topolo actions call <action-id> --data @payload.json --confirm --json"
            ],
            "http_example": {
              "method": "DELETE",
              "path": "/api/organizations/organization_example/data",
              "body": null
            },
            "effects": "Changes organization state in the selected Topolo resource context.",
            "verification": [
              "Validate the response against outputSchema and re-read the affected resource to confirm the intended state."
            ],
            "recovery": [
              {
                "mode": "irreversible",
                "instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
              },
              "401 authentication_required: Authenticate again or provide a valid Topolo API key.",
              "403 permission_denied: Grant the credential permission privacy:write and the required resource binding.",
              "429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
              "422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
              "503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID.",
              "409 state_conflict: Read the current resource state, reconcile the intended change, and retry only if still valid."
            ],
            "docs_url": "https://docs.topolo.app/reference/actions?service=topolo-blog&action=organizations.data.erase",
            "resource": {
              "kind": "organization",
              "idPath": "$.id"
            },
            "next_action_ids": [],
            "rollback_action_id": null
          },
          "implementation": {
            "status": "implemented",
            "route_key": "DELETE /api/organizations/*/data",
            "evidence": "Matched to a served route extracted from canonical staging source."
          }
        }
      ],
      "action_coverage": {
        "status": "ok",
        "served_routes": 44,
        "matched_actions": 37,
        "declared_unserved_actions": [
          "DELETE /api/saved-searches/*",
          "DELETE /api/templates/*",
          "POST /api/articles/*/review/approve",
          "POST /api/articles/*/review/changes-requested",
          "POST /api/articles/*/review/request"
        ],
        "coverage_excluded_actions": [],
        "uncatalogued_routes": [
          {
            "key": "DELETE /api/saved-searches",
            "method": "DELETE",
            "path": "/api/saved-searches",
            "source": "apps/api/src/editorial-routes.ts",
            "target": "api"
          },
          {
            "key": "DELETE /api/templates",
            "method": "DELETE",
            "path": "/api/templates",
            "source": "apps/api/src/editorial-routes.ts",
            "target": "api"
          },
          {
            "key": "GET /api/public/publications",
            "method": "GET",
            "path": "/api/public/publications",
            "source": "apps/api/src/article-routes.ts",
            "target": "api"
          },
          {
            "key": "GET /api/public/publications/*/*",
            "method": "GET",
            "path": "/api/public/publications/{segment1}/{segment2}",
            "source": "apps/api/src/article-routes.ts",
            "target": "api"
          },
          {
            "key": "POST /api/articles/*/review",
            "method": "POST",
            "path": "/api/articles/{segment1}/review",
            "source": "apps/api/src/article-routes.ts",
            "target": "api"
          }
        ],
        "ignored_routes": 2,
        "configured_exclusions": 3,
        "configuration_findings": [
          "GET /api/public/media/*: exclusion matches no served route",
          "GET /api/public/publications/*/articles: exclusion matches no served route",
          "GET /api/public/publications/*/articles/*: exclusion matches no served route"
        ],
        "notes": []
      },
      "runtime_contract_audit": {
        "status": "verified",
        "actions": 42,
        "contracts": 42,
        "contract_module": "topolo.action-contracts.mjs",
        "validator_sources": [
          "apps/api/src/worker.ts"
        ],
        "authorization_sources": [
          "apps/api/src/worker.ts"
        ],
        "findings": []
      }
    }
  ],
  "mobile_contracts": [],
  "package_manifests": [],
  "deployment_configs": [],
  "source_signals": {
    "api_routes": [
      {
        "method": "ALL",
        "path": "*",
        "source_path": "apps/TopoloBlog/apps/api/src/worker.ts"
      },
      {
        "method": "LITERAL",
        "path": "/api/health",
        "source_path": "apps/TopoloBlog/apps/api/src/worker.ts"
      },
      {
        "method": "LITERAL",
        "path": "/api/app-identity",
        "source_path": "apps/TopoloBlog/apps/api/src/worker.ts"
      },
      {
        "method": "LITERAL",
        "path": "/api/widget",
        "source_path": "apps/TopoloBlog/apps/api/src/worker.ts"
      },
      {
        "method": "LITERAL",
        "path": "/api/bootstrap",
        "source_path": "apps/TopoloBlog/apps/api/src/worker.ts"
      }
    ],
    "ui_routes": [
      {
        "path": "/getting-started",
        "source_path": "apps/TopoloBlog/apps/web/src/App.tsx"
      },
      {
        "path": "/articles",
        "source_path": "apps/TopoloBlog/apps/web/src/app-routes.tsx"
      },
      {
        "path": "/calendar",
        "source_path": "apps/TopoloBlog/apps/web/src/app-routes.tsx"
      },
      {
        "path": "/media",
        "source_path": "apps/TopoloBlog/apps/web/src/app-routes.tsx"
      },
      {
        "path": "/templates",
        "source_path": "apps/TopoloBlog/apps/web/src/app-routes.tsx"
      },
      {
        "path": "/publications",
        "source_path": "apps/TopoloBlog/apps/web/src/app-routes.tsx"
      },
      {
        "path": "/analytics",
        "source_path": "apps/TopoloBlog/apps/web/src/app-routes.tsx"
      },
      {
        "path": "/settings",
        "source_path": "apps/TopoloBlog/apps/web/src/app-routes.tsx"
      },
      {
        "path": "/settings/:section",
        "source_path": "apps/TopoloBlog/apps/web/src/app-routes.tsx"
      },
      {
        "path": "/articles/:articleId",
        "source_path": "apps/TopoloBlog/apps/web/src/app-routes.tsx"
      },
      {
        "path": "/getting-started",
        "source_path": "apps/TopoloBlog/apps/web/src/app-routes.tsx"
      },
      {
        "path": "/blog/identity-is-operating-infrastructure",
        "source_path": "apps/TopoloBlog/apps/web/src/routes/AnalyticsRoute.tsx"
      }
    ],
    "test_cases": [],
    "database_tables": []
  },
  "documentation": {
    "declared_paths": [
      "internal/apps/blog",
      "applications/blog"
    ],
    "present_paths": [
      "internal/apps/blog",
      "applications/blog"
    ],
    "missing_paths": [],
    "human_reference": "/systems/topolo-blog",
    "machine_reference": "/machine/systems/topolo-blog.json",
    "action_examples": 42,
    "action_schemas": 42
  },
  "source_findings": [
    {
      "type": "declared_unserved_actions",
      "source_path": "apps/TopoloBlog/topolo.app.json",
      "detail": [
        "DELETE /api/saved-searches/*",
        "DELETE /api/templates/*",
        "POST /api/articles/*/review/approve",
        "POST /api/articles/*/review/changes-requested",
        "POST /api/articles/*/review/request"
      ]
    },
    {
      "type": "uncatalogued_routes",
      "source_path": "apps/TopoloBlog/topolo.app.json",
      "detail": [
        {
          "key": "DELETE /api/saved-searches",
          "method": "DELETE",
          "path": "/api/saved-searches",
          "source": "apps/api/src/editorial-routes.ts",
          "target": "api"
        },
        {
          "key": "DELETE /api/templates",
          "method": "DELETE",
          "path": "/api/templates",
          "source": "apps/api/src/editorial-routes.ts",
          "target": "api"
        },
        {
          "key": "GET /api/public/publications",
          "method": "GET",
          "path": "/api/public/publications",
          "source": "apps/api/src/article-routes.ts",
          "target": "api"
        },
        {
          "key": "GET /api/public/publications/*/*",
          "method": "GET",
          "path": "/api/public/publications/{segment1}/{segment2}",
          "source": "apps/api/src/article-routes.ts",
          "target": "api"
        },
        {
          "key": "POST /api/articles/*/review",
          "method": "POST",
          "path": "/api/articles/{segment1}/review",
          "source": "apps/api/src/article-routes.ts",
          "target": "api"
        }
      ]
    },
    {
      "type": "action_coverage_configuration",
      "source_path": "apps/TopoloBlog/topolo.app.json",
      "detail": [
        "GET /api/public/media/*: exclusion matches no served route",
        "GET /api/public/publications/*/articles: exclusion matches no served route",
        "GET /api/public/publications/*/articles/*: exclusion matches no served route"
      ]
    }
  ]
}