4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
91 lines
3.3 KiB
Python
91 lines
3.3 KiB
Python
"""Publish-findings node — entry points for the investigation pipeline.
|
|
|
|
Node contract:
|
|
Entrypoint : deliver(state: InvestigationState) -> dict[str, Any]
|
|
Reads : root_cause, validated_claims, non_validated_claims,
|
|
remediation_steps, correlation, evidence, resolved_integrations,
|
|
slack_context, telegram_context, whatsapp_context,
|
|
discord_context, problem_md, masking_context, opensre_evaluate
|
|
Writes : slack_message, report, opensre_llm_eval (optional)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, cast
|
|
|
|
from core.state import InvestigationState
|
|
from platform.masking import MaskingContext
|
|
from platform.notifications.ingest_delivery import create_investigation_and_attach_url
|
|
from tools.investigation.reporting.context import build_report_context
|
|
from tools.investigation.reporting.delivery import dispatch_report
|
|
from tools.investigation.reporting.evaluation import run_optional_opensre_evaluation
|
|
from tools.investigation.reporting.formatters.messages import (
|
|
ReportMessages,
|
|
build_report_messages,
|
|
)
|
|
from tools.investigation.reporting.renderers.editor import open_in_editor
|
|
from tools.investigation.reporting.renderers.terminal import render_report
|
|
from tools.investigation.reporting.upstream_correlation import (
|
|
enrich_upstream_correlation,
|
|
)
|
|
|
|
|
|
def deliver(state: InvestigationState) -> dict[str, Any]:
|
|
"""Format and deliver the investigation report to all configured channels.
|
|
|
|
Returns state updates with slack_message and report fields.
|
|
"""
|
|
state_dict = dict(state)
|
|
extra_updates = run_optional_opensre_evaluation(state_dict)
|
|
return {**generate_report(state), **extra_updates}
|
|
|
|
|
|
def generate_report(
|
|
state: InvestigationState,
|
|
*,
|
|
render_terminal: bool = True,
|
|
open_editor: bool = True,
|
|
) -> dict[str, Any]:
|
|
"""Generate and publish the final RCA report."""
|
|
correlation_updates = enrich_upstream_correlation(state)
|
|
enriched_state = cast(InvestigationState, {**dict(state), **correlation_updates})
|
|
ctx = build_report_context(enriched_state)
|
|
short_summary = enriched_state.get("problem_md")
|
|
messages = build_report_messages(ctx)
|
|
|
|
# Restore any masked infrastructure identifiers in user-facing output.
|
|
# No-op when masking is disabled or the state has no placeholders.
|
|
masking_ctx = MaskingContext.from_state(dict(enriched_state))
|
|
messages = ReportMessages(
|
|
slack_text=masking_ctx.unmask(messages.slack_text),
|
|
telegram_html=masking_ctx.unmask(messages.telegram_html),
|
|
whatsapp_text=masking_ctx.unmask(messages.whatsapp_text),
|
|
slack_blocks=masking_ctx.unmask_value(messages.slack_blocks),
|
|
)
|
|
if isinstance(short_summary, str):
|
|
short_summary = masking_ctx.unmask(short_summary)
|
|
|
|
investigation_id, investigation_url = create_investigation_and_attach_url(
|
|
enriched_state,
|
|
messages.slack_text,
|
|
short_summary,
|
|
)
|
|
|
|
if render_terminal:
|
|
render_report(messages.slack_text)
|
|
if open_editor:
|
|
open_in_editor(messages.slack_text)
|
|
|
|
dispatch_report(
|
|
enriched_state,
|
|
messages,
|
|
investigation_id=investigation_id,
|
|
investigation_url=investigation_url,
|
|
)
|
|
|
|
return {
|
|
**correlation_updates,
|
|
"slack_message": messages.slack_text,
|
|
"report": messages.slack_text,
|
|
}
|