# DGen 5.0 scene API contract v1.1 (working interface)

This is a machine payload interface, not the RP player agreement. DGen / Wall of Degenerates belongs to 5.0. Hardcore 64 is a separate 4.0 player-contract program.

Status: usable schema and validation endpoint; ingestion and scoring are not implemented. Coordinate changes with the bot agent before treating this as final.

## Available now

- `GET /handoff/dgen-scene.v1.1.schema.json`: current JSON Schema.
- `GET /handoff/dgen-scene.v1.1.example.json`: current fictional fixture, not real account IDs.
- `POST /api/dgen/validate`: validates a JSON payload of at most 16 KiB. A 200 response means `valid: true, stored: false`. Nothing is stored or scored.
- Canonical TypeScript validator: `lib/dgen-contract.ts`.

The Site audience was public when checked on September 22, 2026. The current endpoint only validates shape and performs no persistence. Future ingest must use an explicitly configured supported service-access path and authenticate the bot; public website access does not authorize ingest. Do not embed user session cookies or provider tokens in a bot payload.

## Version and program boundary

v1.1 explicitly requires `program_id: "dgen"` and `server_era: "V"`. It adds `participant_agreement_version`, `activity_catalog_version`, and `activity_code`; `rubric_version` identifies the selected DGen rubric. The provisional `pursuit.unspecified` fixture is illustrative, not a verified 5.0 crime catalog entry.

Do not silently break independently developing bots: the old v1 schema/fixture remain available at their original paths. The validator still accepts valid v1 shapes and returns `migration_required: true`; v1.1 returns false. Neither version stores events. A future production ingest service must require the current program-specific envelope and server-owned active agreement records; a submitted version string does not prove acceptance.

No 4.0 hardcore event should be relabeled as DGen 5.0. If a 5.0 group later adopts hardcore rules, define a distinct agreement namespace and character-stakes event contract. A down observed by DGen never constitutes a permaroll instruction by itself.

## Boundary

Observer → candidate interpretation → private evidence/review → confirmed event → derived scoreboard. Only the first payload shape exists here; no review or persistence endpoint is live.

`event_id` is a UUID for this immutable interpretation version. `scene_id` is stable across observations of the same scene. A future ingest service must enforce retry idempotency by event ID, detect changed-body collisions, and avoid counting overlapping scene observations as separate successes. Do not treat a new UUID as a new chase automatically. Multiple player perspectives may share a scene.

Discord and channel IDs are strings. The receiver must verify them against server-owned identity and active consent records; valid-looking IDs in JSON are not authentication. Character names are display data and may change. The program, server era, and agreement references prevent projects being mixed. A shared Discord ID is not shared enrollment.

The payload describes a completed scene. Timestamps must be UTC ISO-8601 strings; end cannot precede start and observation cannot precede end. Future ingestion should additionally bound clock skew and apply the agreed publication policy. Public timing/redaction rules still need an owner decision.

`apparent_outcome` is an AI claim, never an authoritative escape/death. `confidence` may be null and is not a probability of truth without calibration. `context` explicitly permits uncertainty. The receiving service must set its own review state and credit; incoming `score`, `verified`, `confirmed`, or `consent` fields are rejected by this strict schema.

`observation_basis` records frames, audio, or chat. IRC is chat transport; it does not provide gameplay screenshots. Chat alone cannot establish an in-game outcome. Capture/model integrations remain separate from the website.

`private_evidence_ref` is an opaque reference, never a public screenshot or signed media URL. Raw images, video, chat transcripts, and URLs are not part of this payload. A future public serializer must omit the private reference and Discord ID. Use private, access-controlled evidence storage with an agreed retention period.

## Responses

| Status | Meaning |
|---|---|
| 200 | Payload shape valid; stored false; legacy v1 flagged for migration |
| 400 | Missing body, malformed JSON, or unreadable body |
| 413 | Body exceeds 16 KiB, including when Content-Length is absent |
| 415 | Content-Type is not application/json |
| 422 | Schema or timestamp-order validation failed |

The read-only schema is Draft 2020-12. JSON Schema format validation varies by client; the TypeScript validator also enforces timestamp order and unique observation basis entries.

## Local verification

Run `node --experimental-strip-types --test tests/dgen-contract.test.mjs` and `node node_modules/typescript/bin/tsc --noEmit`.

## Integration work remaining

Confirm Discord auth support, authenticate the bot server-side, verify channel ownership and consent, add durable records with deduplication and audit history, establish reviewer roles, version the rubric and agreements, choose publication delay/redaction, and wire the feed to real data. Never replace the pending connection state with fabricated results.
