feat(P1): event emitters — CloudEvents envelope, Decision Ledger, Infracost adapter, attestation/confidence/policy event emission
P1 (Wave 1, feat) — REQ-187, REQ-188, REQ-205 (emitter), REQ-206 (emitter) New components: - core/metrics/event_envelope.py — CloudEvents 1.0 envelope + platform.* conventions - core/metrics/run_manifest.py — per-run manifest writer (nova.run.started/completed/failed) - core/metrics/decision_ledger.py — SQLite append-only hash-chain (ai.decision.made + attestation.recorded) - core/metrics/infracost_adapter.py — Infracost post-processor (degraded mode when CLI absent, A6) - schemas/metrics_event.schema.json — CloudEvents envelope schema - schemas/metrics_run_manifest.schema.json — per-run manifest schema - metrics/README.md — backup/restore doc (REQ-201) - tests/test_metrics_emitters.py — 16 tests (all pass) Modified components: - core/confidence_signal.py — emits nova.confidence.computed + nova.ai.decision.made (D-122) - core/hitl_gates.py — emits nova.attestation.recorded on qa/prod/dr gates (D-132) - adapters/terraform/policy/checkov_adapter.py — emits nova.policy.evaluated - pyproject.toml — addopts gains --junitxml + --json-report + --cov (REQ-206) - .gitignore — metrics runtime artifacts ignored D-120: Nova-native (JSONL + SQLite, no Kafka/OTel) D-121: Decision Ledger = outbox_writer extension → SQLite hash-chain D-122: AI decision = confidence_signal + HITL gate (not LLM) D-128: metrics/ at repo root D-132: Attestation instrumentation ---ci--- project: acdl phase: 1 milestone: v1.17 status: execute ---/ci---
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Nova Per-Run Manifest",
|
||||
"description": "Per-run manifest written to metrics/runs/<run_id>.json (REQ-187). Captures the full run lifecycle.",
|
||||
"type": "object",
|
||||
"required": ["run_id", "contract_id", "environment", "started_at", "completed_at", "exit_code", "stages"],
|
||||
"properties": {
|
||||
"run_id": {"type": "string", "minLength": 1},
|
||||
"contract_id": {"type": "string"},
|
||||
"environment": {"type": "string", "enum": ["dev", "qa", "prod", "dr"]},
|
||||
"started_at": {"type": "string", "format": "date-time"},
|
||||
"completed_at": {"type": "string", "format": "date-time"},
|
||||
"exit_code": {"type": "integer"},
|
||||
"stages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["name", "duration_ms", "exit_code"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"duration_ms": {"type": "number"},
|
||||
"exit_code": {"type": "integer"},
|
||||
"error": {"type": "string"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"confidence": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"score": {"type": "number"},
|
||||
"band": {"type": "string", "enum": ["pass", "warn", "block"]},
|
||||
"perInput": {"type": "object"}
|
||||
}
|
||||
},
|
||||
"hitl": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"gate": {"type": "string"},
|
||||
"result": {"type": "string"},
|
||||
"block": {"type": "boolean"}
|
||||
}
|
||||
},
|
||||
"policy": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"passed": {"type": "integer"},
|
||||
"failed": {"type": "integer"},
|
||||
"skipped": {"type": "integer"}
|
||||
}
|
||||
},
|
||||
"cost_estimate_usd": {"type": "number"},
|
||||
"decision_id": {"type": "string"},
|
||||
"outcome": {"type": "string", "enum": ["succeeded", "failed", "pending"]}
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
Reference in New Issue
Block a user