feat(policy): persist gate evaluation queue, snapshots, orchestrator jobs

Policy Engine: moves gate evaluation, snapshots, orchestrator job tracking,
and ledger export from in-memory state to Postgres-backed stores.

- New persistence migrations 007 (runtime state), 008 (snapshot artifact
  identity), 009 (orchestrator jobs).
- New repositories: PolicyEngineSnapshotRepository,
  PolicyEngineLedgerExportRepository, PolicyEngineOrchestratorJobRepository,
  WorkerResultRepository.
- Gateway services: GateEvaluationJobDispatchService,
  GateEvaluationJobStatusService, GateEvaluationJobWorker,
  SchedulerBackedGateEvaluationQueue (plus Unsupported fallback),
  GateTargetSnapshotMaterializer, PersistedKnowledgeSnapshotStore,
  GateBaselineBootstrapper, PolicyGateEvaluationJobExecutor.
- New endpoints: GateJobEndpoints for job status + dispatch.
- Worker host: PolicyOrchestratorJobWorkerHost to drain the persistent queue.
- PersistedOrchestratorStores + DeltaSnapshotServiceAdapter swap in the
  persistent implementations via DI.

Tests: PersistedDeltaRuntimeTests, PolicyEngineGateTargetSnapshotRuntimeTests,
PolicyEngineRegistryWebhookRuntimeTests, PostgresLedgerExportStoreTests,
PostgresSnapshotStoreTests, PolicyGatewayPersistedDeltaRuntimeTests,
RegistryWebhookQueueRuntimeTests. Archives the old S001 demo seed.

Docs: policy API + architecture pages updated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-04-15 11:14:41 +03:00
parent d8f6bade9a
commit 786d09b88f
70 changed files with 5994 additions and 768 deletions

View File

@@ -407,6 +407,58 @@ Scopes: policy:runs, policy:simulate
Produces sealed bundle for determinism verification; returns location of bundle.
### 6.6 Orchestrator Job Producer Runtime
The engine-owned orchestration surface is exposed directly under `/policy/*`. Unlike the stateless batch evaluator below, this path persists orchestrator and worker state in Policy storage.
```
POST /policy/orchestrator/jobs
Scopes: policy:run
```
**Request**
```json
{
"tenantId": "acme",
"policyVersion": "sha256:1fb2...",
"items": [
{
"findingId": "acme::artifact-1::CVE-2024-12345",
"eventId": "5d1fcc61-6903-42ef-9285-7f4d3d8f7f69",
"event": { "...": "canonical ledger payload" }
}
]
}
```
**Response 200**
```json
{
"jobId": "01HSR2M1D0BP7V2QY3QGJ31Z8V",
"status": "queued",
"requestedAt": "2026-04-15T08:30:00Z",
"completedAt": null,
"resultHash": null
}
```
Related endpoints:
```
POST /policy/orchestrator/jobs/preview
GET /policy/orchestrator/jobs/{jobId}
GET /policy/worker/jobs/{jobId}
```
Runtime contract:
- Submitting `/policy/orchestrator/jobs` now signals the engine background worker, which leases queued jobs, marks them `running`, executes `PolicyWorkerService`, persists `policy.worker_results`, and records terminal `completed` or `failed` state on the orchestrator job.
- Clients should poll `GET /policy/orchestrator/jobs/{jobId}` for status and read the final materialized worker payload from `GET /policy/worker/jobs/{jobId}`.
- `POST /policy/orchestrator/jobs/preview` remains non-mutating.
- `POST /api/policy/eval/batch` remains explicitly stateless and must not be used as a persistence side channel for orchestrator or worker rows.
---
## 7·Batch Evaluation API