Kiket docs
Start

Scanner runs

How compliance scanner runs are triggered, deduplicated, and explained — and how output reaches the Findings Inbox.

A scanner run evaluates one scoped slice of your operational twin: it loads the process model (workflow definition), case context, linked evidence, and recent operational events, runs configured checks, and upserts findings with human-readable explanations.

Runs are durable records — you can list them, diff consecutive passes, and triage inbox output since last scan.

Scanner logic lives in the platform API and @kiket/engine checks — not in LLM output. Findings include a fixed source check id and structured explanation text derived from check results.

Triggers

Each run stores a trigger value describing why it started:

TriggerWhen it runs
eventAfter successful normalization of a new operational event (when workspace or process scope is known). Idempotency key: scan:event:<event dedupe key>.
scheduledPeriodic sweeps — for example privacy-request deadline checks keyed per case and hour bucket.
manualOperator-initiated from Process Twin, the command palette (Run compliance scanner), or POST /platform/scanner-runs.
backfillHistorical or replay scans over existing data.
simulationEditor or cockpit simulation — evaluates a supplied workflow definition without mutating production state beyond the run record.

Event-driven path

Raw inbox → normalize → operational event → enqueue scanner run → checks → findings

Normalization skips scheduling when the operational event is a duplicate or lacks workspace/process scope. In local dev without job queues, the scanner may run inline immediately after normalization.

Manual path

The web app posts:

POST /platform/scanner-runs
{
  "trigger": "manual",
  "idempotencyKey": "<unique>",
  "workspaceId": "...",
  "processId": "...",
  "caseId": "...",
  "eventId": "..."   // optional — adds event-scoped evidence context
}

The CLI exposes the same contract: kiket scan --trigger manual ….

Production workers process queued runs asynchronously (status: queued → running → completed or failed). Tests and no-queue environments run deterministically inline and return findings in the 202 response.

Run lifecycle and visibility

FieldMeaning
statusqueued, running, completed, or failed.
summaryJSON summary — e.g. checksEvaluated, findingsObserved.
startedAt / completedAt / failedAtTimestamps for timeline and triage windows.
errorServer message when status is failed.

Process Twin shows recent runs in the activity feed. Full history:

GET /platform/scanner-runs?workspaceId=&processId=&caseId=

Compare two consecutive completed runs in scope:

GET /platform/scanner-runs/:id/diff

Returns added and resolved findings between the run and the previous completed run.

Explainability

Every finding emitted by a scanner run includes:

FieldPurpose
sourceCheckStable check identifier (maps to engine / YAML check definition).
explanationHuman-readable reason the check failed or observed a gap.
remediationStructured hints (action type, instructions) used by the inbox stepper — not model-generated prose.
severitycritical, high, medium, low, or informational tiers for triage.
auditHistoryAppend-only log; new observations record scannerRunId and timestamp.

The Findings Inbox detail panel surfaces explanation and recommended next steps. Assistive panels may summarize metrics but do not replace check output as the source of truth.

Linked evidence ids from the check are stored as evidence links (targetType: finding, linkType: supports) so reviewers can open Evidence Center from the finding.

Dedupe behavior

Scanner runs and findings both dedupe to keep the loop idempotent under retries and webhook redelivery.

Scanner run dedupe

Runs are unique per organization on idempotencyKey (organization_id + idempotency_key unique index).

  • If a duplicate request arrives and the existing run is already completed, the API returns that run and existing findings without re-executing checks.
  • Event-driven scheduling uses deterministic keys (scan:event:…) so the same operational event does not spawn parallel runs.

Finding dedupe

Findings upsert on dedupeKey per organization. Re-observation during a later run updates lastSeenAt and appends to auditHistory rather than creating duplicate inbox rows.

Closed findings (resolved, suppressed, false_positive) follow transition rules — reopening requires an explicit status change, not silent overwrite.

From scanner run to Findings Inbox

After a completed run, open Findings Inbox (/findings):

Triage filterUse
since_last_scanFindings observed during the latest completed run (per process when processId is set).
actionableOpen, acknowledged, or remediating items needing work.
missing_evidenceActionable findings with no linked proof.
criticalHighest-severity actionable queue.

Example deep link:

/findings?triage=since_last_scan&processId=<uuid>&selected=<findingId>

Full inbox, bulk triage, and remediation stepper: Findings inbox and remediation.

What's next?

On this page