{
  "spec_version": "2.0.0",
  "project": "cre8-platform-ui-unified",
  "generated_at_utc": "2026-04-05T05:34:40Z",
  "supersedes_files": [
    "ui/endpoints.json",
    "ui/endpoints_flat.json",
    "ui/endpoints_schema.json"
  ],
  "source_documents": {
    "rich_spec": "ui/endpoints.json",
    "flat_spec": "ui/endpoints_flat.json",
    "schema": "ui/endpoints_schema.json"
  },
  "global_contracts": {
    "response_envelope": {
      "success_shape": {
        "data": "object|array",
        "meta": {
          "envelope_version": "string",
          "timestamp_utc": "ISO-8601"
        }
      },
      "error_shape": {
        "error": {
          "code": "string",
          "message": "string",
          "details": "array|object",
          "request_id": "string"
        },
        "meta": {
          "envelope_version": "string",
          "timestamp_utc": "ISO-8601"
        }
      }
    },
    "http_error_patterns": [
      {
        "status": 401,
        "meaning": "invalid credentials/auth invalid"
      },
      {
        "status": 403,
        "meaning": "forbidden/permission/CSRF/policy guard"
      },
      {
        "status": 404,
        "meaning": "resource not found or not visible"
      },
      {
        "status": 409,
        "meaning": "conflict (e.g., existing owner)"
      },
      {
        "status": 422,
        "meaning": "validation failed"
      }
    ],
    "ui_state_model": [
      "idle",
      "loading",
      "validating",
      "submitting",
      "success",
      "empty",
      "forbidden",
      "not_found",
      "validation_error",
      "server_error"
    ]
  },
  "description_templates": {
    "general_principles": [
      "Prefer clean, accessible layouts with consistent spacing and clear hierarchy.",
      "Keep states explicit: loading, empty, success, validation_error, forbidden, not_found, server_error.",
      "Use concise, human microcopy that explains next action and never blames the user."
    ],
    "html_structure_seed": {
      "app_shell": "Header + content container + optional contextual sidebar.",
      "form_page": "Title block, helper text, grouped fields, primary CTA, secondary escape action.",
      "list_page": "Filter/sort row, result list or table, paging controls, empty/error blocks.",
      "detail_page": "Primary content panel, metadata strip, contextual actions, related activity section.",
      "moderation_page": "Decision context, action controls, reason capture, confirmation feedback."
    },
    "design_tone_tokens": {
      "voice": "friendly, concise, confident",
      "visual": "clean, modern, readable",
      "interaction": "predictable, responsive, low-friction"
    }
  },
  "schema_reference": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://cre8.pw/schemas/page-spec-entry.schema.json",
    "title": "PageSpecEntry",
    "type": "object",
    "additionalProperties": false,
    "required": [
      "page_id",
      "sprint",
      "url",
      "method",
      "persona",
      "purpose",
      "required_fields",
      "api_calls",
      "success_ux",
      "error_ux",
      "figma_data"
    ],
    "properties": {
      "page_id": {
        "type": "string",
        "pattern": "^[a-z0-9_]+_v[0-9]+$"
      },
      "sprint": {
        "type": "string",
        "pattern": "^S[0-9]+$"
      },
      "url": {
        "type": "string",
        "pattern": "^/.*"
      },
      "method": {
        "type": "string",
        "enum": [
          "GET",
          "POST",
          "PUT",
          "PATCH",
          "DELETE"
        ]
      },
      "persona": {
        "type": "array",
        "minItems": 1,
        "items": {
          "type": "string",
          "minLength": 1
        },
        "uniqueItems": true
      },
      "purpose": {
        "type": "string",
        "minLength": 5
      },
      "required_fields": {
        "type": "array",
        "items": {
          "$ref": "#/$defs/requiredField"
        }
      },
      "api_calls": {
        "type": "array",
        "minItems": 1,
        "items": {
          "$ref": "#/$defs/apiCall"
        }
      },
      "success_ux": {
        "type": "array",
        "minItems": 1,
        "items": {
          "type": "string",
          "minLength": 1
        }
      },
      "error_ux": {
        "type": "array",
        "minItems": 1,
        "items": {
          "type": "string",
          "minLength": 1
        }
      },
      "figma_data": {
        "type": "object",
        "minProperties": 1,
        "additionalProperties": true
      }
    },
    "$defs": {
      "requiredField": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "type",
          "required"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "type": {
            "type": "string",
            "enum": [
              "string",
              "integer",
              "number",
              "boolean",
              "enum",
              "array[string]",
              "array[number]",
              "array[object]",
              "object"
            ]
          },
          "required": {
            "type": "boolean"
          },
          "format": {
            "type": "string"
          },
          "values": {
            "type": "array",
            "items": {
              "type": [
                "string",
                "number",
                "boolean"
              ]
            },
            "minItems": 1
          },
          "default": {},
          "min_length": {
            "type": "integer",
            "minimum": 0
          },
          "max_length": {
            "type": "integer",
            "minimum": 0
          },
          "conditional_required_when": {
            "type": "string"
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "type": {
                  "const": "enum"
                }
              },
              "required": [
                "type"
              ]
            },
            "then": {
              "required": [
                "values"
              ]
            }
          }
        ]
      },
      "apiCall": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "method",
          "endpoint",
          "success_statuses"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "method": {
            "type": "string",
            "enum": [
              "GET",
              "POST",
              "PUT",
              "PATCH",
              "DELETE",
              "OPTIONS"
            ]
          },
          "endpoint": {
            "type": "string",
            "pattern": "^/.*"
          },
          "query_params": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "uniqueItems": true
          },
          "request_body": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "uniqueItems": true
              }
            ]
          },
          "success_statuses": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "integer",
              "minimum": 100,
              "maximum": 599
            },
            "uniqueItems": true
          },
          "error_statuses": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 100,
              "maximum": 599
            },
            "uniqueItems": true
          },
          "success_payload_keys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "uniqueItems": true
          },
          "current_backend_status": {
            "type": "string"
          },
          "sensitive_response_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "uniqueItems": true
          }
        }
      }
    }
  },
  "sprints": [
    {
      "sprint_id": "S1",
      "name": "Auth + Discovery",
      "goal": "Enable entry, authentication, and read-only feed navigation",
      "pages": [
        {
          "page_id": "auth_login_v1",
          "url": "/login",
          "method": "GET",
          "persona": [
            "owner_admin"
          ],
          "purpose": "Email/password login for owner sessions",
          "required_fields": [
            {
              "name": "email",
              "type": "string",
              "required": true,
              "format": "email",
              "ui_component": "text_input",
              "placeholder": "you@company.com",
              "validation_messages": {
                "required": "Email is required",
                "invalid_format": "Enter a valid email address"
              }
            },
            {
              "name": "password",
              "type": "string",
              "required": true,
              "ui_component": "password_input",
              "placeholder": "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
              "validation_messages": {
                "required": "Password is required"
              }
            }
          ],
          "api_calls": [
            {
              "name": "owner_login",
              "method": "POST",
              "endpoint": "/api/auth/login",
              "request_body": {
                "email": "string",
                "password": "string"
              },
              "success_statuses": [
                200
              ],
              "error_statuses": [
                401,
                422
              ],
              "success_payload_keys": [
                "data.access_token",
                "data.refresh_token",
                "data.expires_in"
              ]
            }
          ],
          "success_ux": [
            "Show success toast: 'Signed in'",
            "Persist session tokens per auth strategy",
            "Redirect to /feed"
          ],
          "error_ux": [
            "Map 422 details to field-level helper text",
            "Show 401 banner: 'Invalid credentials'",
            "Keep email populated; clear password"
          ],
          "figma_data_attributes": {
            "surface": "public_auth",
            "primary_cta": "Sign in",
            "secondary_cta": "Use API key",
            "tracking_events": [
              "login_submit",
              "login_success",
              "login_failure"
            ],
            "layout_tokens": [
              "form_single_column",
              "max_width_sm"
            ]
          },
          "acceptance_criteria": [
            "Submit disabled until required fields are non-empty",
            "API errors display without page crash",
            "Keyboard Enter submits form"
          ]
        },
        {
          "page_id": "auth_key_login_v1",
          "url": "/key-login",
          "method": "GET",
          "persona": [
            "key_operator"
          ],
          "purpose": "Authenticate with key_id + api_key",
          "required_fields": [
            {
              "name": "key_id",
              "type": "string",
              "required": true,
              "ui_component": "text_input",
              "placeholder": "32-char key id"
            },
            {
              "name": "api_key",
              "type": "string",
              "required": true,
              "ui_component": "secret_input",
              "placeholder": "cre8k_...",
              "security_hints": [
                "masked_by_default",
                "copy_protection_optional"
              ]
            }
          ],
          "api_calls": [
            {
              "name": "key_login",
              "method": "POST",
              "endpoint": "/api/auth/key-login",
              "request_body": {
                "key_id": "string",
                "api_key": "string"
              },
              "success_statuses": [
                200
              ],
              "error_statuses": [
                401,
                422
              ]
            }
          ],
          "success_ux": [
            "Route to /feed with gateway auth context",
            "Display active scope/permissions summary chip row"
          ],
          "error_ux": [
            "401 generic auth failure message",
            "422 required-field highlights"
          ],
          "figma_data_attributes": {
            "surface": "public_auth",
            "primary_cta": "Sign in with key",
            "tracking_events": [
              "key_login_submit",
              "key_login_success",
              "key_login_failure"
            ],
            "component_variants": [
              "secret_input_reveal_toggle",
              "inline_security_tip"
            ]
          },
          "acceptance_criteria": [
            "No plaintext api_key shown after submit",
            "Error states are non-destructive to user input"
          ]
        },
        {
          "page_id": "auth_owner_signup_v1",
          "url": "/signup-owner",
          "method": "GET",
          "persona": [
            "first_owner"
          ],
          "purpose": "Create owner account",
          "required_fields": [
            {
              "name": "email",
              "type": "string",
              "required": true,
              "format": "email",
              "ui_component": "text_input"
            },
            {
              "name": "password",
              "type": "string",
              "required": true,
              "min_length": 12,
              "ui_component": "password_input"
            }
          ],
          "api_calls": [
            {
              "name": "register_owner",
              "method": "POST",
              "endpoint": "/console/owners",
              "request_body": {
                "email": "string",
                "password": "string"
              },
              "success_statuses": [
                201
              ],
              "error_statuses": [
                409,
                422
              ]
            }
          ],
          "success_ux": [
            "Show owner created confirmation with owner_id",
            "CTA: Continue to /login"
          ],
          "error_ux": [
            "409 owner conflict banner",
            "422 per-field validation details"
          ],
          "figma_data_attributes": {
            "surface": "public_auth",
            "primary_cta": "Create owner",
            "helper_blocks": [
              "password_policy",
              "security_notice"
            ],
            "tracking_events": [
              "owner_signup_submit",
              "owner_signup_success",
              "owner_signup_conflict"
            ]
          },
          "acceptance_criteria": [
            "Password policy hint visible before typing",
            "Conflict error uses dedicated design state"
          ]
        },
        {
          "page_id": "feed_index_v1",
          "url": "/feed",
          "method": "GET",
          "persona": [
            "owner_admin",
            "key_operator",
            "reader"
          ],
          "purpose": "Browse visible posts with cursor pagination",
          "required_fields": [],
          "query_controls": [
            {
              "name": "scope",
              "type": "enum",
              "values": [
                "public",
                "delegated"
              ],
              "default": "delegated",
              "ui_component": "segmented_control"
            },
            {
              "name": "limit",
              "type": "number",
              "default": 50,
              "constraints": {
                "min": 1,
                "max": 200
              },
              "ui_component": "hidden_or_advanced"
            },
            {
              "name": "cursor",
              "type": "string",
              "required": false,
              "ui_component": "pagination_state"
            }
          ],
          "api_calls": [
            {
              "name": "list_feed",
              "method": "GET",
              "endpoint": "/api/feed",
              "query_params": [
                "scope",
                "limit",
                "cursor"
              ],
              "success_statuses": [
                200
              ]
            }
          ],
          "success_ux": [
            "Render post cards",
            "Show Load more when paging.has_more = true",
            "Persist selected scope in URL"
          ],
          "error_ux": [
            "Retry inline block on network/server error",
            "Empty illustration + CTA to create post if no data"
          ],
          "figma_data_attributes": {
            "surface": "gateway",
            "list_item_schema": [
              "id",
              "title",
              "body",
              "visibility_scope",
              "state",
              "author_id",
              "created_at_utc"
            ],
            "tracking_events": [
              "feed_loaded",
              "feed_scope_changed",
              "feed_load_more_clicked"
            ]
          },
          "acceptance_criteria": [
            "Cursor pagination does not duplicate cards",
            "Scope change resets cursor"
          ]
        }
      ]
    },
    {
      "sprint_id": "S2",
      "name": "Posts + Comments",
      "goal": "Enable content creation, detail, editing, and commenting",
      "pages": [
        {
          "page_id": "post_create_gateway_v1",
          "url": "/posts/new",
          "method": "GET",
          "persona": [
            "key_operator_with_posts_create"
          ],
          "purpose": "Create post from gateway surface",
          "required_fields": [
            {
              "name": "title",
              "type": "string",
              "required": true,
              "ui_component": "text_input"
            },
            {
              "name": "body",
              "type": "string",
              "required": true,
              "ui_component": "textarea"
            },
            {
              "name": "visibility_scope",
              "type": "enum",
              "required": true,
              "values": [
                "public",
                "private",
                "delegated"
              ],
              "ui_component": "select"
            },
            {
              "name": "state",
              "type": "enum",
              "required": false,
              "values": [
                "draft",
                "published"
              ],
              "default": "published",
              "ui_component": "radio_group"
            }
          ],
          "api_calls": [
            {
              "name": "create_post_gateway",
              "method": "POST",
              "endpoint": "/api/posts",
              "request_body": [
                "title",
                "body",
                "visibility_scope",
                "state?"
              ],
              "success_statuses": [
                201
              ],
              "error_statuses": [
                403,
                422
              ]
            }
          ],
          "success_ux": [
            "Redirect to /posts/{id}",
            "Toast confirmation and state badge"
          ],
          "error_ux": [
            "403 permission/policy banner",
            "422 field-level errors"
          ],
          "figma_data_attributes": {
            "surface": "gateway",
            "primary_cta": "Publish post",
            "secondary_cta": "Save draft",
            "tracking_events": [
              "post_create_submit",
              "post_create_success",
              "post_create_forbidden"
            ]
          },
          "acceptance_criteria": [
            "Visibility options exactly match API allowed values",
            "Use-key restriction handled with explicit copy"
          ]
        },
        {
          "page_id": "post_detail_v1",
          "url": "/posts/{postId}",
          "method": "GET",
          "persona": [
            "reader",
            "owner_admin",
            "key_operator"
          ],
          "purpose": "View full post",
          "required_fields": [],
          "path_params": [
            {
              "name": "postId",
              "type": "hex32"
            }
          ],
          "api_calls": [
            {
              "name": "get_post",
              "method": "GET",
              "endpoint": "/api/posts/{postId}",
              "success_statuses": [
                200
              ],
              "error_statuses": [
                403,
                404
              ]
            }
          ],
          "success_ux": [
            "Show full post content + metadata",
            "Show action bar: Edit, Flag, Comments"
          ],
          "error_ux": [
            "404: dedicated not-found layout",
            "403: access denied with support CTA"
          ],
          "figma_data_attributes": {
            "surface": "gateway",
            "header_fields": [
              "title",
              "created_at_utc",
              "author_id",
              "visibility_scope",
              "state"
            ],
            "tracking_events": [
              "post_detail_loaded",
              "post_detail_not_found"
            ]
          },
          "acceptance_criteria": [
            "Handles deleted/hidden resources gracefully",
            "Skeleton state while fetching"
          ]
        },
        {
          "page_id": "post_edit_v1",
          "url": "/posts/{postId}/edit",
          "method": "GET",
          "persona": [
            "key_operator_with_posts_edit"
          ],
          "purpose": "Revise post content",
          "required_fields": [
            {
              "name": "title",
              "type": "string",
              "required": true
            },
            {
              "name": "body",
              "type": "string",
              "required": true
            },
            {
              "name": "change_reason_code",
              "type": "string",
              "required": false,
              "default": "manual_edit"
            }
          ],
          "api_calls": [
            {
              "name": "edit_post",
              "method": "PATCH",
              "endpoint": "/api/posts/{postId}",
              "request_body": [
                "title",
                "body",
                "change_reason_code?"
              ],
              "success_statuses": [
                200
              ],
              "error_statuses": [
                403,
                404,
                422
              ]
            }
          ],
          "success_ux": [
            "Confirm save and return to detail page",
            "Optional summary of changes"
          ],
          "error_ux": [
            "422 inline field messages",
            "403/404 full-width alert component"
          ],
          "figma_data_attributes": {
            "surface": "gateway",
            "editing_mode": "single_page_form",
            "tracking_events": [
              "post_edit_submit",
              "post_edit_success",
              "post_edit_error"
            ]
          },
          "acceptance_criteria": [
            "Unsaved changes guard modal",
            "Server-side validation messages render under fields"
          ]
        },
        {
          "page_id": "post_flag_v1",
          "url": "/posts/{postId}/flag",
          "method": "GET",
          "persona": [
            "reader",
            "operator"
          ],
          "purpose": "Submit policy flag for a post",
          "required_fields": [
            {
              "name": "reason_code",
              "type": "string",
              "required": true,
              "ui_component": "select_or_text"
            }
          ],
          "api_calls": [
            {
              "name": "flag_post",
              "method": "POST",
              "endpoint": "/api/posts/{postId}/flags",
              "request_body": [
                "reason_code"
              ],
              "success_statuses": [
                201
              ],
              "error_statuses": [
                404,
                422
              ]
            }
          ],
          "success_ux": [
            "Success dialog and redirect back to post"
          ],
          "error_ux": [
            "Validation message for missing reason_code",
            "Not-found fallback state"
          ],
          "figma_data_attributes": {
            "surface": "gateway",
            "primary_cta": "Submit flag",
            "tracking_events": [
              "post_flag_submit",
              "post_flag_success"
            ]
          },
          "acceptance_criteria": [
            "Form cannot submit empty reason code"
          ]
        },
        {
          "page_id": "comment_thread_v1",
          "url": "/posts/{postId}/comments",
          "method": "GET",
          "persona": [
            "reader",
            "operator"
          ],
          "purpose": "Read comments for a post",
          "required_fields": [],
          "api_calls": [
            {
              "name": "list_comments",
              "method": "GET",
              "endpoint": "/api/posts/{postId}/comments",
              "success_statuses": [
                200
              ],
              "error_statuses": [
                404
              ]
            }
          ],
          "success_ux": [
            "Chronological comment list",
            "CTA to add comment"
          ],
          "error_ux": [
            "Thread unavailable state"
          ],
          "figma_data_attributes": {
            "surface": "gateway",
            "comment_item_schema": [
              "id",
              "author_id",
              "body",
              "state",
              "created_at_utc"
            ],
            "tracking_events": [
              "comments_loaded",
              "comments_empty"
            ]
          },
          "acceptance_criteria": [
            "Long threads remain performant",
            "Empty thread state has clear primary CTA"
          ]
        },
        {
          "page_id": "comment_create_v1",
          "url": "/posts/{postId}/comments/new",
          "method": "GET",
          "persona": [
            "operator_with_comments_create"
          ],
          "purpose": "Create comment on post",
          "required_fields": [
            {
              "name": "body",
              "type": "string",
              "required": true,
              "ui_component": "textarea"
            }
          ],
          "api_calls": [
            {
              "name": "create_comment",
              "method": "POST",
              "endpoint": "/api/posts/{postId}/comments",
              "request_body": [
                "body"
              ],
              "success_statuses": [
                201
              ],
              "error_statuses": [
                403,
                404,
                422
              ]
            }
          ],
          "success_ux": [
            "Return to thread with new comment highlighted"
          ],
          "error_ux": [
            "403-specific messages for post state, permission, or comments toggle",
            "422 body-required inline error",
            "404 if post unavailable"
          ],
          "figma_data_attributes": {
            "surface": "gateway",
            "guard_states": [
              "post_locked",
              "permissions_missing",
              "comments_toggle_off"
            ],
            "tracking_events": [
              "comment_submit",
              "comment_success",
              "comment_blocked"
            ]
          },
          "acceptance_criteria": [
            "All forbidden reasons map to human-readable copy"
          ]
        }
      ]
    },
    {
      "sprint_id": "S3",
      "name": "Console Content + Moderation",
      "goal": "Enable owner workflow for managing posts and moderation actions",
      "pages": [
        {
          "page_id": "console_post_index_v1",
          "url": "/console/posts",
          "method": "GET",
          "persona": [
            "owner_admin"
          ],
          "purpose": "Manage owner-authored posts",
          "required_fields": [],
          "api_calls": [
            {
              "name": "console_list_posts",
              "method": "GET",
              "endpoint": "/console/api/posts",
              "success_statuses": [
                200
              ]
            }
          ],
          "success_ux": [
            "Table/grid of posts with quick actions"
          ],
          "error_ux": [
            "Unauthorized/session-expired handling"
          ],
          "figma_data_attributes": {
            "surface": "console",
            "table_columns": [
              "title",
              "visibility_scope",
              "state",
              "created_at_utc",
              "actions"
            ],
            "tracking_events": [
              "console_posts_loaded"
            ]
          },
          "acceptance_criteria": [
            "Supports empty state and sortable columns"
          ]
        },
        {
          "page_id": "console_post_create_v1",
          "url": "/console/posts/new",
          "method": "GET",
          "persona": [
            "owner_admin"
          ],
          "purpose": "Create console-surface post",
          "required_fields": [
            {
              "name": "title",
              "type": "string",
              "required": true
            },
            {
              "name": "body",
              "type": "string",
              "required": true
            },
            {
              "name": "visibility_scope",
              "type": "enum",
              "required": true,
              "values": [
                "public",
                "private",
                "delegated"
              ]
            },
            {
              "name": "state",
              "type": "enum",
              "required": false,
              "values": [
                "draft",
                "published"
              ]
            }
          ],
          "api_calls": [
            {
              "name": "console_create_post",
              "method": "POST",
              "endpoint": "/console/api/posts",
              "request_body": [
                "title",
                "body",
                "visibility_scope",
                "state?"
              ],
              "success_statuses": [
                201
              ],
              "error_statuses": [
                422
              ]
            }
          ],
          "success_ux": [
            "Redirect to console post list/detail with confirmation"
          ],
          "error_ux": [
            "Validation details rendered inline"
          ],
          "figma_data_attributes": {
            "surface": "console",
            "primary_cta": "Create post",
            "tracking_events": [
              "console_post_create_submit",
              "console_post_create_success"
            ]
          },
          "acceptance_criteria": [
            "Field constraints match server validation exactly"
          ]
        },
        {
          "page_id": "console_post_moderation_v1",
          "url": "/console/posts/{postId}/moderation",
          "method": "GET",
          "persona": [
            "owner_admin_moderator"
          ],
          "purpose": "Moderate a post",
          "required_fields": [
            {
              "name": "action",
              "type": "enum",
              "required": true,
              "values": [
                "hide",
                "lock",
                "archive",
                "delete"
              ]
            },
            {
              "name": "reason_code",
              "type": "string",
              "required": false
            }
          ],
          "api_calls": [
            {
              "name": "moderate_post",
              "method": "POST",
              "endpoint": "/console/api/posts/{postId}/moderation",
              "request_body": [
                "action",
                "reason_code?"
              ],
              "success_statuses": [
                200
              ],
              "error_statuses": [
                404,
                422
              ]
            }
          ],
          "success_ux": [
            "Show resulting post state and moderation timestamp"
          ],
          "error_ux": [
            "Invalid action helper",
            "Not-found post fallback"
          ],
          "figma_data_attributes": {
            "surface": "console",
            "action_set": [
              "hide",
              "lock",
              "archive",
              "delete"
            ],
            "danger_actions": [
              "delete"
            ],
            "tracking_events": [
              "post_moderation_submit",
              "post_moderation_success"
            ]
          },
          "acceptance_criteria": [
            "Dangerous action requires confirmation modal"
          ]
        },
        {
          "page_id": "console_comment_moderation_v1",
          "url": "/console/posts/{postId}/comments/{commentId}/moderation",
          "method": "GET",
          "persona": [
            "owner_admin_moderator"
          ],
          "purpose": "Moderate a comment",
          "required_fields": [
            {
              "name": "action",
              "type": "enum",
              "required": true,
              "values": [
                "hide",
                "lock",
                "delete"
              ]
            },
            {
              "name": "reason_code",
              "type": "string",
              "required": false
            }
          ],
          "api_calls": [
            {
              "name": "moderate_comment",
              "method": "POST",
              "endpoint": "/console/api/posts/{postId}/comments/{commentId}/moderation",
              "request_body": [
                "action",
                "reason_code?"
              ],
              "success_statuses": [
                200
              ],
              "error_statuses": [
                404,
                422
              ]
            }
          ],
          "success_ux": [
            "Confirmation with resulting comment state"
          ],
          "error_ux": [
            "Invalid action guidance",
            "Comment-not-found state"
          ],
          "figma_data_attributes": {
            "surface": "console",
            "action_set": [
              "hide",
              "lock",
              "delete"
            ],
            "tracking_events": [
              "comment_moderation_submit",
              "comment_moderation_success"
            ]
          },
          "acceptance_criteria": [
            "Action options match API exactly"
          ]
        }
      ]
    },
    {
      "sprint_id": "S4",
      "name": "Keys + Invites + Placeholder Completion",
      "goal": "Operational tooling for delegation and lifecycle controls",
      "pages": [
        {
          "page_id": "console_key_issue_v1",
          "url": "/console/keys/new",
          "method": "GET",
          "persona": [
            "owner_admin"
          ],
          "purpose": "Issue author/use keys with policy constraints",
          "required_fields": [
            {
              "name": "key_class",
              "type": "enum",
              "required": true,
              "values": [
                "primary_author",
                "secondary_author",
                "use"
              ]
            },
            {
              "name": "permissions",
              "type": "array[string]",
              "required": true
            },
            {
              "name": "scope",
              "type": "array[string]",
              "required": true
            },
            {
              "name": "parent_envelope_id",
              "type": "string",
              "required": false,
              "conditional_required_when": "key_class == 'use'"
            },
            {
              "name": "ttl_seconds",
              "type": "integer",
              "required": false
            },
            {
              "name": "comments_enabled",
              "type": "boolean",
              "required": false
            }
          ],
          "api_calls": [
            {
              "name": "issue_key",
              "method": "POST",
              "endpoint": "/console/api/keys",
              "request_body": [
                "key_class",
                "parent_envelope_id?",
                "permissions",
                "scope",
                "ttl_seconds?",
                "comments_enabled?"
              ],
              "success_statuses": [
                201
              ],
              "error_statuses": [
                403,
                422
              ],
              "sensitive_response_fields": [
                "data.api_key"
              ]
            }
          ],
          "success_ux": [
            "One-time reveal of api_key with copy/download pattern",
            "Display delegation metadata (depth, envelope id, expires_at_utc)"
          ],
          "error_ux": [
            "Policy violation messages for ttl, subset, hierarchy, owner mismatch"
          ],
          "figma_data_attributes": {
            "surface": "console",
            "security_patterns": [
              "secret_reveal_once",
              "copy_with_warning",
              "acknowledgement_checkbox"
            ],
            "tracking_events": [
              "key_issue_submit",
              "key_issue_success",
              "key_issue_policy_error"
            ]
          },
          "acceptance_criteria": [
            "Secrets are not re-rendered after navigation",
            "Conditional required UI for use keys is enforced"
          ]
        },
        {
          "page_id": "console_key_lifecycle_v1",
          "url": "/console/keys/{keyId}/lifecycle",
          "method": "GET",
          "persona": [
            "owner_admin"
          ],
          "purpose": "Suspend/cancel/revoke key lifecycle",
          "required_fields": [
            {
              "name": "state",
              "type": "enum",
              "required": true,
              "values": [
                "suspend",
                "cancel",
                "revoke"
              ]
            }
          ],
          "api_calls": [
            {
              "name": "transition_key_state",
              "method": "POST",
              "endpoint": "/console/api/keys/{keyId}/lifecycle",
              "request_body": [
                "state"
              ],
              "success_statuses": [
                204
              ],
              "error_statuses": [
                404,
                422
              ]
            }
          ],
          "success_ux": [
            "Display lifecycle transition success state and disable repeat action"
          ],
          "error_ux": [
            "Invalid state or missing key message"
          ],
          "figma_data_attributes": {
            "surface": "console",
            "risk_map": {
              "suspend": "low",
              "cancel": "medium",
              "revoke": "high"
            },
            "tracking_events": [
              "key_lifecycle_submit",
              "key_lifecycle_success"
            ]
          },
          "acceptance_criteria": [
            "Revoke action requires explicit confirmation text"
          ]
        },
        {
          "page_id": "console_keychain_index_v1",
          "url": "/console/keychains",
          "method": "GET",
          "persona": [
            "owner_admin"
          ],
          "purpose": "Keychain management shell (backend currently placeholder)",
          "required_fields": [],
          "api_calls": [
            {
              "name": "list_keychains",
              "method": "GET",
              "endpoint": "/console/api/keychains",
              "success_statuses": [
                200
              ],
              "current_backend_status": "placeholder_returns_empty_list"
            }
          ],
          "success_ux": [
            "Show empty state with roadmap copy",
            "Prepare table layout for future keychain records"
          ],
          "error_ux": [
            "Generic retrieval error + retry"
          ],
          "figma_data_attributes": {
            "surface": "console",
            "placeholder_tag": "backend_pending",
            "tracking_events": [
              "keychain_view_loaded"
            ]
          },
          "acceptance_criteria": [
            "Can gracefully handle empty list as default"
          ]
        },
        {
          "page_id": "console_invite_create_v1",
          "url": "/console/invites/new",
          "method": "GET",
          "persona": [
            "owner_admin"
          ],
          "purpose": "Create invite (current API emits generated invite receipt)",
          "required_fields": [],
          "api_calls": [
            {
              "name": "create_invite",
              "method": "POST",
              "endpoint": "/console/api/invites",
              "request_body": {},
              "success_statuses": [
                201
              ],
              "current_backend_status": "lightweight_generated_receipt"
            }
          ],
          "success_ux": [
            "Receipt view with invite_id and created timestamp",
            "Copy invite identifier action"
          ],
          "error_ux": [
            "Fallback error panel if create fails"
          ],
          "figma_data_attributes": {
            "surface": "console",
            "placeholder_tag": "backend_extension_likely",
            "tracking_events": [
              "invite_create_submit",
              "invite_create_success"
            ]
          },
          "acceptance_criteria": [
            "Supports future extension for invite metadata fields"
          ]
        }
      ]
    }
  ],
  "pages": [
    {
      "page_id": "auth_login_v1",
      "sprint": "S1",
      "url": "/login",
      "method": "GET",
      "persona": [
        "owner_admin"
      ],
      "purpose": "Email/password login",
      "required_fields": [
        {
          "name": "email",
          "type": "string",
          "required": true,
          "format": "email"
        },
        {
          "name": "password",
          "type": "string",
          "required": true
        }
      ],
      "api_calls": [
        {
          "name": "owner_login",
          "method": "POST",
          "endpoint": "/api/auth/login",
          "request_body": {
            "email": "string",
            "password": "string"
          },
          "success_statuses": [
            200
          ],
          "error_statuses": [
            401,
            422
          ]
        }
      ],
      "success_ux": [
        "Store session",
        "Redirect to /feed"
      ],
      "error_ux": [
        "401 invalid credentials",
        "422 field-level validation"
      ],
      "figma_data": {
        "surface": "public_auth",
        "primary_cta": "Sign in"
      },
      "friendly_ui_description": {
        "friendly_summary": "A calm, trustworthy sign-in screen that gets returning owners into CRE8 in seconds.",
        "html_seed_description": "Use a centered single-column card with generous spacing, clear field labels, and a confident primary button. Keep the email visible after errors, clear the password on 401, and show inline validation helpers without shifting layout.",
        "visual_keywords": [
          "clean",
          "trustworthy",
          "minimal",
          "focused"
        ],
        "style_notes": "Soft neutral background, high-contrast form card, subtle shadow, and clear success/error banners.",
        "microcopy_tone": "Confident, reassuring, and direct."
      }
    },
    {
      "page_id": "auth_key_login_v1",
      "sprint": "S1",
      "url": "/key-login",
      "method": "GET",
      "persona": [
        "key_operator"
      ],
      "purpose": "Key ID + API key login",
      "required_fields": [
        {
          "name": "key_id",
          "type": "string",
          "required": true
        },
        {
          "name": "api_key",
          "type": "string",
          "required": true
        }
      ],
      "api_calls": [
        {
          "name": "key_login",
          "method": "POST",
          "endpoint": "/api/auth/key-login",
          "request_body": {
            "key_id": "string",
            "api_key": "string"
          },
          "success_statuses": [
            200
          ],
          "error_statuses": [
            401,
            422
          ]
        }
      ],
      "success_ux": [
        "Redirect to /feed"
      ],
      "error_ux": [
        "401 invalid key credentials",
        "422 required fields"
      ],
      "figma_data": {
        "surface": "public_auth",
        "primary_cta": "Sign in with key"
      },
      "friendly_ui_description": {
        "friendly_summary": "A secure operator login that makes secret handling feel safe and intentional.",
        "html_seed_description": "Present key ID and API key in a secure form with masked input by default and reveal toggle. Add a short security tip block, avoid exposing secrets after submit, and keep errors concise and non-alarming.",
        "visual_keywords": [
          "secure",
          "technical",
          "calm",
          "precise"
        ],
        "style_notes": "Monospace support for key fields, shield icon accents, and strong visual separation between key ID and secret.",
        "microcopy_tone": "Security-forward and practical."
      }
    },
    {
      "page_id": "auth_owner_signup_v1",
      "sprint": "S1",
      "url": "/signup-owner",
      "method": "GET",
      "persona": [
        "first_owner"
      ],
      "purpose": "Owner registration",
      "required_fields": [
        {
          "name": "email",
          "type": "string",
          "required": true,
          "format": "email"
        },
        {
          "name": "password",
          "type": "string",
          "required": true,
          "min_length": 12
        }
      ],
      "api_calls": [
        {
          "name": "register_owner",
          "method": "POST",
          "endpoint": "/console/owners",
          "request_body": {
            "email": "string",
            "password": "string"
          },
          "success_statuses": [
            201
          ],
          "error_statuses": [
            409,
            422
          ]
        }
      ],
      "success_ux": [
        "Show owner_id",
        "CTA to /login"
      ],
      "error_ux": [
        "409 owner conflict",
        "422 validation"
      ],
      "figma_data": {
        "surface": "public_auth",
        "primary_cta": "Create owner"
      },
      "friendly_ui_description": {
        "friendly_summary": "A welcoming owner onboarding page that feels premium but straightforward.",
        "html_seed_description": "Build a simple registration form with strength hints for password rules and a clear progression to login after success. Surface conflict errors as actionable guidance and keep friction low.",
        "visual_keywords": [
          "welcoming",
          "professional",
          "simple",
          "guided"
        ],
        "style_notes": "Progressive helper text, password strength meter, and success confirmation panel with next-step CTA.",
        "microcopy_tone": "Encouraging and concise."
      }
    },
    {
      "page_id": "feed_index_v1",
      "sprint": "S1",
      "url": "/feed",
      "method": "GET",
      "persona": [
        "reader",
        "owner_admin",
        "key_operator"
      ],
      "purpose": "Feed browsing",
      "required_fields": [],
      "api_calls": [
        {
          "name": "list_feed",
          "method": "GET",
          "endpoint": "/api/feed",
          "query_params": [
            "scope",
            "limit",
            "cursor"
          ],
          "success_statuses": [
            200
          ],
          "error_statuses": [
            401,
            403,
            500
          ]
        }
      ],
      "success_ux": [
        "Render cards",
        "Load more via cursor"
      ],
      "error_ux": [
        "Retry block",
        "Empty state"
      ],
      "figma_data": {
        "surface": "gateway",
        "list_component": "post_cards"
      },
      "friendly_ui_description": {
        "friendly_summary": "A scannable activity feed that helps users discover updates quickly.",
        "html_seed_description": "Use card-based post previews with clear hierarchy (title, author, timestamp, snippet) and cursor-driven load-more behavior. Include polished empty/loading/error states that preserve rhythm and context.",
        "visual_keywords": [
          "scannable",
          "content-first",
          "dynamic",
          "modular"
        ],
        "style_notes": "Responsive multi-column grid on desktop, single column on mobile, lightweight filters near top.",
        "microcopy_tone": "Informative and energetic."
      }
    },
    {
      "page_id": "post_create_gateway_v1",
      "sprint": "S2",
      "url": "/posts/new",
      "method": "GET",
      "persona": [
        "key_operator_with_posts_create"
      ],
      "purpose": "Create post",
      "required_fields": [
        {
          "name": "title",
          "type": "string",
          "required": true
        },
        {
          "name": "body",
          "type": "string",
          "required": true
        },
        {
          "name": "visibility_scope",
          "type": "enum",
          "required": true,
          "values": [
            "public",
            "private",
            "delegated"
          ]
        },
        {
          "name": "state",
          "type": "enum",
          "required": false,
          "values": [
            "draft",
            "published"
          ]
        }
      ],
      "api_calls": [
        {
          "name": "create_post_gateway",
          "method": "POST",
          "endpoint": "/api/posts",
          "request_body": {
            "title": "string",
            "body": "string",
            "visibility_scope": "enum",
            "state": "enum?"
          },
          "success_statuses": [
            201
          ],
          "error_statuses": [
            403,
            422
          ]
        }
      ],
      "success_ux": [
        "Redirect to /posts/{id}"
      ],
      "error_ux": [
        "403 forbidden",
        "422 field errors"
      ],
      "figma_data": {
        "surface": "gateway",
        "primary_cta": "Publish post"
      },
      "friendly_ui_description": {
        "friendly_summary": "A focused post composer designed for fast publishing with guardrails.",
        "html_seed_description": "Provide a distraction-light editor with title, body, visibility selector, and publish action. Keep validation immediate and friendly; surface permission failures with clear explanation and next action.",
        "visual_keywords": [
          "focused",
          "creator-centric",
          "efficient",
          "clear"
        ],
        "style_notes": "Sticky action bar, autosize textarea, and compact metadata controls.",
        "microcopy_tone": "Creator-friendly and decisive."
      }
    },
    {
      "page_id": "post_detail_v1",
      "sprint": "S2",
      "url": "/posts/{postId}",
      "method": "GET",
      "persona": [
        "reader",
        "owner_admin",
        "key_operator"
      ],
      "purpose": "View post detail",
      "required_fields": [],
      "api_calls": [
        {
          "name": "get_post",
          "method": "GET",
          "endpoint": "/api/posts/{postId}",
          "success_statuses": [
            200
          ],
          "error_statuses": [
            403,
            404
          ]
        }
      ],
      "success_ux": [
        "Render full post"
      ],
      "error_ux": [
        "404 not found",
        "403 access denied"
      ],
      "figma_data": {
        "surface": "gateway",
        "detail_layout": "article_with_actions"
      },
      "friendly_ui_description": {
        "friendly_summary": "An immersive article view with clear primary content and secondary actions.",
        "html_seed_description": "Prioritize readability with generous line length control, metadata row, and action cluster for share/flag/edit depending on role. Error states should feel intentional, not broken.",
        "visual_keywords": [
          "readable",
          "immersive",
          "balanced",
          "clean"
        ],
        "style_notes": "Article typography scale, subtle separators, and optional sidebar for contextual actions.",
        "microcopy_tone": "Clear and editorial."
      }
    },
    {
      "page_id": "post_edit_v1",
      "sprint": "S2",
      "url": "/posts/{postId}/edit",
      "method": "GET",
      "persona": [
        "key_operator_with_posts_edit"
      ],
      "purpose": "Edit post content",
      "required_fields": [
        {
          "name": "title",
          "type": "string",
          "required": true
        },
        {
          "name": "body",
          "type": "string",
          "required": true
        },
        {
          "name": "change_reason_code",
          "type": "string",
          "required": false,
          "default": "manual_edit"
        }
      ],
      "api_calls": [
        {
          "name": "edit_post",
          "method": "PATCH",
          "endpoint": "/api/posts/{postId}",
          "request_body": {
            "title": "string",
            "body": "string",
            "change_reason_code": "string?"
          },
          "success_statuses": [
            200
          ],
          "error_statuses": [
            403,
            404,
            422
          ]
        }
      ],
      "success_ux": [
        "Saved confirmation"
      ],
      "error_ux": [
        "Validation + permissions handling"
      ],
      "figma_data": {
        "surface": "gateway",
        "form_layout": "post_editor"
      },
      "friendly_ui_description": {
        "friendly_summary": "A safe editing workspace that communicates confidence and revision intent.",
        "html_seed_description": "Preload existing content into an editor with obvious save state and optional change-reason input. Keep unsaved-change awareness visible and confirm successful updates without redirect confusion.",
        "visual_keywords": [
          "controlled",
          "productive",
          "trustworthy",
          "structured"
        ],
        "style_notes": "Diff-friendly spacing, persistent save controls, and soft warning treatment for unsaved edits.",
        "microcopy_tone": "Precise and supportive."
      }
    },
    {
      "page_id": "post_flag_v1",
      "sprint": "S2",
      "url": "/posts/{postId}/flag",
      "method": "GET",
      "persona": [
        "reader",
        "operator"
      ],
      "purpose": "Flag/report post",
      "required_fields": [
        {
          "name": "reason_code",
          "type": "string",
          "required": true
        }
      ],
      "api_calls": [
        {
          "name": "flag_post",
          "method": "POST",
          "endpoint": "/api/posts/{postId}/flags",
          "request_body": {
            "reason_code": "string"
          },
          "success_statuses": [
            201
          ],
          "error_statuses": [
            404,
            422
          ]
        }
      ],
      "success_ux": [
        "Submission confirmation"
      ],
      "error_ux": [
        "Validation/not-found messaging"
      ],
      "figma_data": {
        "surface": "gateway",
        "modal_pattern": "confirm_submit"
      },
      "friendly_ui_description": {
        "friendly_summary": "A respectful reporting flow that is quick, clear, and non-confrontational.",
        "html_seed_description": "Implement as a compact modal or panel with reason selection and concise policy context. Confirm submission immediately and prevent duplicate submissions while request is in flight.",
        "visual_keywords": [
          "respectful",
          "lightweight",
          "clear",
          "safe"
        ],
        "style_notes": "Neutral warning palette, compact form controls, and clear confirmation state.",
        "microcopy_tone": "Calm and responsible."
      }
    },
    {
      "page_id": "comment_thread_v1",
      "sprint": "S2",
      "url": "/posts/{postId}/comments",
      "method": "GET",
      "persona": [
        "reader",
        "operator"
      ],
      "purpose": "View comments",
      "required_fields": [],
      "api_calls": [
        {
          "name": "list_comments",
          "method": "GET",
          "endpoint": "/api/posts/{postId}/comments",
          "success_statuses": [
            200
          ],
          "error_statuses": [
            404
          ]
        }
      ],
      "success_ux": [
        "Render thread chronologically"
      ],
      "error_ux": [
        "Unavailable thread state"
      ],
      "figma_data": {
        "surface": "gateway",
        "list_component": "comment_thread"
      },
      "friendly_ui_description": {
        "friendly_summary": "A readable conversation thread that keeps context and chronology obvious.",
        "html_seed_description": "Display comments in chronological order with clear nesting/author cues where applicable. Keep thread loading and unavailable states visually consistent with post detail pages.",
        "visual_keywords": [
          "conversational",
          "organized",
          "readable",
          "contextual"
        ],
        "style_notes": "Avatar + metadata row per comment, comfortable vertical rhythm, subtle dividers.",
        "microcopy_tone": "Community-friendly and clear."
      }
    },
    {
      "page_id": "comment_create_v1",
      "sprint": "S2",
      "url": "/posts/{postId}/comments/new",
      "method": "GET",
      "persona": [
        "operator_with_comments_create"
      ],
      "purpose": "Create comment",
      "required_fields": [
        {
          "name": "body",
          "type": "string",
          "required": true
        }
      ],
      "api_calls": [
        {
          "name": "create_comment",
          "method": "POST",
          "endpoint": "/api/posts/{postId}/comments",
          "request_body": {
            "body": "string"
          },
          "success_statuses": [
            201
          ],
          "error_statuses": [
            403,
            404,
            422
          ]
        }
      ],
      "success_ux": [
        "Redirect to comments thread"
      ],
      "error_ux": [
        "Blocked states + validation"
      ],
      "figma_data": {
        "surface": "gateway",
        "editor_component": "comment_input"
      },
      "friendly_ui_description": {
        "friendly_summary": "A simple reply composer that encourages thoughtful participation.",
        "html_seed_description": "Use an inline composer below the thread with character-friendly textarea behavior and clear submit affordance. Explain permission/toggle blocks with plain language instead of technical errors.",
        "visual_keywords": [
          "inviting",
          "lightweight",
          "clear",
          "interactive"
        ],
        "style_notes": "Composer dock with gentle emphasis, inline validation, and optimistic submit feedback.",
        "microcopy_tone": "Warm and direct."
      }
    },
    {
      "page_id": "console_post_index_v1",
      "sprint": "S3",
      "url": "/console/posts",
      "method": "GET",
      "persona": [
        "owner_admin"
      ],
      "purpose": "Console post management list",
      "required_fields": [],
      "api_calls": [
        {
          "name": "console_list_posts",
          "method": "GET",
          "endpoint": "/console/api/posts",
          "success_statuses": [
            200
          ],
          "error_statuses": [
            401,
            403
          ]
        }
      ],
      "success_ux": [
        "Management table with actions"
      ],
      "error_ux": [
        "Auth/session error treatment"
      ],
      "figma_data": {
        "surface": "console",
        "table_component": "posts_admin_table"
      },
      "friendly_ui_description": {
        "friendly_summary": "An operational posts dashboard for owners to monitor and manage content quickly.",
        "html_seed_description": "Build a high-signal table/list with status chips, visibility tags, and quick row actions. Include robust empty/error states and sorting/filter controls tuned for admin workflows.",
        "visual_keywords": [
          "operational",
          "high-signal",
          "structured",
          "efficient"
        ],
        "style_notes": "Dense but legible layout, sticky headers, and status color coding.",
        "microcopy_tone": "Professional and concise."
      }
    },
    {
      "page_id": "console_post_create_v1",
      "sprint": "S3",
      "url": "/console/posts/new",
      "method": "GET",
      "persona": [
        "owner_admin"
      ],
      "purpose": "Create post in console",
      "required_fields": [
        {
          "name": "title",
          "type": "string",
          "required": true
        },
        {
          "name": "body",
          "type": "string",
          "required": true
        },
        {
          "name": "visibility_scope",
          "type": "enum",
          "required": true,
          "values": [
            "public",
            "private",
            "delegated"
          ]
        },
        {
          "name": "state",
          "type": "enum",
          "required": false,
          "values": [
            "draft",
            "published"
          ]
        }
      ],
      "api_calls": [
        {
          "name": "console_create_post",
          "method": "POST",
          "endpoint": "/console/api/posts",
          "success_statuses": [
            201
          ],
          "error_statuses": [
            422
          ]
        }
      ],
      "success_ux": [
        "Created confirmation + navigation"
      ],
      "error_ux": [
        "Validation detail mapping"
      ],
      "figma_data": {
        "surface": "console",
        "primary_cta": "Create post"
      },
      "friendly_ui_description": {
        "friendly_summary": "An admin-grade composer with publishing controls and policy-safe defaults.",
        "html_seed_description": "Mirror gateway create UX but with admin context cues and optional advanced controls. Keep defaults safe, validation explicit, and success state tied to moderation visibility.",
        "visual_keywords": [
          "administrative",
          "controlled",
          "robust",
          "clear"
        ],
        "style_notes": "Split sections for content and policy settings, with consistent control labels.",
        "microcopy_tone": "Authoritative but friendly."
      }
    },
    {
      "page_id": "console_post_moderation_v1",
      "sprint": "S3",
      "url": "/console/posts/{postId}/moderation",
      "method": "GET",
      "persona": [
        "owner_admin_moderator"
      ],
      "purpose": "Moderate post",
      "required_fields": [
        {
          "name": "action",
          "type": "enum",
          "required": true,
          "values": [
            "hide",
            "lock",
            "archive",
            "delete"
          ]
        },
        {
          "name": "reason_code",
          "type": "string",
          "required": false
        }
      ],
      "api_calls": [
        {
          "name": "moderate_post",
          "method": "POST",
          "endpoint": "/console/api/posts/{postId}/moderation",
          "success_statuses": [
            200
          ],
          "error_statuses": [
            404,
            422
          ]
        }
      ],
      "success_ux": [
        "Show updated moderation state"
      ],
      "error_ux": [
        "Invalid action/not found handling"
      ],
      "figma_data": {
        "surface": "console",
        "action_panel": "post_moderation_actions"
      },
      "friendly_ui_description": {
        "friendly_summary": "A decisive moderation action panel for post-level enforcement.",
        "html_seed_description": "Present action buttons (hide/lock/archive/delete) with brief consequence hints and optional reason code input. Confirm destructive actions and show resulting state immediately.",
        "visual_keywords": [
          "decisive",
          "safe",
          "auditable",
          "clear"
        ],
        "style_notes": "Action hierarchy with destructive emphasis, audit sidebar for recent actions.",
        "microcopy_tone": "Firm, neutral, accountable."
      }
    },
    {
      "page_id": "console_comment_moderation_v1",
      "sprint": "S3",
      "url": "/console/posts/{postId}/comments/{commentId}/moderation",
      "method": "GET",
      "persona": [
        "owner_admin_moderator"
      ],
      "purpose": "Moderate comment",
      "required_fields": [
        {
          "name": "action",
          "type": "enum",
          "required": true,
          "values": [
            "hide",
            "lock",
            "delete"
          ]
        },
        {
          "name": "reason_code",
          "type": "string",
          "required": false
        }
      ],
      "api_calls": [
        {
          "name": "moderate_comment",
          "method": "POST",
          "endpoint": "/console/api/posts/{postId}/comments/{commentId}/moderation",
          "success_statuses": [
            200
          ],
          "error_statuses": [
            404,
            422
          ]
        }
      ],
      "success_ux": [
        "Show updated comment state"
      ],
      "error_ux": [
        "Invalid action/not found handling"
      ],
      "figma_data": {
        "surface": "console",
        "action_panel": "comment_moderation_actions"
      },
      "friendly_ui_description": {
        "friendly_summary": "A streamlined comment moderation view built for fast, accurate decisions.",
        "html_seed_description": "Keep comment context visible while exposing moderation actions and reason capture. Ensure rapid transitions between comments without losing location in the queue.",
        "visual_keywords": [
          "streamlined",
          "focused",
          "operational",
          "auditable"
        ],
        "style_notes": "Two-pane moderation layout with context on left and actions on right.",
        "microcopy_tone": "Neutral and action-oriented."
      }
    },
    {
      "page_id": "console_key_issue_v1",
      "sprint": "S4",
      "url": "/console/keys/new",
      "method": "GET",
      "persona": [
        "owner_admin"
      ],
      "purpose": "Issue delegated keys",
      "required_fields": [
        {
          "name": "key_class",
          "type": "enum",
          "required": true,
          "values": [
            "primary_author",
            "secondary_author",
            "use"
          ]
        },
        {
          "name": "permissions",
          "type": "array[string]",
          "required": true
        },
        {
          "name": "scope",
          "type": "array[string]",
          "required": true
        },
        {
          "name": "parent_envelope_id",
          "type": "string",
          "required": false,
          "conditional_required_when": "key_class=use"
        },
        {
          "name": "ttl_seconds",
          "type": "integer",
          "required": false
        },
        {
          "name": "comments_enabled",
          "type": "boolean",
          "required": false
        }
      ],
      "api_calls": [
        {
          "name": "issue_key",
          "method": "POST",
          "endpoint": "/console/api/keys",
          "success_statuses": [
            201
          ],
          "error_statuses": [
            403,
            422
          ]
        }
      ],
      "success_ux": [
        "One-time secret reveal for api_key"
      ],
      "error_ux": [
        "Policy violation messaging"
      ],
      "figma_data": {
        "surface": "console",
        "security_pattern": "secret_reveal_once"
      },
      "friendly_ui_description": {
        "friendly_summary": "A controlled key issuance wizard that balances speed and security clarity.",
        "html_seed_description": "Guide owners through key class, scopes, permissions, TTL, and comments toggle with inline explanations. Highlight irreversible security implications before final issue.",
        "visual_keywords": [
          "secure",
          "guided",
          "technical",
          "intentional"
        ],
        "style_notes": "Step-based or sectioned form with permission chips and scope selectors.",
        "microcopy_tone": "Security-conscious and instructional."
      }
    },
    {
      "page_id": "console_key_lifecycle_v1",
      "sprint": "S4",
      "url": "/console/keys/{keyId}/lifecycle",
      "method": "GET",
      "persona": [
        "owner_admin"
      ],
      "purpose": "Suspend/cancel/revoke key",
      "required_fields": [
        {
          "name": "state",
          "type": "enum",
          "required": true,
          "values": [
            "suspend",
            "cancel",
            "revoke"
          ]
        }
      ],
      "api_calls": [
        {
          "name": "transition_key_state",
          "method": "POST",
          "endpoint": "/console/api/keys/{keyId}/lifecycle",
          "success_statuses": [
            204
          ],
          "error_statuses": [
            404,
            422
          ]
        }
      ],
      "success_ux": [
        "Transition confirmation"
      ],
      "error_ux": [
        "Invalid state/not found"
      ],
      "figma_data": {
        "surface": "console",
        "danger_action": "revoke"
      },
      "friendly_ui_description": {
        "friendly_summary": "A lifecycle control surface for rotating, revoking, and state-managing keys safely.",
        "html_seed_description": "Show current key metadata and lifecycle state prominently, then provide guarded transition actions with confirmation and audit trace visibility.",
        "visual_keywords": [
          "control",
          "safety",
          "traceable",
          "clear"
        ],
        "style_notes": "State timeline component, confirmation modals, and immutable audit snippets.",
        "microcopy_tone": "Explicit and reliable."
      }
    },
    {
      "page_id": "console_keychain_index_v1",
      "sprint": "S4",
      "url": "/console/keychains",
      "method": "GET",
      "persona": [
        "owner_admin"
      ],
      "purpose": "Keychain management shell (backend placeholder)",
      "required_fields": [],
      "api_calls": [
        {
          "name": "list_keychains",
          "method": "GET",
          "endpoint": "/console/api/keychains",
          "success_statuses": [
            200
          ]
        }
      ],
      "success_ux": [
        "Empty/placeholder state supported"
      ],
      "error_ux": [
        "Generic retry state"
      ],
      "figma_data": {
        "surface": "console",
        "backend_status": "placeholder"
      },
      "friendly_ui_description": {
        "friendly_summary": "A searchable key inventory for governance, visibility, and compliance checks.",
        "html_seed_description": "Render keychains as a sortable/filterable admin list with status, scope, permissions, and expiry columns. Support quick drill-down without overwhelming new operators.",
        "visual_keywords": [
          "inventory",
          "governance",
          "structured",
          "scannable"
        ],
        "style_notes": "Data-grid emphasis with faceted filters and compact badges.",
        "microcopy_tone": "Clear and operational."
      }
    },
    {
      "page_id": "console_invite_create_v1",
      "sprint": "S4",
      "url": "/console/invites/new",
      "method": "GET",
      "persona": [
        "owner_admin"
      ],
      "purpose": "Create invite receipt flow (light backend)",
      "required_fields": [],
      "api_calls": [
        {
          "name": "create_invite",
          "method": "POST",
          "endpoint": "/console/api/invites",
          "success_statuses": [
            201
          ]
        }
      ],
      "success_ux": [
        "Display invite_id receipt"
      ],
      "error_ux": [
        "Fallback error panel"
      ],
      "figma_data": {
        "surface": "console",
        "backend_status": "lightweight_generated_receipt"
      },
      "friendly_ui_description": {
        "friendly_summary": "A lightweight invite creation page that feels fast and trustworthy.",
        "html_seed_description": "Use a small form with immediate feedback on creation and easy copy/share affordances for generated invite IDs. Keep success state prominent and actionable.",
        "visual_keywords": [
          "lightweight",
          "fast",
          "practical",
          "trustworthy"
        ],
        "style_notes": "Compact panel with copy-to-clipboard affordance and success toast.",
        "microcopy_tone": "Friendly and efficient."
      }
    }
  ],
  "index": {
    "page_ids": [
      "auth_login_v1",
      "auth_key_login_v1",
      "auth_owner_signup_v1",
      "feed_index_v1",
      "post_create_gateway_v1",
      "post_detail_v1",
      "post_edit_v1",
      "post_flag_v1",
      "comment_thread_v1",
      "comment_create_v1",
      "console_post_index_v1",
      "console_post_create_v1",
      "console_post_moderation_v1",
      "console_comment_moderation_v1",
      "console_key_issue_v1",
      "console_key_lifecycle_v1",
      "console_keychain_index_v1",
      "console_invite_create_v1"
    ],
    "by_sprint": {
      "S1": [
        "auth_login_v1",
        "auth_key_login_v1",
        "auth_owner_signup_v1",
        "feed_index_v1"
      ],
      "S2": [
        "post_create_gateway_v1",
        "post_detail_v1",
        "post_edit_v1",
        "post_flag_v1",
        "comment_thread_v1",
        "comment_create_v1"
      ],
      "S3": [
        "console_post_index_v1",
        "console_post_create_v1",
        "console_post_moderation_v1",
        "console_comment_moderation_v1"
      ],
      "S4": [
        "console_key_issue_v1",
        "console_key_lifecycle_v1",
        "console_keychain_index_v1",
        "console_invite_create_v1"
      ]
    },
    "total_pages": 18
  }
}
