Snapshot Store Reference

Persistent snapshot substrate for Dashboard V2. The store backs historical trends, manual baselines, compare/export workflows, and release-gate evidence.

Scope

The snapshot layer is no longer a simple time-series cache. It is a metadata-rich evidence store used by:

  • Dashboard trends and period comparisons
  • Manual project and group snapshots
  • Snapshot-to-snapshot compare and export
  • Release-gate pre/post evidence capture
  • Notification context for release-driven events

Snapshot Model

Each snapshot stores both summarized scores and provenance metadata.

Core identity fields:

  • id
  • scopeproject, group, or portfolio
  • scope_ref — canonical target reference
  • project_name / group_id when applicable
  • timestamp

Evidence metadata:

  • reason
  • initiator
  • trigger_source
  • analyzer_version
  • rule_version
  • source_ref
  • immutable
  • retention_class

Payload data:

  • health, audit, compliance, release, SCA, and quality summaries
  • source bundle used for compare/export
  • serialized snapshot payload for later replay

Lifecycle

Capture -> Persist -> Compare / Export -> Retain / Cleanup

Capture sources:

  • background scheduler
  • manual API and CLI calls
  • release-gate pre/post automation

Retention rules:

  • standard retention uses dashboard.snapshot_retention_days
  • snapshots marked immutable are protected from ordinary cleanup
  • release-triggered snapshots can use a separate retention class

API Surfaces

All endpoints live under /api/v2/dashboard.

Create Manual Snapshot

POST /snapshots

Use this to capture a manual baseline for a project, group, or portfolio.

Request fields include:

  • scope
  • project_name or group_id
  • reason
  • trigger_source
  • analyzer_version
  • rule_version
  • source_ref
  • immutable
  • retention_class

ACL follows the same ProjectContext rules as the underlying project/group.

List Snapshots

GET /snapshots

Filters:

  • scope
  • project_name
  • group_id
  • limit

The maximum returned count is bounded by dashboard.snapshot_list_limit.

Snapshot Governance Policy

GET /snapshots/policy

Returns the live immutable-governance contract. Current runtime mode is:

  • immutable_governance_mode = no_delete_policy
  • delete_supported = false
  • archival_supported = false
  • ordinary cleanup still respects immutable = true

Compare Snapshots

POST /snapshots/compare

Supported modes:

  • compare by from_snapshot_id and to_snapshot_id
  • compare by legacy project timestamps

Compare output includes:

  • metric deltas
  • trend_direction
  • dimension_states with improved, regressed, or unchanged
  • optional drilldown_categories
  • optional drilldown_previews

Export Snapshot or Compare Report

POST /snapshots/{snapshot_id}/export

Supported formats:

  • json
  • markdown
  • pdf

If baseline_snapshot_id is provided, export produces a compare report instead of a single-snapshot report.

Trend Endpoints

Existing trend endpoints remain available:

  • GET /snapshots/{project_name}/trends
  • GET /snapshots/{project_name}/diff
  • GET /snapshots/{project_name}/compare-periods

These routes use persisted snapshot data when available and preserve compatibility with the broader dashboard trend model.

CLI Surfaces

Implemented in src/cli/dashboard_commands.py.

Available commands:

  • dashboard snapshot create
  • dashboard snapshot list
  • dashboard snapshot show
  • dashboard snapshot policy
  • dashboard snapshot compare
  • dashboard snapshot export

Examples:

codegraph dashboard snapshot create --scope project --project my-service --reason "pre-hardening"
codegraph dashboard snapshot list --scope portfolio --group team-a --format json
codegraph dashboard snapshot show <snapshot_id> --format json
codegraph dashboard snapshot policy --format json
codegraph dashboard snapshot compare --from-snapshot <id1> --to-snapshot <id2> --include-drilldown
codegraph dashboard snapshot export <snapshot_id> --baseline-snapshot <older_id> --format markdown

Release-Gate Integration

POST /api/v1/release/check can create:

  • pre snapshot before evaluation
  • post snapshot after evaluation

Response fields:

  • pre_snapshot_id
  • post_snapshot_id
  • snapshot_diff

Release-triggered behavior is controlled by:

  • dashboard.snapshot_release_pre_enabled
  • dashboard.snapshot_release_post_enabled
  • dashboard.snapshot_release_immutable
  • dashboard.snapshot_release_retention_class

Notification Integration

The notification service consumes snapshot-derived context for release-driven notifications. Current integration passes:

  • snapshot IDs
  • compare diff summary
  • release outcome context

This allows release alerts to point to reproducible state evidence instead of only a status string.

Configuration

Relevant dashboard config keys:

  • snapshot_enabled
  • snapshot_interval_minutes
  • snapshot_retention_days
  • snapshot_db_path
  • snapshot_list_limit
  • snapshot_release_pre_enabled
  • snapshot_release_post_enabled
  • snapshot_release_immutable
  • snapshot_release_retention_class

Operational Notes

  • The store uses SQLite and is created automatically on first use.
  • One active scheduler instance is recommended for steady-state writes.
  • Manual snapshots and compare/export flows are safe to run without enabling the background scheduler.
  • immutable currently uses explicit no_delete_policy: runtime does not expose delete or mutation endpoints, and ordinary cleanup skips immutable records.

Source Files

File Purpose
src/api/services/dashboard/snapshot_store.py Persistent snapshot storage and migration
src/api/services/dashboard/history.py Snapshot compare semantics and drilldown
src/api/services/dashboard/export.py Snapshot and compare export
src/api/services/dashboard/snapshot_scheduler.py Scheduled snapshot collection
src/api/routers/dashboard_v2.py REST endpoints for list/create/compare/export/trends
src/api/routers/release_gate.py Release-triggered pre/post snapshot automation
tests/unit/test_dashboard_v2/test_snapshot_store.py Snapshot store coverage
tests/unit/test_dashboard_v2/test_history_service.py Compare semantics coverage