{
  "schema": "smmods.publishing-workflow.v1",
  "generatedAt": "2026-05-29T05:43:00Z",
  "status": "planned-static-contract",
  "liveBackend": false,
  "summary": "Static contract for the future authenticated mod publishing lane. The current production site uses the documented manual importer until backend services exist.",
  "auth": {
    "live": false,
    "accountRequired": true,
    "sessionRequired": true,
    "roles": [
      "player",
      "modder",
      "moderator",
      "admin"
    ],
    "plannedCapabilities": [
      "free account creation",
      "email verification",
      "session cookies",
      "mod ownership",
      "upload ownership",
      "moderation permissions",
      "audit log attribution"
    ]
  },
  "upload": {
    "live": false,
    "plannedEndpoint": {
      "method": "POST",
      "path": "/api/v1/uploads"
    },
    "statusEndpointTemplate": "/api/v1/uploads/{submissionId}",
    "acceptedContentTypes": [
      "application/zip",
      "application/x-zip-compressed"
    ],
    "requiredSidecarSchema": "smmods.mod-release-submission.v1",
    "sidecarSchemaUrl": "https://smmods.com/api/v1/publishing/mod-release-submission.schema.json",
    "maxPackageBytes": 104857600,
    "stagingPathTemplate": "uploads/staging/{submissionId}/{fileName}",
    "artifactPathTemplate": "downloads/mods/{modId}/{version}/{fileName}",
    "immutableArtifacts": true,
    "liveUploadGate": "POST /api/v1/uploads returns uploads_disabled until SMMODS_LIVE_UPLOADS=1 is active on the deployed backend."
  },
  "backendRequirements": {
    "status": "planned",
    "summary": "These services must exist and be covered by validation before liveBackend can become true.",
    "backendContractUrl": "https://smmods.com/api/v1/publishing/backend-contract.json",
    "frameworkValidationContractUrl": "https://smmods.com/api/v1/publishing/starminer-publishing-validation.v1.json",
    "frameworkValidationContractSchemaUrl": "https://smmods.com/api/v1/publishing/starminer-publishing-validation.schema.json",
    "requiredServices": [
      {
        "id": "auth_service",
        "required": true,
        "live": false,
        "description": "Free player/modder accounts, verification email delivery, write-route rate limits, session cookies, password recovery, and role assignment."
      },
      {
        "id": "upload_storage",
        "required": true,
        "live": false,
        "description": "Private staging storage for submitted ZIPs plus immutable public artifact promotion."
      },
      {
        "id": "validation_worker",
        "required": true,
        "live": false,
        "description": "Background package validation for sidecar schema, manifest schema, ZIP safety, hashes, dependencies, target build, and manager parsing."
      },
      {
        "id": "moderation_queue",
        "required": true,
        "live": false,
        "description": "Authenticated moderator queue with approve, reject, changes requested, hide, and supersede actions."
      },
      {
        "id": "catalog_publisher",
        "required": true,
        "live": false,
        "description": "Atomic catalog/detail/version regeneration from approved releases with immutable artifact URLs."
      },
      {
        "id": "audit_log",
        "required": true,
        "live": false,
        "description": "Durable audit trail for account, upload, validation, moderation, and publication actions."
      },
      {
        "id": "public_smoke_runner",
        "required": true,
        "live": false,
        "description": "Post-publish public smoke runner that fetches live routes, validates JSON, downloads artifacts, verifies hashes, and runs manager URL readers."
      }
    ],
    "goLiveRules": [
      "Do not set liveBackend true until every required service is live.",
      "Do not enable public account copy until verification email delivery is configured and account creation fails closed when delivery is unavailable.",
      "Do not enable public account, upload, or moderation copy until rate_limit_exceeded responses are covered by backend deployment smoke.",
      "Do not expose POST /api/v1/uploads until auth, staging storage, validation workers, moderation, audit logging, catalog publication, and SMMODS_LIVE_UPLOADS=1 are covered by CI or deployment smoke.",
      "Do not remove static placeholder copy from account, upload, or moderation pages until the matching service is deployed and validated.",
      "Keep the manual fallback active until the backend import path has produced at least one verified public mod release."
    ]
  },
  "states": [
    {
      "id": "draft",
      "label": "Draft",
      "publicCatalogVisible": false,
      "downloadEnabled": false
    },
    {
      "id": "uploaded",
      "label": "Uploaded",
      "publicCatalogVisible": false,
      "downloadEnabled": false
    },
    {
      "id": "validating",
      "label": "Validating",
      "publicCatalogVisible": false,
      "downloadEnabled": false
    },
    {
      "id": "validation_failed",
      "label": "Validation failed",
      "publicCatalogVisible": false,
      "downloadEnabled": false
    },
    {
      "id": "cancelled",
      "label": "Cancelled",
      "publicCatalogVisible": false,
      "downloadEnabled": false
    },
    {
      "id": "pending_review",
      "label": "Pending review",
      "publicCatalogVisible": false,
      "downloadEnabled": false
    },
    {
      "id": "changes_requested",
      "label": "Changes requested",
      "publicCatalogVisible": false,
      "downloadEnabled": false
    },
    {
      "id": "approved",
      "label": "Approved",
      "publicCatalogVisible": false,
      "downloadEnabled": false
    },
    {
      "id": "published",
      "label": "Published",
      "publicCatalogVisible": true,
      "downloadEnabled": true
    },
    {
      "id": "rejected",
      "label": "Rejected",
      "publicCatalogVisible": false,
      "downloadEnabled": false
    },
    {
      "id": "hidden",
      "label": "Hidden",
      "publicCatalogVisible": false,
      "downloadEnabled": false
    },
    {
      "id": "superseded",
      "label": "Superseded",
      "publicCatalogVisible": true,
      "downloadEnabled": true
    }
  ],
  "transitions": [
    {
      "from": "draft",
      "to": "uploaded",
      "actor": "modder"
    },
    {
      "from": "uploaded",
      "to": "validating",
      "actor": "system"
    },
    {
      "from": "validating",
      "to": "validation_failed",
      "actor": "system"
    },
    {
      "from": "validation_failed",
      "to": "cancelled",
      "actor": "modder"
    },
    {
      "from": "validating",
      "to": "pending_review",
      "actor": "system"
    },
    {
      "from": "pending_review",
      "to": "changes_requested",
      "actor": "moderator"
    },
    {
      "from": "pending_review",
      "to": "rejected",
      "actor": "moderator"
    },
    {
      "from": "pending_review",
      "to": "approved",
      "actor": "moderator"
    },
    {
      "from": "approved",
      "to": "published",
      "actor": "system"
    },
    {
      "from": "published",
      "to": "hidden",
      "actor": "moderator"
    },
    {
      "from": "published",
      "to": "superseded",
      "actor": "system"
    }
  ],
  "validationChecks": [
    {
      "id": "sidecar_schema",
      "required": true,
      "description": "Sidecar metadata must use smmods.mod-release-submission.v1."
    },
    {
      "id": "manifest_schema",
      "required": true,
      "description": "Package manifest must match the Starminer mod manifest schema."
    },
    {
      "id": "manifest_identity",
      "required": true,
      "description": "Manifest id, name, version, and targetGameBuild must match sidecar release metadata."
    },
    {
      "id": "semantic_version",
      "required": true,
      "description": "Release version must be semantic and must not reuse an existing immutable artifact URL."
    },
    {
      "id": "target_game_build",
      "required": true,
      "description": "Release targetGameBuild must match the pinned runtime/framework build policy."
    },
    {
      "id": "backend_readiness",
      "required": true,
      "description": "Backend auth, upload storage, validation workers, moderation, catalog publishing, audit logs, and public smoke must be ready before uploads go live."
    },
    {
      "id": "dependency_contract",
      "required": true,
      "description": "Sidecar dependencies must match manifest dependencies and remain manager-readable."
    },
    {
      "id": "zip_path_safety",
      "required": true,
      "description": "ZIP entries must be relative, must not contain traversal, and executable files must stay under Binaries/Win64."
    },
    {
      "id": "entrypoint_presence",
      "required": true,
      "description": "Every manifest entrypoint path must exist inside the uploaded ZIP."
    },
    {
      "id": "mod_config_contract",
      "required": true,
      "description": "Optional modConfig metadata must declare safe JSON config paths, select settings, defaults, and allowed option values."
    },
    {
      "id": "artifact_hash",
      "required": true,
      "description": "Publication computes SHA256 from the exact immutable artifact served by smmods.com."
    },
    {
      "id": "detail_page",
      "required": true,
      "description": "A public mod detail page must exist before catalog publication."
    },
    {
      "id": "manager_catalog_parse",
      "required": true,
      "description": "The current smmodmanager build must parse catalog.json after publication."
    },
    {
      "id": "public_smoke",
      "required": true,
      "description": "Public smoke must fetch JSON endpoints, download artifacts, verify hashes, and run manager URL readers."
    }
  ],
  "publicationOutputs": [
    "/downloads/mods/{modId}/{version}/{fileName}",
    "/api/v1/catalog.json",
    "/api/v1/mods/index.json",
    "/api/v1/mods/{modId}/index.json",
    "/api/v1/mods/{modId}/versions.json"
  ],
  "manualFallback": {
    "active": true,
    "tool": "tools/Import-ModRelease.ps1",
    "runbook": "docs/manual-publishing.md",
    "sidecarSchema": "public/api/v1/publishing/mod-release-submission.schema.json",
    "sidecarExample": "docs/mod-release-submission.example.json",
    "command": ".\\tools\\Import-ModRelease.ps1 -PackagePath \"E:\\path\\to\\mod-1.2.3.zip\" -MetadataPath \"E:\\path\\to\\mod-1.2.3.release.json\""
  }
}
