feat(posture): add deterministic feedback proposals
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
This commit is contained in:
tegwick 2026-08-23 13:16:34 +02:00
parent dc8da422f8
commit cfc9e7d0cb
19 changed files with 1428 additions and 16 deletions

View file

@ -0,0 +1,145 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://netkingdom.local/schemas/posture-feedback-report_v0.1.schema.json",
"title": "NetKingdom Posture Feedback Report v0.1",
"type": "object",
"additionalProperties": false,
"required": [
"apiVersion",
"kind",
"ok",
"as_of",
"horizon_days",
"fail_on",
"automation",
"summary",
"validation_errors",
"findings",
"report_digest"
],
"properties": {
"apiVersion": {
"const": "netkingdom.io/posture-feedback/v0.1"
},
"kind": {
"const": "PostureFeedbackReport"
},
"ok": {
"type": "boolean"
},
"as_of": {
"type": "string",
"format": "date-time"
},
"horizon_days": {
"type": "integer",
"minimum": 0
},
"fail_on": {
"enum": ["none", "low", "medium", "high"]
},
"automation": {
"type": "object",
"additionalProperties": false,
"required": [
"mode",
"external_write_permitted",
"policy_mutation_permitted",
"declaration_mutation_permitted"
],
"properties": {
"mode": {"const": "proposal-only"},
"external_write_permitted": {"const": false},
"policy_mutation_permitted": {"const": false},
"declaration_mutation_permitted": {"const": false}
}
},
"summary": {
"type": "object",
"additionalProperties": false,
"required": ["total", "high", "medium", "low", "unknown_owner"],
"properties": {
"total": {"type": "integer", "minimum": 0},
"high": {"type": "integer", "minimum": 0},
"medium": {"type": "integer", "minimum": 0},
"low": {"type": "integer", "minimum": 0},
"unknown_owner": {"type": "integer", "minimum": 0}
}
},
"validation_errors": {
"type": "array",
"items": {"type": "string", "minLength": 1}
},
"findings": {
"type": "array",
"items": {
"$ref": "#/$defs/finding"
}
},
"report_digest": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{64}$"
}
},
"$defs": {
"finding": {
"type": "object",
"additionalProperties": false,
"required": [
"id",
"class",
"severity",
"source",
"service",
"control",
"owner",
"evidence_state",
"reason",
"recommended_action"
],
"properties": {
"id": {
"type": "string",
"pattern": "^NKFB-[0-9a-f]{16}$"
},
"class": {
"enum": [
"posture-review-overdue",
"posture-review-due-soon",
"zone-review-overdue",
"zone-review-due-soon",
"evidence-freshness-unknown",
"evidence-expired",
"evidence-due-soon",
"implemented-not-evidenced",
"declared-gap"
]
},
"severity": {
"enum": ["low", "medium", "high"]
},
"source": {"type": "string", "minLength": 1},
"service": {"type": "string", "minLength": 1},
"control": {"type": "string", "minLength": 1},
"owner": {"type": "string", "minLength": 1},
"evidence_state": {
"enum": [
"not-applicable",
"due-soon",
"overdue",
"unknown",
"expired",
"implemented",
"gap"
]
},
"due": {
"type": "string",
"minLength": 1
},
"reason": {"type": "string", "minLength": 1},
"recommended_action": {"type": "string", "minLength": 1}
}
}
}
}

View file

@ -21,6 +21,9 @@
"type": "string",
"minLength": 1
},
"responsible_repo": {
"$ref": "#/$defs/repoName"
},
"workload_identity": {
"$ref": "#/$defs/workloadIdentity"
},
@ -36,6 +39,9 @@
"evidence": {
"$ref": "#/$defs/evidence"
},
"evidence_freshness": {
"$ref": "#/$defs/evidenceFreshness"
},
"notes": {
"$ref": "#/$defs/stringList"
},
@ -100,6 +106,16 @@
"required": [
"evidence"
]
},
{
"required": [
"responsible_repo"
]
},
{
"required": [
"evidence_freshness"
]
}
]
}
@ -601,6 +617,76 @@
]
}
},
"evidenceFreshnessEntry": {
"type": "object",
"required": [
"kind",
"observed_at",
"responsible_repo",
"scope",
"remediation"
],
"properties": {
"kind": {
"enum": [
"mechanical",
"adversarial"
]
},
"observed_at": {
"type": "string",
"format": "date-time"
},
"valid_until": {
"type": "string",
"format": "date-time"
},
"responsible_repo": {
"$ref": "#/$defs/repoName"
},
"scope": {
"type": "string",
"minLength": 1
},
"remediation": {
"type": "string",
"minLength": 1
},
"source_revision": {
"type": "string",
"minLength": 1
}
},
"allOf": [
{
"if": {
"properties": {
"kind": {
"const": "adversarial"
}
},
"required": [
"kind"
]
},
"then": {
"required": [
"valid_until"
]
}
}
],
"additionalProperties": false
},
"evidenceFreshness": {
"type": "object",
"patternProperties": {
"^[IAEPRV][0-4]$": {
"$ref": "#/$defs/evidenceFreshnessEntry"
}
},
"additionalProperties": false
},
"service": {
"type": "object",
"required": [
@ -616,6 +702,9 @@
"type": "string",
"minLength": 1
},
"responsible_repo": {
"$ref": "#/$defs/repoName"
},
"workload_identity": {
"$ref": "#/$defs/workloadIdentity"
},
@ -628,6 +717,9 @@
"evidence": {
"$ref": "#/$defs/evidence"
},
"evidence_freshness": {
"$ref": "#/$defs/evidenceFreshness"
},
"notes": {
"$ref": "#/$defs/stringList"
},