Add signal contracts for reachability, exploitability, trust, and unknown symbols
- Introduced `ReachabilityState`, `RuntimeHit`, `ExploitabilitySignal`, `ReachabilitySignal`, `SignalEnvelope`, `SignalType`, `TrustSignal`, and `UnknownSymbolSignal` records to define various signal types and their properties. - Implemented JSON serialization attributes for proper data interchange. - Created project files for the new signal contracts library and corresponding test projects. - Added deterministic test fixtures for micro-interaction testing. - Included cryptographic keys for secure operations with cosign.
This commit is contained in:
@@ -5,5 +5,5 @@
|
||||
"subject": "User signup",
|
||||
"body": "User john@example.com joined",
|
||||
"redacted_body": "User ***@example.com joined",
|
||||
"pii_hash": "TBD"
|
||||
"pii_hash": "dd4eefc8dded5d6f46c832e959ba0eef95ee8b77f10ac0aae90f7c89ad42906c"
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"template_id":"tmpl-incident-start","locale":"en-US","channel":"email","expected_hash":"TBD","body_sample_path":"tmpl-incident-start.email.en-US.json"}
|
||||
{"template_id":"tmpl-incident-start","locale":"en-US","channel":"email","expected_hash":"05eb80e384eaf6edf0c44a655ca9064ca4e88b8ad7cefa1483eda5c9aaface00","body_sample_path":"tmpl-incident-start.email.en-US.json"}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
"subject": "Incident started: ${incident_id}",
|
||||
"body": "Incident ${incident_id} started at ${started_at}. Severity: ${severity}.",
|
||||
"merge_fields": ["incident_id", "started_at", "severity"],
|
||||
"preview_hash": "TBD"
|
||||
"preview_hash": "05eb80e384eaf6edf0c44a655ca9064ca4e88b8ad7cefa1483eda5c9aaface00"
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ Close NR1–NR10 by defining contracts, evidence, and deterministic test hooks f
|
||||
- Add the above evidence paths to the NOTIFY-GAPS-171-014 task in `docs/implplan/SPRINT_0171_0001_0001_notifier_i.md` and mirror status in `src/Notifier/StellaOps.Notifier/TASKS.md`.
|
||||
- When artifacts land, append TRX/fixture links in the sprint **Execution Log** and reference this doc under **Decisions & Risks**.
|
||||
- Offline kit artefacts must mirror mirror/offline packaging rules (deterministic flags, time-anchor hook, PQ dual-sign toggle) already used by Mirror/Offline sprints.
|
||||
- Simulation evidence lives in `docs/notifications/simulations/` (index.ndjson + per-rule reports) and is validated by contract tests under `Contracts/PolicyDocsCompletenessTests.cs`.
|
||||
- Contract tests under `Contracts/` verify schema catalog ↔ DSSE alignment, fixture hashes, simulation index presence, and offline kit manifest/DSSE consistency.
|
||||
|
||||
## Next steps
|
||||
1) Generate initial schema catalog (`notify-schemas-catalog.json`) with rule/template/channel/webhook/receipt definitions and run canonicalization harness.
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
"hash_algorithm": "blake3-256",
|
||||
"canonicalization": "json-normalized-utf8",
|
||||
"entries": [
|
||||
{ "file": "event-envelope.schema.json", "digest": "TBD" },
|
||||
{ "file": "rule.schema.json", "digest": "TBD" },
|
||||
{ "file": "template.schema.json", "digest": "TBD" },
|
||||
{ "file": "channel.schema.json", "digest": "TBD" },
|
||||
{ "file": "receipt.schema.json", "digest": "TBD" },
|
||||
{ "file": "webhook.schema.json", "digest": "TBD" },
|
||||
{ "file": "dlq-notify.schema.json", "digest": "TBD" }
|
||||
{ "file": "event-envelope.schema.json", "digest": "0534e778a7e24dfdcbdc66cec2902f24684ec0bdf26d708ab9bca98e6674a318" },
|
||||
{ "file": "rule.schema.json", "digest": "34d4f1c2ba97b76acf85ad61f4e8de4591664eefecbc7ebb6d168aa5a998ddd1" },
|
||||
{ "file": "template.schema.json", "digest": "e0a8f9bb5e5f29a11b040e7cb0e7e9a8c5d42256f9a4bd72f79460eb613dac52" },
|
||||
{ "file": "channel.schema.json", "digest": "bd9e2dfb4e6e7e7a38f26cc94ae8bcdf9b8c44b1e97bf78c146711783fe8fa2b" },
|
||||
{ "file": "receipt.schema.json", "digest": "fb4431019b3803081983b215fc9ca2e7618c3cf91f8274baedf72cacad8dfe46" },
|
||||
{ "file": "webhook.schema.json", "digest": "54a6e0d956fd6af7e88f6508bda78221ca04cfedea4112bfefc7fa5dbfa45c09" },
|
||||
{ "file": "dlq-notify.schema.json", "digest": "1330e589245b923f6e1fea6af080b7b302a97effa360a90dbef4ba3b06021b2f" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
{
|
||||
"payloadType": "application/vnd.notify.schema-catalog+json",
|
||||
"payload": "BASE64_ENCODED_NOTIFY_SCHEMA_CATALOG_TBD",
|
||||
"signatures": [],
|
||||
"note": "Placeholder; replace with signed payload once BLAKE3 digest and signing key are available."
|
||||
"payload": "eyJjYW5vbmljYWxpemF0aW9uIjoianNvbi1ub3JtYWxpemVkLXV0ZjgiLCJjYXRhbG9nX3ZlcnNpb24iOiJ2MS4wIiwiZ2VuZXJhdGVkX2F0IjoiMjAyNS0xMi0wNFQwMDowMDowMFoiLCJoYXNoX2FsZ29yaXRobSI6ImJsYWtlMy0yNTYiLCJzY2hlbWFzIjpbeyJkaWdlc3QiOiIwNTM0ZTc3OGE3ZTI0ZGZkY2JkYzY2Y2VjMjkwMmYyNDY4NGVjMGJkZjI2ZDcwOGFiOWJjYTk4ZTY2NzRhMzE4IiwiZmlsZSI6ImV2ZW50LWVudmVsb3BlLnNjaGVtYS5qc29uIiwiaWQiOiJldmVudC1lbnZlbG9wZSIsInZlcnNpb24iOiJ2MS4wIn0seyJkaWdlc3QiOiIzNGQ0ZjFjMmJhOTdiNzZhY2Y4NWFkNjFmNGU4ZGU0NTkxNjY0ZWVmZWNiYzdlYmI2ZDE2OGFhNWE5OThkZGQxIiwiZmlsZSI6InJ1bGUuc2NoZW1hLmpzb24iLCJpZCI6InJ1bGUiLCJ2ZXJzaW9uIjoidjEuMCJ9LHsiZGlnZXN0IjoiZTBhOGY5YmI1ZTVmMjlhMTFiMDQwZTdjYjBlN2U5YThjNWQ0MjI1NmY5YTRiZDcyZjc5NDYwZWI2MTNkYWM1MiIsImZpbGUiOiJ0ZW1wbGF0ZS5zY2hlbWEuanNvbiIsImlkIjoidGVtcGxhdGUiLCJ2ZXJzaW9uIjoidjEuMCJ9LHsiZGlnZXN0IjoiYmQ5ZTJkZmI0ZTZlN2U3YTM4ZjI2Y2M5NGFlOGJjZGY5YjhjNDRiMWU5N2JmNzhjMTQ2NzExNzgzZmU4ZmEyYiIsImZpbGUiOiJjaGFubmVsLnNjaGVtYS5qc29uIiwiaWQiOiJjaGFubmVsIiwidmVyc2lvbiI6InYxLjAifSx7ImRpZ2VzdCI6ImZiNDQzMTAxOWIzODAzMDgxOTgzYjIxNWZjOWNhMmU3NjE4YzNjZjkxZjgyNzRiYWVkZjcyY2FjYWQ4ZGZlNDYiLCJmaWxlIjoicmVjZWlwdC5zY2hlbWEuanNvbiIsImlkIjoicmVjZWlwdCIsInZlcnNpb24iOiJ2MS4wIn0seyJkaWdlc3QiOiI1NGE2ZTBkOTU2ZmQ2YWY3ZTg4ZjY1MDhiZGE3ODIyMWNhMDRjZmVkZWE0MTEyYmZlZmM3ZmE1ZGJmYTQ1YzA5IiwiZmlsZSI6IndlYmhvb2suc2NoZW1hLmpzb24iLCJpZCI6IndlYmhvb2siLCJ2ZXJzaW9uIjoidjEuMCJ9LHsiZGlnZXN0IjoiMTMzMGU1ODkyNDViOTIzZjZlMWZlYTZhZjA4MGI3YjMwMmE5N2VmZmEzNjBhOTBkYmVmNGJhM2IwNjAyMWIyZiIsImZpbGUiOiJkbHEtbm90aWZ5LnNjaGVtYS5qc29uIiwiaWQiOiJkbHEiLCJ2ZXJzaW9uIjoidjEuMCJ9XX0=",
|
||||
"signatures": [
|
||||
{
|
||||
"sig": "99WPzzc6sCaEQHXk2B15aLxtG/Ics6qsgHYa2oDTI1g=",
|
||||
"keyid": "notify-dev-hmac-001",
|
||||
"signedAt": "2025-12-04T21:12:53+00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
"canonicalization": "json-normalized-utf8",
|
||||
"generated_at": "2025-12-04T00:00:00Z",
|
||||
"schemas": [
|
||||
{ "id": "event-envelope", "file": "event-envelope.schema.json", "version": "v1.0", "digest": "TBD" },
|
||||
{ "id": "rule", "file": "rule.schema.json", "version": "v1.0", "digest": "TBD" },
|
||||
{ "id": "template", "file": "template.schema.json", "version": "v1.0", "digest": "TBD" },
|
||||
{ "id": "channel", "file": "channel.schema.json", "version": "v1.0", "digest": "TBD" },
|
||||
{ "id": "receipt", "file": "receipt.schema.json", "version": "v1.0", "digest": "TBD" },
|
||||
{ "id": "webhook", "file": "webhook.schema.json", "version": "v1.0", "digest": "TBD" },
|
||||
{ "id": "dlq", "file": "dlq-notify.schema.json", "version": "v1.0", "digest": "TBD" }
|
||||
{ "id": "event-envelope", "file": "event-envelope.schema.json", "version": "v1.0", "digest": "0534e778a7e24dfdcbdc66cec2902f24684ec0bdf26d708ab9bca98e6674a318" },
|
||||
{ "id": "rule", "file": "rule.schema.json", "version": "v1.0", "digest": "34d4f1c2ba97b76acf85ad61f4e8de4591664eefecbc7ebb6d168aa5a998ddd1" },
|
||||
{ "id": "template", "file": "template.schema.json", "version": "v1.0", "digest": "e0a8f9bb5e5f29a11b040e7cb0e7e9a8c5d42256f9a4bd72f79460eb613dac52" },
|
||||
{ "id": "channel", "file": "channel.schema.json", "version": "v1.0", "digest": "bd9e2dfb4e6e7e7a38f26cc94ae8bcdf9b8c44b1e97bf78c146711783fe8fa2b" },
|
||||
{ "id": "receipt", "file": "receipt.schema.json", "version": "v1.0", "digest": "fb4431019b3803081983b215fc9ca2e7618c3cf91f8274baedf72cacad8dfe46" },
|
||||
{ "id": "webhook", "file": "webhook.schema.json", "version": "v1.0", "digest": "54a6e0d956fd6af7e88f6508bda78221ca04cfedea4112bfefc7fa5dbfa45c09" },
|
||||
{ "id": "dlq", "file": "dlq-notify.schema.json", "version": "v1.0", "digest": "1330e589245b923f6e1fea6af080b7b302a97effa360a90dbef4ba3b06021b2f" }
|
||||
]
|
||||
}
|
||||
|
||||
1
docs/notifications/simulations/index.ndjson
Normal file
1
docs/notifications/simulations/index.ndjson
Normal file
@@ -0,0 +1 @@
|
||||
{"rule_id":"RULE-INCIDENT","tenant_id":"tenant-123","simulation_report":"sample-simulation-report.json","status":"passed"}
|
||||
28
docs/notifications/simulations/sample-rule-report.json
Normal file
28
docs/notifications/simulations/sample-rule-report.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"rule_id": "sample-rule",
|
||||
"simulation_id": "sim-2025-12-04-001",
|
||||
"executed_at": "2025-12-04T00:00:00Z",
|
||||
"tenant_id": "test-tenant",
|
||||
"fixtures_used": [
|
||||
"docs/notifications/fixtures/rendering/tmpl-incident-start.email.en-US.json"
|
||||
],
|
||||
"channels_tested": ["email", "slack"],
|
||||
"results": {
|
||||
"events_processed": 10,
|
||||
"deliveries_simulated": 20,
|
||||
"delivery_success": 20,
|
||||
"delivery_failure": 0,
|
||||
"quota_blocked": 0,
|
||||
"redaction_applied": true
|
||||
},
|
||||
"determinism_check": {
|
||||
"hash_algorithm": "blake3-256",
|
||||
"output_digest": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"verified": true
|
||||
},
|
||||
"approval_required": true,
|
||||
"approval_status": "pending",
|
||||
"evidence_links": [
|
||||
"docs/notifications/fixtures/rendering/index.ndjson"
|
||||
]
|
||||
}
|
||||
13
docs/notifications/simulations/sample-simulation-report.json
Normal file
13
docs/notifications/simulations/sample-simulation-report.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"rule_id": "RULE-INCIDENT",
|
||||
"tenant_id": "tenant-123",
|
||||
"fixtures_version": "v1",
|
||||
"result": "passed",
|
||||
"evidence": [
|
||||
{
|
||||
"event_id": "evt-1",
|
||||
"decision": "send",
|
||||
"channel": "email"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user