# Submission Readiness — What is Acceptable to Start

> **Source of truth:** `schemas/submission-readiness.schema.json` (v1.18,
> REQ-217). The validator is `core/submission_readiness.py` (REQ-218),
> invoked as `python3 -m core.lambda.contract_ingestor --check-readiness
> <submission.json>` (D-133).

Nova's submission-readiness gate defines what is **acceptable to start**.
It is a superset gate *above* contract-schema validity: the contract schema
(`schemas/contract.schema.json`) defines the **shape** (id / name /
environment / infrastructure); the readiness schema defines the **gate**
(tags, per-env mandatory metadata, policy preconditions, profile markers,
appSource). Both must pass before ingestion proceeds.

## How It Works

```
citizen developer submits
        ↓
contract.schema.json validation (shape)     ← the existing check
        ↓
submission-readiness.schema.json (gate)     ← the new check
  ├── contractId present (non-empty)
  ├── environment valid (dev/qa/prod/dr)
  ├── tags: all 5 Nova tags present (D-054)
  ├── policyPreconditions declared
  ├── profile: developer or agentic
  │     └── if agentic: naturalLanguageIntent + confidenceAtSubmission + agentTrace
  ├── appSource: repo + ref (for runtime fetch)
  └── per-env mandatory (W3.E):
        dev  → stack + environment
        qa   → + validation.e2eSuite + validation.loadTest
        prod → + runbook + dashboard + oncall
        dr   → + drDrillRef
        ↓
ready → proceed to contract ingestion
not ready → reject with citizen-developer-facing error (reason code)
```

## Reason Codes

When a submission is not ready, the validator returns one or more reason
codes. These are citizen-developer-facing — no stack traces.

| Code | Meaning |
|---|---|
| `MISSING_TAGS:<tag1>,<tag2>` | One or more required Nova tags are absent |
| `ENV_MISSING_MANDATORY:<env>:<field>` | A per-env mandatory field (W3.E) is missing |
| `AGENTIC_MISSING_INTENT:<marker>` | profile=agentic but a required marker is absent |
| `MISSING_APP_SOURCE` | appSource (repo + ref) is missing |
| `POLICY_PRECONDITION_MISSING` | No policy preconditions declared |
| `CONTRACT_SCHEMA_INVALID:<detail>` | The contract shape failed contract.schema.json |
| `READINESS_SCHEMA_INVALID:<detail>` | The submission failed the readiness schema |

## Good Example

```json
{
  "contractId": "uuid-1234",
  "id": "webapi",
  "name": "Customer Web API",
  "environment": "dev",
  "tags": {
    "nova:owner": "consumer-repo",
    "nova:contract": "uuid-1234",
    "nova:environment": "dev",
    "nova:cost-center": "nova-default",
    "nova:ref": "CHG0678912"
  },
  "policyPreconditions": {
    "public-ingress": false,
    "encryption_enabled": true,
    "deletion_protection": true
  },
  "profile": "developer",
  "appSource": {
    "repo": "consumer/web-api",
    "ref": "main"
  },
  "infrastructure": {
    "static-assets": {
      "inputs": {
        "bucket_name": "webapi-assets"
      }
    }
  }
}
```

Result: **READY** — passes the shape + the gate.

## Rejected Examples

### Missing Tags

```json
{
  "contractId": "uuid-1234",
  "environment": "dev",
  "tags": {
    "nova:owner": "consumer-repo"
  },
  "policyPreconditions": {"public-ingress": false},
  "profile": "developer",
  "appSource": {"repo": "consumer/repo", "ref": "main"}
}
```

Result: `NOT READY — MISSING_TAGS:nova:contract,nova:environment,nova:cost-center,nova:ref`

### Agentic Missing Intent

```json
{
  "contractId": "uuid-1234",
  "environment": "qa",
  "tags": { "nova:owner": "x", "nova:contract": "x", "nova:environment": "qa", "nova:cost-center": "x", "nova:ref": "x" },
  "policyPreconditions": {"public-ingress": false},
  "profile": "agentic",
  "appSource": {"repo": "x", "ref": "x"},
  "validation": {"e2eSuite": true, "loadTest": true}
}
```

Result: `NOT READY — AGENTIC_MISSING_INTENT:naturalLanguageIntent; AGENTIC_MISSING_INTENT:confidenceAtSubmission; AGENTIC_MISSING_INTENT:agentTrace`

### Env Missing Mandatory (prod without runbook)

```json
{
  "contractId": "uuid-1234",
  "environment": "prod",
  "tags": { "nova:owner": "x", "nova:contract": "x", "nova:environment": "prod", "nova:cost-center": "x", "nova:ref": "x" },
  "policyPreconditions": {"public-ingress": false},
  "profile": "developer",
  "appSource": {"repo": "x", "ref": "x"}
}
```

Result: `NOT READY — ENV_MISSING_MANDATORY:prod:runbook; ENV_MISSING_MANDATORY:prod:dashboard; ENV_MISSING_MANDATORY:prod:oncall`

## Compliance-Standard Equivalence

The submission-readiness gate applies **equally** to all upstream sources.
Whether the citizen developer's submission originated from an AI coding
agent, an agentic SDLC platform, or a traditional development platform —
the same tags, the same env mandatory, the same policy preconditions, the
same profile markers are required. The source does not matter; the
submission does. This is the RACI compliance-standard equivalence note
(`docs/raci.md`) made machine-checkable.