feat: implement RMASTER-WP-0023 private-by-default exposure

Add the exposure contract, additive family schema fields, validator
checks and fixtures, the reef-railiance exception snapshot, and
routed intakes. Enforcement stays in the owning repos.
This commit is contained in:
codex 2026-08-15 20:08:37 +02:00
parent 6301798fab
commit 4a664533d3
24 changed files with 998 additions and 13 deletions

View file

@ -78,8 +78,46 @@
"type": "array",
"minItems": 1,
"items": { "$ref": "#/$defs/sourceDocument" }
},
"exposure": {
"type": "object",
"additionalProperties": false,
"required": ["posture"],
"description": "Host-port and public-DNS surface this reef publishes. Optional; omitted means private (ADR-0008). public is a substrate grant, not reef lifecycle_state. Provider-delegated reefs must not set public.",
"properties": {
"posture": {
"enum": ["private", "operator", "public"],
"description": "Default if exposure is omitted: private."
},
"grants": {
"type": "array",
"minItems": 1,
"items": { "$ref": "#/$defs/exposureGrant" },
"description": "Substrate grants. Required by schema when posture is public."
},
"tunnel": { "$ref": "#/$defs/exposureTunnel" }
}
}
},
"allOf": [
{
"description": "public reef exposure requires at least one substrate grant.",
"if": {
"required": ["exposure"],
"properties": {
"exposure": {
"required": ["posture"],
"properties": { "posture": { "const": "public" } }
}
}
},
"then": {
"properties": {
"exposure": { "required": ["grants"] }
}
}
}
],
"$defs": {
"repoSlug": {
"type": "string",
@ -111,6 +149,35 @@
"repo": { "$ref": "#/$defs/repoSlug" },
"path": { "type": "string", "minLength": 1 }
}
},
"exposureGrant": {
"type": "object",
"additionalProperties": false,
"required": ["reason", "approved_on", "residual_risk_owner"],
"description": "Accepted residual risk for a reef host port or public DNS name we publish. Must name a hostname or a port. Port 6443 is rejected by the validator.",
"properties": {
"hostname": { "type": "string", "minLength": 1 },
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
"reason": { "type": "string", "minLength": 1 },
"approved_on": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
"residual_risk_owner": { "type": "string", "minLength": 1 }
},
"anyOf": [
{ "required": ["hostname"] },
{ "required": ["port"] }
]
},
"exposureTunnel": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"description": "Named ops-bridge / SSH path to this reef. Does not change packet posture.",
"properties": {
"name": { "type": "string", "minLength": 1 },
"local_port": { "type": "integer", "minimum": 1, "maximum": 65535 }
}
}
}
}