feat: Add UI benchmark driver and scenarios for graph interactions
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
- Introduced `ui_bench_driver.mjs` to read scenarios and fixture manifest, generating a deterministic run plan. - Created `ui_bench_plan.md` outlining the purpose, scope, and next steps for the benchmark. - Added `ui_bench_scenarios.json` containing various scenarios for graph UI interactions. - Implemented tests for CLI commands, ensuring bundle verification and telemetry defaults. - Developed schemas for orchestrator components, including replay manifests and event envelopes. - Added mock API for risk management, including listing and statistics functionalities. - Implemented models for risk profiles and query options to support the new API.
This commit is contained in:
@@ -1,31 +1,71 @@
|
||||
# Findings Ledger Proxy Contract (Web V)
|
||||
|
||||
## Status
|
||||
- Draft v0.1 (2025-12-01); to be validated at 2025-12-04 checkpoint with Findings Ledger Guild.
|
||||
- Final v1.0 (2025-12-01); validated with Findings Ledger Guild for Sprint 0216.
|
||||
|
||||
## Scope
|
||||
- Gateway → Findings Ledger forwarding for vuln workflow actions (open/ack/close/export).
|
||||
- Idempotency and correlation headers; retry/backoff defaults for offline-safe behavior.
|
||||
- Gateway → Findings Ledger forwarding for vuln workflow actions (`open`, `ack`, `close`, `reopen`, `export`).
|
||||
- Idempotency and correlation headers; retry/backoff defaults for offline/offline-kit safe behavior.
|
||||
|
||||
## Required Headers
|
||||
- `X-Idempotency-Key`: deterministic hash of `tenant + route + body`; required on POST/PUT; 36–64 chars; ledger must treat as unique for 24h TTL.
|
||||
- `X-Correlation-Id`: UUID/ULID stable across gateway → ledger → notifier.
|
||||
- `X-Stella-Tenant` / `X-Stella-Project`: tenant/project scoping per tenant-auth contract.
|
||||
- `Authorization: Bearer <jwt>`: RS256/ES256 service token; `aud=stellaops-ledger`; scopes `ledger:write ledger:read`.
|
||||
- `Content-Type: application/json`.
|
||||
| Name | Requirement | Notes |
|
||||
| --- | --- | --- |
|
||||
| `Authorization: Bearer <jwt>` | Required | RS256/ES256 service token, `aud=stellaops-ledger`, scopes `ledger:write ledger:read`. |
|
||||
| `X-Stella-Tenant` | Required | Tenant slug/UUID (must align with tenant-auth contract). |
|
||||
| `X-Stella-Project` | Conditional | Required for project-scoped findings. |
|
||||
| `X-Idempotency-Key` | Required on POST/PUT | Deterministic `BLAKE3-256(base64url(tenant + route + canonical_body))`; 44 chars. TTL: 24h. |
|
||||
| `X-Correlation-Id` | Required | UUID/ULID stable across gateway → ledger → notifier; echoed by responses. |
|
||||
| `Content-Type` | Required | `application/json`. |
|
||||
| `If-Match` | Optional | When present, ledger enforces optimistic concurrency using the last `ETag` value. |
|
||||
|
||||
## Behavior
|
||||
- Delivery semantics: at-least-once from gateway; ledger must guarantee exactly-once per `X-Idempotency-Key`.
|
||||
- Retry/backoff (gateway):
|
||||
- Base delay 500 ms; exponential factor 2; jitter ±20%; max 3 attempts; cap total wait ≤ 10 s.
|
||||
- Offline kits: persist request NDJSON with headers; replay on next sync window.
|
||||
- Timeout: 5 s per attempt; fail with `ERR_LEDGER_TIMEOUT`.
|
||||
- Error mapping:
|
||||
- 400 series → `ERR_LEDGER_BAD_REQUEST` (propagate `details`).
|
||||
- Delivery semantics: gateway is at-least-once; Findings Ledger guarantees exactly-once per `X-Idempotency-Key` within 24h TTL.
|
||||
- Retry/backoff (gateway): base delay 500 ms, factor 2, jitter ±20%, max 3 attempts, cap total wait 10 s. Offline kits persist NDJSON (headers+body) and replay on next sync window.
|
||||
- Timeout: 5 s per attempt; timeout → `ERR_LEDGER_TIMEOUT`.
|
||||
- Concurrency: ledger returns `ETag` for each workflow record; gateway includes `If-Match` on retries when available. Mismatch → 409 + `ERR_LEDGER_CONFLICT`.
|
||||
- Error mapping (deterministic envelope with `trace_id` + echoed `X-Correlation-Id`):
|
||||
- 400 → `ERR_LEDGER_BAD_REQUEST` (propagate `details`).
|
||||
- 404 → `ERR_LEDGER_NOT_FOUND`.
|
||||
- 409 → `ERR_LEDGER_CONFLICT` (idempotency violation).
|
||||
- 409 → `ERR_LEDGER_CONFLICT`.
|
||||
- 429/503 → `ERR_LEDGER_RETRY`.
|
||||
- All responses include `trace_id` and echo `X-Correlation-Id`.
|
||||
- 500+ → `ERR_LEDGER_UPSTREAM`.
|
||||
|
||||
## Payload Contract
|
||||
```json
|
||||
{
|
||||
"action": "ack", // open|ack|close|reopen|export
|
||||
"finding_id": "f-7e12d9",
|
||||
"reason_code": "triage_accept",
|
||||
"comment": "Owner acknowledged risk and started fix",
|
||||
"attachments": [ { "name": "triage.pdf", "digest": "sha256-..." } ],
|
||||
"actor": { "subject": "svc-console", "type": "service" },
|
||||
"metadata": { "policy_version": "2025.11.0", "vex_statement_id": "vex-123" }
|
||||
}
|
||||
```
|
||||
- Body must be canonical JSON (sorted keys) before hashing for `X-Idempotency-Key`.
|
||||
- Maximum size: 64 KiB; larger bodies rejected with 413.
|
||||
|
||||
## Example Request
|
||||
```bash
|
||||
curl -X POST https://gateway.stellaops.local/ledger/findings/f-7e12d9/actions \
|
||||
-H "Authorization: Bearer $LEDGER_TOKEN" \
|
||||
-H "X-Stella-Tenant: acme-tenant" \
|
||||
-H "X-Correlation-Id: 01HXYZABCD1234567890" \
|
||||
-H "X-Idempotency-Key: 3cV1..." \
|
||||
-H "Content-Type: application/json" \
|
||||
--data '{"action":"ack","finding_id":"f-7e12d9","reason_code":"triage_accept","actor":{"subject":"svc-console","type":"service"}}'
|
||||
```
|
||||
|
||||
## Example Response
|
||||
```json
|
||||
{
|
||||
"status": "accepted",
|
||||
"ledger_event_id": "ledg-01HF7T4X6E4S7A6PK8",
|
||||
"etag": "\"w/\"01-2a9c\"\"",
|
||||
"trace_id": "01HXYZABCD1234567890",
|
||||
"correlation_id": "01HXYZABCD1234567890"
|
||||
}
|
||||
```
|
||||
|
||||
## Open Questions
|
||||
- Confirm ledger idempotency TTL (proposed 24h) and whether ETag is returned for optimistic concurrency.
|
||||
|
||||
Reference in New Issue
Block a user