Skip to content

feat: 用按需 QuestDB Analysis Snapshot 完成受治理 OODA 闭环 #96

Description

@1012839419a-alt

Problem Statement

OpenCLI already persists authoritative Workflow Runs, trace events, acquisition executions, Records, Evidence, Findings, and governed control actions. Operators can inspect individual runs, but they cannot select a bounded historical range, orient themselves with time-window analysis, turn the result into a durable Finding, and act through the existing proposal and Gate boundary. Adding a continuously synchronized analytics database would create a second authority and operational burden, while raw trace export would leak free-form payloads and credentials.

Solution

Add an optional, user-triggered OODA Analysis Loop backed by QuestDB as an External Analysis Runtime. From an existing Run detail surface, an authorized operator selects a completed time range and creates a redacted Analysis Snapshot containing Workflow Trace events and acquisition execution metrics. OpenCLI records an authoritative export receipt while QuestDB stores only the disposable analytical projection for 30 days by default. Curated analyses orient the operator, selected results become Findings, and an operator may turn a Finding into an Agent Operation Proposal. Every action continues through the existing confirmation, Gate, Actuator, revision, and evidence path.

The feature is absent-safe: OpenCLI remains fully usable without QuestDB, exports fail without changing authoritative Run data, and there is no event subscription, dual write, retry queue, or automatic remediation.

User Stories

  1. As an operator, I want to start an analysis from a completed Run, so that I remain in the Project and Workflow context I am investigating.
  2. As an operator, I want to select an explicit UTC time range, so that the exported facts are bounded and reproducible.
  3. As an operator, I want to preview the selected event and metric counts before export, so that I understand the scope.
  4. As an operator, I want the system to reject an empty or unauthorized selection, so that I do not create misleading snapshots.
  5. As an operator, I want only redacted Workflow Trace event fields exported, so that messages, details, URLs, tokens, credentials, and raw payloads remain authoritative and private.
  6. As an operator, I want acquisition status and duration metrics exported without inputs or result payloads, so that I can compare execution behavior safely.
  7. As an operator, I want re-exporting the same selection to be idempotent, so that one source fact does not become multiple analytical facts.
  8. As an operator, I want an export receipt containing scope, schema version, status, row counts, timestamps, and redacted failure code, so that the operation is auditable.
  9. As an operator, I want a failed QuestDB connection to leave Runs, events, acquisition executions, Records, and Evidence unchanged, so that analysis cannot damage production truth.
  10. As an operator, I want to see whether the optional QuestDB runtime is unavailable, unhealthy, or ready, so that a capability gap is explicit.
  11. As an operator, I want curated time-window summaries for throughput, latency, failure rate, event type, and node behavior, so that I can orient without writing SQL.
  12. As an operator, I want comparisons to cite the Analysis Snapshot and source range, so that an observation can be reproduced.
  13. As an operator, I want to save an analysis result as a Finding, so that a decision survives beyond the temporary snapshot.
  14. As an operator, I want a Finding to distinguish observation, interpretation, recommendation, and evidence, so that the decision is reviewable.
  15. As an operator, I want to create an Agent Operation Proposal from a Finding, so that the Act step uses the same governed boundary as every other operation.
  16. As an operator, I want dangerous or unsupported recommendations to downgrade to review, so that analysis never bypasses control policy.
  17. As an operator, I want the final proposal diff and target revisions shown before confirmation, so that stale analysis cannot silently mutate current state.
  18. As an operator, I want snapshot retention to default to 30 days and support early deletion, so that QuestDB remains disposable.
  19. As an operator, I want snapshot expiry or deletion to preserve Findings, proposal evidence, and export receipts, so that audit history remains intact.
  20. As an administrator, I want QuestDB enabled through an optional Compose profile with pinned version and loopback-only ports, so that default installations do not gain a mandatory service.
  21. As an administrator, I want readiness and health probes without exposing QuestDB credentials or raw SQL, so that the runtime is governable.
  22. As a developer, I want the mapping and redaction contract testable without a running QuestDB instance, so that most verification remains fast.
  23. As a developer, I want a disposable-container integration test for schema, deduplication, aggregation, failure, and cleanup, so that protocol assumptions are proven empirically.
  24. As a product owner, I want OpenCLI to work unchanged when the plugin is disabled, so that the analysis capability remains optional.

