NEO-144: add contract template schemas and prototype catalog

Lock ContractTemplate row shape and the single frozen repeat-combat-pocket template for CI.
pull/184/head
VinPropane 2026-06-20 19:18:56 -04:00
parent c7a9e81067
commit 58d2c32152
3 changed files with 103 additions and 0 deletions

View File

@ -0,0 +1,20 @@
{
"schemaVersion": 1,
"contractTemplates": [
{
"id": "prototype_contract_clear_combat_pocket",
"displayName": "Clear Combat Pocket (Repeat)",
"zoneDifficultyBand": 1,
"objectiveKind": "encounter_clear",
"encounterTemplateId": "prototype_combat_pocket",
"minFactionStanding": {
"factionId": "prototype_faction_grid_operators",
"minStanding": 0
},
"completionRewardBundle": {
"itemGrants": [{ "itemId": "scrap_metal_bulk", "quantity": 5 }],
"skillXpGrants": [{ "skillId": "salvage", "amount": 15 }]
}
}
]
}

View File

@ -0,0 +1,31 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://neon-sprawl.local/schemas/contract-seed.json",
"title": "ContractSeed",
"description": "Inputs for contract issuance (POST …/contracts/issue body or audit record). Validated when HTTP wiring lands (NEO-147+). See docs/decomposition/modules/E7_M4_ContractMissionGenerator.md.",
"type": "object",
"additionalProperties": false,
"required": ["playerId", "templateId", "seedBucket"],
"properties": {
"playerId": {
"type": "string",
"minLength": 1,
"description": "Target player id for deterministic contractInstanceId suffix."
},
"templateId": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]*$",
"description": "Contract template id from content/contracts; omit selection logic uses band + standing filters."
},
"seedBucket": {
"type": "string",
"minLength": 1,
"description": "Deterministic rotation bucket (date string or client counter) for audit and instance id hashing."
},
"zoneDifficultyBand": {
"type": "integer",
"minimum": 1,
"description": "Optional issue-time band override; prototype defaults to 1 when omitted."
}
}
}

View File

@ -0,0 +1,52 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://neon-sprawl.local/schemas/contract-template.json",
"title": "ContractTemplate",
"description": "Single contract template row for catalogs (e.g. content/contracts/*_contract_templates.json). Repeatable mission skeleton keyed by zone difficulty band. See docs/decomposition/modules/E7_M4_ContractMissionGenerator.md.",
"type": "object",
"additionalProperties": false,
"required": [
"id",
"displayName",
"zoneDifficultyBand",
"objectiveKind",
"encounterTemplateId",
"minFactionStanding",
"completionRewardBundle"
],
"properties": {
"id": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]*$",
"description": "Immutable template key for issuance APIs and telemetry."
},
"displayName": {
"type": "string",
"minLength": 1,
"description": "Player-facing label; safe to change without migrating instance data."
},
"zoneDifficultyBand": {
"type": "integer",
"minimum": 1,
"description": "Difficulty band used to filter eligible templates at issue time (E4.M1 live zone deferred in Slice 4 v1)."
},
"objectiveKind": {
"type": "string",
"enum": ["encounter_clear"],
"description": "Objective discriminator; Slice 4 v1 binds encounterTemplateId only."
},
"encounterTemplateId": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]*$",
"description": "Encounter template id from content/encounters (E5.M3)."
},
"minFactionStanding": {
"$ref": "https://neon-sprawl.local/schemas/faction-gate-rule.json",
"description": "Minimum faction standing required to issue this template."
},
"completionRewardBundle": {
"$ref": "https://neon-sprawl.local/schemas/quest-reward-bundle.json",
"description": "Repeat completion payout delivered via RewardRouterOperations (E7.M2); separate idempotency from quest and first-time encounter loot."
}
}
}