{
  "feature": "subscription-billing",
  "version": "1.0.0",
  "description": "Recurring subscription lifecycle with plan tiers, billing cycles, trials, proration, dunning retries, and cancellation handling.",
  "category": "payment",
  "tags": [
    "subscriptions",
    "recurring-billing",
    "plans",
    "trials",
    "dunning",
    "proration",
    "saas"
  ],
  "fields": [
    {
      "name": "subscription_id",
      "type": "text",
      "label": "Subscription ID",
      "required": true,
      "validation": [
        {
          "type": "pattern",
          "value": "^sub_[a-zA-Z0-9]+$",
          "message": "Subscription ID must match the required format"
        }
      ]
    },
    {
      "name": "customer_id",
      "type": "text",
      "label": "Customer ID",
      "required": true
    },
    {
      "name": "plan_id",
      "type": "select",
      "label": "Plan",
      "required": true,
      "options": [
        {
          "value": "free",
          "label": "Free"
        },
        {
          "value": "starter",
          "label": "Starter"
        },
        {
          "value": "pro",
          "label": "Pro"
        },
        {
          "value": "enterprise",
          "label": "Enterprise"
        }
      ]
    },
    {
      "name": "billing_cycle",
      "type": "select",
      "label": "Billing Cycle",
      "required": true,
      "options": [
        {
          "value": "monthly",
          "label": "Monthly"
        },
        {
          "value": "annual",
          "label": "Annual"
        }
      ]
    },
    {
      "name": "trial_ends_at",
      "type": "datetime",
      "label": "Trial End Date",
      "required": false
    },
    {
      "name": "current_period_start",
      "type": "datetime",
      "label": "Current Period Start",
      "required": true
    },
    {
      "name": "current_period_end",
      "type": "datetime",
      "label": "Current Period End",
      "required": true
    },
    {
      "name": "status",
      "type": "select",
      "label": "Subscription Status",
      "required": true,
      "options": [
        {
          "value": "trialing",
          "label": "Trialing"
        },
        {
          "value": "active",
          "label": "Active"
        },
        {
          "value": "past_due",
          "label": "Past Due"
        },
        {
          "value": "canceled",
          "label": "Canceled"
        },
        {
          "value": "unpaid",
          "label": "Unpaid"
        }
      ]
    },
    {
      "name": "cancel_at_period_end",
      "type": "boolean",
      "label": "Cancel at Period End",
      "required": false,
      "default": false
    },
    {
      "name": "payment_method_id",
      "type": "text",
      "label": "Payment Method",
      "required": false
    },
    {
      "name": "dunning_attempts",
      "type": "number",
      "label": "Failed Payment Retry Count",
      "required": false,
      "default": 0,
      "validation": [
        {
          "type": "max",
          "value": 3,
          "message": "Dunning attempts cannot exceed 3"
        }
      ]
    }
  ],
  "states": {
    "field": "status",
    "values": [
      {
        "name": "trialing",
        "description": "Customer is on a free trial period (default 14 days)",
        "initial": true
      },
      {
        "name": "active",
        "description": "Subscription is active with successful recurring payments"
      },
      {
        "name": "past_due",
        "description": "Payment failed, dunning retries in progress"
      },
      {
        "name": "canceled",
        "description": "Subscription canceled by customer or system",
        "terminal": true
      },
      {
        "name": "unpaid",
        "description": "All dunning retries exhausted, subscription suspended",
        "terminal": true
      }
    ],
    "transitions": [
      {
        "from": "trialing",
        "to": "active",
        "actor": "system",
        "description": "Trial period ends and first payment succeeds",
        "condition": "Valid payment method on file and charge succeeds"
      },
      {
        "from": "trialing",
        "to": "canceled",
        "actor": "customer",
        "description": "Customer cancels during trial"
      },
      {
        "from": "active",
        "to": "past_due",
        "actor": "system",
        "description": "Recurring payment fails",
        "condition": "Payment charge returns a failure"
      },
      {
        "from": "past_due",
        "to": "active",
        "actor": "system",
        "description": "Retry payment succeeds during dunning window",
        "condition": "Payment retry succeeds within 3 attempts over 7 days"
      },
      {
        "from": "past_due",
        "to": "unpaid",
        "actor": "system",
        "description": "All dunning retries exhausted",
        "condition": "3 retries failed over 7-day window"
      },
      {
        "from": "active",
        "to": "canceled",
        "actor": "customer",
        "description": "Customer cancels subscription (immediate or end-of-period)"
      },
      {
        "from": "unpaid",
        "to": "active",
        "actor": "system",
        "description": "Customer updates payment method and payment succeeds"
      }
    ]
  },
  "rules": {
    "trial_default_duration": {
      "description": "Free trial defaults to 14 days from subscription creation. Trial can be skipped if customer opts out or plan does not offer trials.\n"
    },
    "proration_on_plan_change": {
      "description": "When upgrading or downgrading mid-cycle, prorate the charge based on remaining days in the current billing period. Upgrades charge the difference immediately; downgrades credit toward next invoice.\n"
    },
    "dunning_retry_schedule": {
      "description": "Failed payments are retried 3 times over 7 days (day 1, day 3, day 7). Each retry sends an email notification to the customer.\n"
    },
    "grace_period": {
      "description": "After entering past_due status, the customer retains access for the remainder of the dunning window (7 days) before suspension.\n"
    },
    "cancellation_modes": {
      "description": "Immediate cancellation revokes access at once. End-of-period cancellation sets cancel_at_period_end to true and revokes access when the current billing period expires.\n"
    },
    "annual_discount": {
      "description": "Annual billing cycle applies a discount (typically 16-20% off the equivalent monthly rate). The exact discount is configured per plan.\n"
    },
    "one_subscription_per_customer": {
      "description": "A customer may hold only one active subscription at a time. Upgrading or downgrading modifies the existing subscription.\n"
    }
  },
  "outcomes": {
    "subscription_created": {
      "priority": 1,
      "given": [
        "customer selects a plan and billing cycle",
        "customer provides a valid payment method"
      ],
      "then": [
        {
          "action": "create_record",
          "type": "subscription",
          "target": "subscription",
          "description": "New subscription record created with trial or active status"
        },
        {
          "action": "set_field",
          "target": "status",
          "value": "trialing",
          "when": "plan_id != \"free\""
        },
        {
          "action": "set_field",
          "target": "trial_ends_at",
          "description": "Set to 14 days from now"
        },
        {
          "action": "emit_event",
          "event": "subscription.created",
          "payload": [
            "subscription_id",
            "customer_id",
            "plan_id",
            "billing_cycle",
            "status"
          ]
        }
      ],
      "result": "Subscription created, trial period begins (or active if no trial)"
    },
    "trial_converted": {
      "priority": 2,
      "given": [
        {
          "field": "status",
          "operator": "eq",
          "value": "trialing"
        },
        "trial_ends_at has passed",
        "valid payment method on file"
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "status",
          "from": "trialing",
          "to": "active"
        },
        {
          "action": "set_field",
          "target": "current_period_start",
          "description": "Set to trial end date"
        },
        {
          "action": "emit_event",
          "event": "subscription.renewed",
          "payload": [
            "subscription_id",
            "plan_id",
            "billing_cycle"
          ]
        }
      ],
      "result": "Trial converts to paid subscription, first charge processed"
    },
    "subscription_upgraded": {
      "priority": 3,
      "given": [
        {
          "field": "status",
          "operator": "eq",
          "value": "active"
        },
        "customer selects a higher-tier plan"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "plan_id",
          "description": "Updated to new plan"
        },
        {
          "action": "set_field",
          "target": "proration_amount",
          "description": "Calculated based on remaining days in current period"
        },
        {
          "action": "emit_event",
          "event": "subscription.upgraded",
          "payload": [
            "subscription_id",
            "old_plan",
            "new_plan",
            "proration_amount"
          ]
        }
      ],
      "result": "Plan upgraded, prorated charge applied immediately"
    },
    "subscription_downgraded": {
      "priority": 4,
      "given": [
        {
          "field": "status",
          "operator": "eq",
          "value": "active"
        },
        "customer selects a lower-tier plan"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "plan_id",
          "description": "Scheduled to change at next billing period"
        },
        {
          "action": "emit_event",
          "event": "subscription.downgraded",
          "payload": [
            "subscription_id",
            "old_plan",
            "new_plan",
            "effective_date"
          ]
        }
      ],
      "result": "Downgrade scheduled for next billing period, credit applied"
    },
    "subscription_renewed": {
      "priority": 5,
      "given": [
        {
          "field": "status",
          "operator": "eq",
          "value": "active"
        },
        "current_period_end has passed",
        "payment charge succeeds"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "current_period_start",
          "description": "Set to previous period end"
        },
        {
          "action": "set_field",
          "target": "current_period_end",
          "description": "Advanced by one billing cycle"
        },
        {
          "action": "emit_event",
          "event": "subscription.renewed",
          "payload": [
            "subscription_id",
            "plan_id",
            "amount_charged"
          ]
        }
      ],
      "result": "Subscription renewed for a new billing period"
    },
    "payment_failed": {
      "priority": 6,
      "given": [
        {
          "field": "status",
          "operator": "eq",
          "value": "active"
        },
        "recurring payment charge fails"
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "status",
          "from": "active",
          "to": "past_due"
        },
        {
          "action": "set_field",
          "target": "dunning_attempts",
          "value": 1
        },
        {
          "action": "emit_event",
          "event": "subscription.payment_failed",
          "payload": [
            "subscription_id",
            "customer_id",
            "attempt_number",
            "next_retry_date"
          ]
        },
        {
          "action": "notify",
          "channel": "email",
          "description": "Notify customer of failed payment and upcoming retry"
        }
      ],
      "result": "Subscription enters past_due, dunning process begins"
    },
    "dunning_retry_succeeded": {
      "priority": 7,
      "given": [
        {
          "field": "status",
          "operator": "eq",
          "value": "past_due"
        },
        "payment retry succeeds within dunning window"
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "status",
          "from": "past_due",
          "to": "active"
        },
        {
          "action": "set_field",
          "target": "dunning_attempts",
          "value": 0
        },
        {
          "action": "emit_event",
          "event": "subscription.renewed",
          "payload": [
            "subscription_id",
            "plan_id",
            "amount_charged"
          ]
        }
      ],
      "result": "Payment recovered, subscription reactivated"
    },
    "dunning_exhausted": {
      "priority": 8,
      "error": "SUBSCRIPTION_DUNNING_EXHAUSTED",
      "given": [
        {
          "field": "status",
          "operator": "eq",
          "value": "past_due"
        },
        {
          "field": "dunning_attempts",
          "operator": "gte",
          "value": 3
        }
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "status",
          "from": "past_due",
          "to": "unpaid"
        },
        {
          "action": "emit_event",
          "event": "subscription.payment_failed",
          "payload": [
            "subscription_id",
            "customer_id",
            {
              "final_attempt": true
            }
          ]
        },
        {
          "action": "notify",
          "channel": "email",
          "description": "Final notice that subscription is suspended"
        }
      ],
      "result": "All retry attempts failed, subscription suspended"
    },
    "subscription_canceled": {
      "priority": 9,
      "given": [
        "customer requests cancellation",
        {
          "any": [
            {
              "field": "status",
              "operator": "eq",
              "value": "active"
            },
            {
              "field": "status",
              "operator": "eq",
              "value": "trialing"
            }
          ]
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "cancel_at_period_end",
          "value": true,
          "description": "For end-of-period cancellation"
        },
        {
          "action": "emit_event",
          "event": "subscription.canceled",
          "payload": [
            "subscription_id",
            "customer_id",
            "effective_date",
            "cancel_mode"
          ]
        }
      ],
      "result": "Subscription marked for cancellation",
      "error": "SUBSCRIPTION_CANCELED"
    },
    "trial_ending_notification": {
      "priority": 10,
      "given": [
        {
          "field": "status",
          "operator": "eq",
          "value": "trialing"
        },
        "trial_ends_at is within 3 days"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "subscription.trial_ending",
          "payload": [
            "subscription_id",
            "customer_id",
            "trial_ends_at"
          ]
        },
        {
          "action": "notify",
          "channel": "email",
          "description": "Remind customer that trial is ending soon"
        }
      ],
      "result": "Customer notified of upcoming trial expiration"
    },
    "no_payment_method": {
      "priority": 1,
      "error": "SUBSCRIPTION_NO_PAYMENT_METHOD",
      "given": [
        "customer attempts to subscribe to a paid plan",
        {
          "field": "payment_method_id",
          "operator": "not_exists"
        }
      ],
      "then": [
        {
          "action": "notify",
          "channel": "ui",
          "description": "Prompt customer to add a payment method"
        }
      ],
      "result": "Subscription cannot proceed without a valid payment method"
    }
  },
  "errors": [
    {
      "code": "SUBSCRIPTION_NO_PAYMENT_METHOD",
      "message": "A valid payment method is required to subscribe to a paid plan.",
      "status": 400
    },
    {
      "code": "SUBSCRIPTION_DUNNING_EXHAUSTED",
      "message": "All payment retry attempts have been exhausted. Please update your payment method.",
      "status": 422
    },
    {
      "code": "SUBSCRIPTION_ALREADY_ACTIVE",
      "message": "An active subscription already exists. Please modify or cancel the current subscription.",
      "status": 409
    },
    {
      "code": "SUBSCRIPTION_PLAN_INVALID",
      "message": "The selected plan is not available for this account.",
      "status": 400
    },
    {
      "code": "SUBSCRIPTION_CANCELED",
      "message": "This subscription has been canceled and cannot be modified.",
      "status": 403
    }
  ],
  "events": [
    {
      "name": "subscription.created",
      "description": "New subscription created",
      "payload": [
        "subscription_id",
        "customer_id",
        "plan_id",
        "billing_cycle",
        "status"
      ]
    },
    {
      "name": "subscription.upgraded",
      "description": "Subscription plan upgraded to a higher tier",
      "payload": [
        "subscription_id",
        "old_plan",
        "new_plan",
        "proration_amount"
      ]
    },
    {
      "name": "subscription.downgraded",
      "description": "Subscription plan downgraded to a lower tier",
      "payload": [
        "subscription_id",
        "old_plan",
        "new_plan",
        "effective_date"
      ]
    },
    {
      "name": "subscription.canceled",
      "description": "Subscription cancellation initiated",
      "payload": [
        "subscription_id",
        "customer_id",
        "effective_date",
        "cancel_mode"
      ]
    },
    {
      "name": "subscription.renewed",
      "description": "Subscription successfully renewed for a new period",
      "payload": [
        "subscription_id",
        "plan_id",
        "amount_charged"
      ]
    },
    {
      "name": "subscription.payment_failed",
      "description": "Recurring payment failed, dunning process initiated or continued",
      "payload": [
        "subscription_id",
        "customer_id",
        "attempt_number",
        "next_retry_date"
      ]
    },
    {
      "name": "subscription.trial_ending",
      "description": "Trial period ending within 3 days",
      "payload": [
        "subscription_id",
        "customer_id",
        "trial_ends_at"
      ]
    }
  ],
  "related": [
    {
      "feature": "payment-methods",
      "type": "required",
      "reason": "Subscription billing requires a saved payment method for recurring charges"
    },
    {
      "feature": "invoicing-payments",
      "type": "required",
      "reason": "Each billing cycle generates an invoice"
    },
    {
      "feature": "currency-conversion",
      "type": "optional",
      "reason": "Multi-currency subscription pricing"
    },
    {
      "feature": "refunds-returns",
      "type": "optional",
      "reason": "Prorated refunds on mid-cycle cancellations"
    }
  ],
  "agi": {
    "goals": [
      {
        "id": "reliable_subscription_billing",
        "description": "Recurring subscription lifecycle with plan tiers, billing cycles, trials, proration, dunning retries, and cancellation handling.",
        "success_metrics": [
          {
            "metric": "policy_violation_rate",
            "target": "0%",
            "measurement": "Operations that violate defined policies"
          },
          {
            "metric": "audit_completeness",
            "target": "100%",
            "measurement": "All decisions have complete audit trails"
          }
        ],
        "constraints": [
          {
            "type": "regulatory",
            "description": "All operations must be auditable and traceable",
            "negotiable": false
          }
        ]
      }
    ],
    "autonomy": {
      "level": "supervised",
      "human_checkpoints": [
        "before transitioning to a terminal state"
      ],
      "escalation_triggers": [
        "error_rate > 5",
        "consecutive_failures > 3"
      ]
    },
    "safety": {
      "action_permissions": [
        {
          "action": "subscription_created",
          "permission": "supervised"
        },
        {
          "action": "trial_converted",
          "permission": "autonomous"
        },
        {
          "action": "subscription_upgraded",
          "permission": "autonomous"
        },
        {
          "action": "subscription_downgraded",
          "permission": "autonomous"
        },
        {
          "action": "subscription_renewed",
          "permission": "autonomous"
        },
        {
          "action": "payment_failed",
          "permission": "autonomous"
        },
        {
          "action": "dunning_retry_succeeded",
          "permission": "autonomous"
        },
        {
          "action": "dunning_exhausted",
          "permission": "autonomous"
        },
        {
          "action": "subscription_canceled",
          "permission": "supervised"
        },
        {
          "action": "trial_ending_notification",
          "permission": "autonomous"
        },
        {
          "action": "no_payment_method",
          "permission": "autonomous"
        }
      ]
    },
    "tradeoffs": [
      {
        "prefer": "accuracy",
        "over": "speed",
        "reason": "financial transactions must be precise and auditable"
      }
    ],
    "verification": {
      "invariants": [
        "error messages never expose internal system details",
        "state transitions follow the defined state machine — no illegal transitions"
      ]
    },
    "coordination": {
      "protocol": "request_response",
      "consumes": [
        {
          "capability": "payment_methods",
          "from": "payment-methods",
          "fallback": "fail"
        },
        {
          "capability": "invoicing_payments",
          "from": "invoicing-payments",
          "fallback": "fail"
        }
      ]
    }
  }
}