Implementation Decisions

  • Use the existing Data Analysis Plugin and External Analysis Runtime concepts. QuestDB does not become a top-level product area or source of business truth.
  • Model each user-triggered export as an Analysis Snapshot with an authoritative OpenCLI receipt and a disposable QuestDB projection.
  • Support two versioned row families in the first release: Workflow Trace events and acquisition execution metrics. Agent and browser runtime metrics remain excluded until their duration semantics are normalized.
  • Export only after explicit user selection from a completed Run context. No post-commit callback, workflow event subscriber, Celery task, Redis stream, outbox, background retry, or continuous mirror is added.
  • Use authoritative source timestamps in UTC and deterministic identities derived from stable source IDs and timestamps. Repeated exports of the same selection are idempotent.
  • Export only allowlisted scalar fields. Free-form messages, details, prompts, tool inputs/results, URLs, cookies, headers, tokens, profile paths, endpoints, raw artifacts, and provider responses are forbidden.
  • Keep high-cardinality identifiers as strings rather than QuestDB symbols. Only bounded dimensions such as event type, status, runtime kind, and bounded failure code may use symbol columns.
  • Provide curated analysis operations rather than exposing arbitrary SQL in the product UI.
  • Persist Finding and proposal evidence in OpenCLI. QuestDB snapshot expiry does not remove durable decisions or governance evidence.
  • Use existing Agent Operation Proposal, revision guard, confirmation, Gate, Actuator, and evidence contracts for Act. QuestDB never executes a control action directly.
  • Default retention is 30 days, with an operator-authorized early-delete action. Expiration deletes only the derived snapshot.
  • Package QuestDB as an optional, pinned Compose profile. It is not an API or worker startup dependency; only the ports required for QWP/query and health are exposed on loopback.
  • Treat runtime unavailability as a typed capability gap. Export failure records a redacted receipt and never mutates source facts.

Testing Decisions

  • The highest business seam is the authenticated Run analysis API: selection, preview, export receipt, curated analysis, Finding creation, and proposal creation are tested through public behavior.
  • The exporter is injected behind one narrow interface. Contract tests cover mapping, redaction, stable identity, idempotency, source-time selection, bounded schemas, and failure isolation without a live service.
  • A disposable QuestDB container test proves pinned-image health, explicit table schemas, designated timestamps, duplicate export behavior, time-window aggregation, retention metadata, endpoint failure, and cleanup.
  • Existing Workflow trace and acquisition fixtures are reused as prior art; tests assert authoritative rows are unchanged after export failure.
  • Frontend tests cover Run-detail selection, preview, readiness, export progress, analysis summaries, Finding creation, proposal review, errors, expiry, and disabled-plugin behavior.
  • One real Playwright path covers Observe → Orient → Decide → Act up to proposal confirmation, using a disposable QuestDB instance and the normal authenticated application.
  • Security checks scan persisted receipts, QuestDB rows, API responses, logs, and browser output for forbidden fields.
  • Regression checks cover Workflow replay, acquisition execution, Agent Control confirmation, migrations, optional Compose startup, and default startup without QuestDB.

Out of Scope

  • Replacing PostgreSQL, SQLite, SQLAlchemy, or existing migrations with QuestDB.
  • Continuous synchronization, dual writes, automatic event mirroring, background retries, or a second replay source.
  • Raw SQL notebooks, a top-level QuestDB workbench, QuestDB Web Console embedding, or arbitrary table access.
  • Exporting raw traces, messages, payload JSON, prompts, credentials, browser state, URLs, artifacts, or provider responses.
  • Agent or browser runtime metrics before a normalized durable metric contract exists.
  • Automatic remediation, self-approval, direct actuator calls, or changes to existing control policy.
  • Cross-workspace snapshot sharing or using QuestDB for authorization, scheduling, replay, or operational correctness.

Further Notes

  • Canonical terms: Analysis Snapshot and OODA Analysis Loop.
  • QuestDB is an optional implementation of an External Analysis Runtime behind the Data Analysis Plugin contract.
  • Release target: QuestDB 10.0.1, pinned rather than latest.
  • The feature must remain useful when only SQLite is configured and absent-safe when QuestDB is disabled.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions