445 lines
13 KiB
JSON
445 lines
13 KiB
JSON
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"$id": "https://jyotisha.chat/contracts/personal-report/report-document.v1.schema.json",
|
|
"title": "ReportDocument v1",
|
|
"description": "Server-issued personal astrology report document. This contract is enforced identically by the JSON Schema below, frontend/src/lib/personal-report-contract.ts (Zod), and scripts/personal_report_contract.py (stdlib Python validator). Semantics that JSON Schema draft-07 cannot express are enforced by both runtime validators and their tests: (1) charts must contain exactly one D1 chart, chart ids must be unique, and the D1 chart must contain all twelve house numbers 1..12 (enough real houses to render without fabrication); (2) every houseNumber must be unique within its chart; (3) evidence ids (id fields of techniqueAudit, conflicts and calculationEvidence rows) must be globally unique across the whole evidence appendix so evidenceRefs are never ambiguous; (4) provenance.evidenceHash is a deterministic recomputation over the evidence appendix (techniqueAudit, conflicts, calculationEvidence in canonical field order) - it is never trusted as a model self-report; the cryptographic hash is verified by the server runtime (frontend/src/lib/personal-report-contract.server.ts) and by the Python validator (scripts/personal_report_contract.py), and a document whose evidenceHash does not equal the recomputed value is rejected; the isomorphic frontend contract validates structure only and never recomputes the hash; (5) every entry in evidenceRefs must reference an id present in evidenceAppendix.techniqueAudit, evidenceAppendix.conflicts, or evidenceAppendix.calculationEvidence; (6) sections whose claimStatus is blocked must not contain deterministic predictions (e.g. 必然, 必定, 一定会, 肯定会, 绝对会, guaranteed, definitely will); (7) the UTF-8 JSON serialization of the whole document must not exceed 1572864 bytes (1.5 MiB). Fixed reader order: this schema defines the display sequence executiveSummary, thematicNarrative, evidenceAppendix as a UI/type-level presentation contract; JSON object key order is not validated (objects are unordered by definition). Privacy rule: subject/provenance metadata must never repeat full birth date, precise coordinates, or a raw chart payload. Content rule: no HTML/JS/CSS, no executable URLs (javascript:, vbscript:, data:text/html, file:), no internal filesystem paths, no prompt/tool traces or exception stacks, no model secrets or JWTs.",
|
|
"type": "object",
|
|
"definitions": {
|
|
"claimStatus": {
|
|
"type": "string",
|
|
"enum": [
|
|
"multi_system_consensus",
|
|
"single_system_inference",
|
|
"parameter_sensitive",
|
|
"unclosed_divisional_chart",
|
|
"user_history_verification_required",
|
|
"blocked"
|
|
]
|
|
},
|
|
"evidenceId": {
|
|
"type": "string",
|
|
"pattern": "^ev-[a-z0-9_-]{1,63}$",
|
|
"minLength": 4,
|
|
"maxLength": 67
|
|
},
|
|
"sha256Hex": {
|
|
"type": "string",
|
|
"pattern": "^[0-9a-f]{64}$",
|
|
"minLength": 64,
|
|
"maxLength": 64
|
|
},
|
|
"iso8601": {
|
|
"type": "string",
|
|
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$",
|
|
"minLength": 20,
|
|
"maxLength": 40
|
|
},
|
|
"house": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"houseNumber": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 12
|
|
},
|
|
"sign": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 40
|
|
},
|
|
"occupants": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 40
|
|
},
|
|
"maxItems": 12
|
|
}
|
|
},
|
|
"required": ["houseNumber", "sign", "occupants"]
|
|
},
|
|
"planet": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 40
|
|
},
|
|
"sign": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 40
|
|
},
|
|
"longitudeDegrees": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"exclusiveMaximum": 360
|
|
},
|
|
"houseNumber": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 12
|
|
},
|
|
"retrograde": {
|
|
"type": "boolean"
|
|
}
|
|
},
|
|
"required": ["name", "sign", "longitudeDegrees", "houseNumber", "retrograde"]
|
|
},
|
|
"chart": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"enum": ["D1", "D9", "D10"]
|
|
},
|
|
"title": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 120
|
|
},
|
|
"houses": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/house"
|
|
},
|
|
"maxItems": 12
|
|
},
|
|
"planets": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/planet"
|
|
},
|
|
"maxItems": 12
|
|
},
|
|
"claimStatus": {
|
|
"$ref": "#/definitions/claimStatus"
|
|
}
|
|
},
|
|
"required": ["id", "title", "houses", "claimStatus"]
|
|
},
|
|
"thematicSection": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"pattern": "^[a-z][a-z0-9_-]{0,63}$",
|
|
"minLength": 1,
|
|
"maxLength": 64
|
|
},
|
|
"title": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 160
|
|
},
|
|
"narrative": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 4000
|
|
},
|
|
"actions": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 400
|
|
},
|
|
"maxItems": 12
|
|
},
|
|
"caveats": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 400
|
|
},
|
|
"maxItems": 12
|
|
},
|
|
"claimStatus": {
|
|
"$ref": "#/definitions/claimStatus"
|
|
},
|
|
"evidenceRefs": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/evidenceId"
|
|
},
|
|
"maxItems": 24
|
|
}
|
|
},
|
|
"required": ["id", "title", "narrative", "actions", "caveats", "claimStatus", "evidenceRefs"]
|
|
},
|
|
"techniqueAuditRow": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"id": {
|
|
"$ref": "#/definitions/evidenceId"
|
|
},
|
|
"techniqueId": {
|
|
"type": "string",
|
|
"pattern": "^[a-z0-9_.-]{1,80}$",
|
|
"minLength": 1,
|
|
"maxLength": 80
|
|
},
|
|
"techniqueName": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 160
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"enum": ["verified", "partial", "blocked"]
|
|
},
|
|
"used": {
|
|
"type": "boolean"
|
|
},
|
|
"notes": {
|
|
"type": "string",
|
|
"maxLength": 500
|
|
}
|
|
},
|
|
"required": ["id", "techniqueId", "techniqueName", "status", "used"]
|
|
},
|
|
"conflictRow": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"id": {
|
|
"$ref": "#/definitions/evidenceId"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 1000
|
|
},
|
|
"impact": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 500
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"enum": ["unresolved", "partial", "resolved"]
|
|
}
|
|
},
|
|
"required": ["id", "description", "impact", "status"]
|
|
},
|
|
"calculationEvidenceRow": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"id": {
|
|
"$ref": "#/definitions/evidenceId"
|
|
},
|
|
"label": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 160
|
|
},
|
|
"value": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 500
|
|
},
|
|
"source": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 200
|
|
}
|
|
},
|
|
"required": ["id", "label", "value", "source"]
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"schemaVersion": {
|
|
"type": "string",
|
|
"const": "report_document.v1"
|
|
},
|
|
"reportId": {
|
|
"type": "string",
|
|
"format": "uuid",
|
|
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
|
|
},
|
|
"reportType": {
|
|
"type": "string",
|
|
"enum": ["personal_full", "personal_thematic"]
|
|
},
|
|
"presentationMode": {
|
|
"type": "string",
|
|
"enum": ["default", "research"]
|
|
},
|
|
"generatedAt": {
|
|
"$ref": "#/definitions/iso8601"
|
|
},
|
|
"subject": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"displayName": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 120
|
|
},
|
|
"birthTimeStatus": {
|
|
"type": "string",
|
|
"enum": ["reported", "candidate", "accepted", "confirmed"]
|
|
},
|
|
"birthPlaceLabel": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 200
|
|
}
|
|
},
|
|
"required": ["displayName", "birthTimeStatus", "birthPlaceLabel"]
|
|
},
|
|
"provenance": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"skillName": {
|
|
"type": "string",
|
|
"pattern": "^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$",
|
|
"minLength": 1,
|
|
"maxLength": 120
|
|
},
|
|
"skillVersion": {
|
|
"type": "string",
|
|
"pattern": "^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$",
|
|
"minLength": 5,
|
|
"maxLength": 80
|
|
},
|
|
"skillSourceCommit": {
|
|
"type": ["string", "null"],
|
|
"pattern": "^[0-9a-f]{40}$",
|
|
"minLength": 40,
|
|
"maxLength": 40
|
|
},
|
|
"skillSnapshotSha256": {
|
|
"$ref": "#/definitions/sha256Hex"
|
|
},
|
|
"calculationHash": {
|
|
"$ref": "#/definitions/sha256Hex"
|
|
},
|
|
"evidenceHash": {
|
|
"$ref": "#/definitions/sha256Hex"
|
|
},
|
|
"reportContractVersion": {
|
|
"type": "string",
|
|
"const": "1"
|
|
}
|
|
},
|
|
"required": ["skillSourceCommit", "skillSnapshotSha256", "calculationHash", "evidenceHash", "reportContractVersion"]
|
|
},
|
|
"executiveSummary": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"headline": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 200
|
|
},
|
|
"summary": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 2000
|
|
},
|
|
"priorities": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 200
|
|
},
|
|
"maxItems": 8
|
|
},
|
|
"overallClaimStatus": {
|
|
"$ref": "#/definitions/claimStatus"
|
|
}
|
|
},
|
|
"required": ["headline", "summary", "priorities", "overallClaimStatus"]
|
|
},
|
|
"charts": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/chart"
|
|
},
|
|
"minItems": 1,
|
|
"maxItems": 3
|
|
},
|
|
"thematicNarrative": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/thematicSection"
|
|
},
|
|
"maxItems": 12
|
|
},
|
|
"evidenceAppendix": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"expandedByDefault": {
|
|
"type": "boolean"
|
|
},
|
|
"techniqueAudit": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/techniqueAuditRow"
|
|
},
|
|
"maxItems": 100
|
|
},
|
|
"conflicts": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/conflictRow"
|
|
},
|
|
"maxItems": 50
|
|
},
|
|
"calculationEvidence": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/calculationEvidenceRow"
|
|
},
|
|
"maxItems": 100
|
|
},
|
|
"blockedTechniques": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 120
|
|
},
|
|
"maxItems": 100
|
|
}
|
|
},
|
|
"required": ["expandedByDefault", "techniqueAudit", "conflicts", "calculationEvidence", "blockedTechniques"]
|
|
},
|
|
"disclaimer": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 2000
|
|
}
|
|
},
|
|
"required": [
|
|
"schemaVersion",
|
|
"reportId",
|
|
"reportType",
|
|
"presentationMode",
|
|
"generatedAt",
|
|
"subject",
|
|
"provenance",
|
|
"executiveSummary",
|
|
"charts",
|
|
"thematicNarrative",
|
|
"evidenceAppendix",
|
|
"disclaimer"
|
|
]
|
|
}
|