agentsclimarketplace

Gds monitor

Skill hypertopos/hypertopos-skills/gds-monitor

Investigation workflows for AI agents exploring geometric data spaces

Install
npx -y skills add hypertopos/hypertopos-skills --skill gds-monitor

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

GDS sphere health monitoring — drift detection, regime change tracking, alert response, and periodic health assessment. Use when user asks to "check sphere health", "monitor drift", "are there any alerts", "what changed since last time", "detect regime changes", "find emerging anomalies", "temporal health check", or "is the sphere healthy". Requires hypertopos MCP server with temporal data.

The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

24.0 KB, ~5.5k tokens by cl100k_base, as published. Nobody here has run it

GDS Monitor

A GDS monitor detects behavioral changes over time — drift at the entity level, regime shifts at the population level, emerging anomalies not yet crossed the threshold, and calibration degradation. The approach is top-down: check population health first, drill to entities only when something is flagged.

Prerequisite: This skill requires patterns with temporal data (has_temporal: true in sphere_overview). If no patterns have temporal data, report that temporal monitoring is unavailable and hand off to gds-explorer for static analysis instead.

For concrete tool output examples, see references/examples.md.


Quick health check

Two calls tell you whether anything needs attention:

sphere_overview(detail="summary")  -> calibration, anomaly rates, profiling_alerts, has_temporal
check_alerts()                     -> alerts sorted by severity
edge_stats(pattern_id)             -> if event patterns exist, graph monitoring available

If alerts are present, respond to them (see table below). If check_alerts returns nothing, proceed to find_regime_changes and find_drifting_entities anyway — absence of alerts does NOT mean absence of temporal patterns. Alerts check geometric health (calibration staleness, threshold violations); regime changes and drift detect behavioral shifts that are structurally valid but operationally significant. Skipping temporal tools when alerts are clean is the most common monitoring gap.

Responding to alerts

AlertWhat it means and what to do
anomaly_rate_spikeanomaly_summary(pattern_id) then contrast_populations({anomaly: true}) — what spiked? If edge table available: degree_velocity on top spikers to check connection rate acceleration.
population_size_shockget_sphere_info() — compare entity counts — data ingestion issue?
theta_miscalibrationrecalibrate(pattern_id) then re-check sphere_overview()
regime_changepointfind_regime_changes(pattern_id) then compare_time_windows() for flagged period
calibration_driftNote for next rebuild. Current results still usable.
stale_vector_indexIncrementally-appended geometry rows sit outside the ANN (IVF) index, so trajectory / similarity tools (detect_trajectory_anomaly, find_similar_entities, find_drifting_similar) silently miss them. MEDIUM severity. Drill down with the vector_index_health block (see below) to read the unindexed fraction, then trigger a reindex on the builder side.

stale_vector_index drilldown — reading vector_index_health

The alert is metadata-only and fires when the unindexed fraction of a pattern's geometry exceeds the stale threshold (default 0.1). There is no standalone health tool — the per-pattern detail is surfaced as a vector_index_health block on every audit_pattern_dims response:

audit_pattern_dims(pattern_id) -> vector_index_health block:
  { index_present, index_type, num_indexed_rows, num_unindexed_rows,
    total_rows, indexed_fraction, num_partitions, is_stale,
    stale_threshold, recommendation }

Triage:

  • is_stale == false — index covers the population; ANN-backed tools are complete. No action.
  • is_stale == true — the recommendation string names the fix; an unindexed run accumulated from incremental ingest. ANN tools under-report on the unindexed tail until a reindex runs. Note it as a monitoring finding and hand the reindex to the sphere owner (it is a build-side operation — see the incremental-ingest path in gds-sphere-designer, which reindexes via incremental_update(reindex=True) or finalize_incremental()).
  • index_present == false with a small population — expected. The builder skips the IVF index below the build-time row floor; ANN tools fall back to a full scan and lose nothing. Not an actionable alert.

Interpret is_stale as "ANN results are currently incomplete", NOT "the geometry is wrong" — the rows exist and exact-scan tools (find_anomalies, explain_anomaly) see them; only the approximate-neighbour tools are affected.


Event rate divergence

Compare event anomaly rate per entity vs static anchor anomaly status:

aggregate(event_pattern, group_by_line=anchor_line,
          geometry_filters={"is_anomaly": true})

Entities with >15% anomalous events but NOT flagged as anchor anomalies have concentrated temporal anomalies — investigate with drift detection.

Shortcut: sphere_overview(detail="full") returns event_rate_divergence_alerts pre-computed for all anchor patterns (top 20 by rate). Caution: detail="full" can take minutes on large spheres (>100K entities) — use only for targeted diagnostics, never in interactive loops.

Windowed volume comparison

Compare event counts per entity across two time periods to detect bursts or drops. Use time_from/time_to on aggregate — ISO-8601 half-open interval [from, to). Pick periods from sphere context (recent batch window, pre/post incident, quarter).

aggregate(event_pattern, group_by_line=anchor_line, metric="count",
          time_from=period_a_start, time_to=period_a_end, limit=20)
aggregate(event_pattern, group_by_line=anchor_line, metric="count",
          time_from=period_b_start, time_to=period_b_end, limit=20)

Entities with 2x+ count increase in period B are burst candidates (order splitting, seasonal spikes, data ingestion anomalies). Requires timestamp_col on the event pattern (set via temporal config in sphere.yaml).


Drift detection

find_drifting_entities(pattern_id, top_n=10, forecast_horizon=3)

Interpreting drift results

  • Single high-displacement drifter = entity-level behavioral change
  • Cluster of drifters in same direction = systemic population shift
  • forecast_anomaly=true + reliability=high = early warning

Drift direction triage. find_drifting_entities now returns drift_direction per entity. On a monitoring sweep, triage thus: deteriorating (highest priority, entities moving away from the population centre — trending toward anomaly), neutral (lateral motion, monitor), normalizing (lowest priority, already self-correcting). Filter the top-N list by drift_direction == "deteriorating" before escalating, otherwise alerts include entities that are actively recovering.

For top drifters, dive_solid(key, pattern_id) reveals whether it is gradual drift or a sudden jump. If edge table available: degree_velocity(key, pattern_id) — accelerating degree alongside geometric displacement = strong behavioral change confirmation.

Dimension-specific drift

Displacement is a single number — it hides WHICH dimension changed. For top drifters:

dive_solid(key, pattern_id) -> compare first vs last slice deltas
-> Which dimension changed most? (e.g., counterparty count spike = new relationships,
   burst metric spike = activity change, value metric spike = monetary shift)

If top drifters ALL show the same dominant dimension (e.g. burst_monthly), other dimensions' real changes are invisible in the ranking. In that case:

  • For each NON-dominant dimension: check if ANY drifter has significant change on THAT specific dimension
  • dive_solid on 3 random high-displacement entities, compare first vs last slice PER DIMENSION separately — not just total displacement
  • A drifter with small total displacement but large change on ONE dim is more interesting than a drifter with large displacement on a high-variance dimension

Tool shortcut — rank_by_dimension:

find_drifting_entities(pattern_id, rank_by_dimension="suppliers")
-> entities ranked by drift on the "suppliers" dimension specifically,
   not total displacement

Use this when you suspect a specific dimension is the signal but total displacement is dominated by a different high-variance dimension.


Compare calibration epochs to inspect drift

After a builder rebuild, compare_calibrations(pattern_id) (default args) returns the drift between the two most recent epochs. Use top_n=N to limit the ranked dimension list, verbose=True to also get the full per-dimension breakdown, or pass explicit v_from / v_to to compare any two epochs the sphere has on disk (list_calibration_versions(pid) returns what's available).

Example query: "Has the population shifted since the last rebuild?" → compare_calibrations("account_pattern") → check overall_drift_rms (RMS in σ units, comparable across patterns) and top_drifted (which dimensions moved the most).

When the anchor pattern declares edge_dim_aggregations:, the report also carries edge_dim_threshold_drift — a per-source-dim {from, to, delta} map of the _count_above_threshold cutoff. A large delta means the population p95 of that source dim shifted between epochs, so the same agent narrative ("X anomalous on _count_above_threshold = +Nσ") does NOT mean the same edge regime as in the previous epoch. Worth flagging when it shows up in monitoring alongside a non-zero overall_drift_rms.

Verdict composer — calibration_drift_report

compare_calibrations returns the raw per-dimension μ/σ/θ drift table but leaves the "is this drift large enough to distrust cross-epoch reasoning?" call to the agent. For a monitoring sweep, prefer calibration_drift_report(pattern_id) — it wraps compare_calibrations and adds a drift_verdict over overall_drift_rms plus a routing recommendation:

calibration_drift_report(pattern_id)  # default args = latest vs previous epoch
-> drift_verdict: "stable" | "moderate" | "significant"
-> top_drifted, interpretation, recommended_next_steps

Monitoring routing by verdict:

  • stable — the coordinate system held; a "still anomalous" / "no longer anomalous" comparison across these epochs reflects the entity, not recalibration. Cross-epoch entity verdicts are safe to report.
  • moderate — some dimensions moved materially; treat cross-epoch verdicts on the top_drifted dimensions with caution before escalating an entity.
  • significant — the coordinate system shifted substantially; a cross-epoch "no longer anomalous" claim is dominated by recalibration. Do NOT compare entity verdicts as if θ were fixed. Use decompose_drift(entity, pattern) to split per-entity change into intrinsic (entity moved) vs extrinsic (population recalibrated around it), and pair with find_calibration_influencers (see end of this skill) to find which entities drove the shift.

Drop to raw compare_calibrations only when you need the full per-dimension table without the interpreted verdict, or to compare two specific non-adjacent epochs (calibration_a / calibration_b).


Threshold sensitivity at a glance

sphere_overview() carries a theta_sensitivity_summary block per pattern (when populated by a recent builder rebuild). The block tells the agent — without a per-pattern drilldown — whether the chosen anomaly_percentile is in a smooth region of the population's delta_norm distribution or perched near a heavy-tail jump.

Fields per pattern:

  • stable_band_from / stable_band_to / stable_band_length — the longest contiguous run of percentiles where adjacent-pair theta_mean ratio stays below 1.30. Within this band, recalibrating to a different percentile shifts the threshold by less than 30 % per step.
  • n_cliffs — number of percentile boundaries (in p90 .. p99) where the theta_mean ratio is at or above 1.50. A single move across a cliff jumps the threshold by 50 % or more — heavy-tail region of the distribution.
  • theta_at_p95 — the production-default p95 threshold value for quick visual reference.

Quick triage rules:

  • stable_band_length >= 8 AND n_cliffs == 0: pattern is light-tail and the chosen percentile sits comfortably. Recalibration moves anywhere in the band are safe.
  • stable_band_length <= 4 OR n_cliffs >= 2: heavy-tail pattern. Production p95 may already sit on a cliff edge. Call theta_sensitivity(pattern_id) for the full per-percentile sweep and inspect the cliffs[] list before any recalibration proposal.
  • p95 inside a cliff pair (e.g. cliffs[0]['from'] == 'p95'): do not recalibrate up — moving to p96 jumps theta materially. Consider tightening the percentile down (p93 or below) instead.
  • Empty theta_sensitivity_summary: the sphere predates the diagnostic. Trigger a rebuild before relying on this surface.

When the theta_sensitivity_summary block flags a non-trivial structure (cliffs > 0 or stable_band_length < 6) and you are about to propose a recalibration move, prefer the verdict composer over the raw sweep:

theta_sensitivity_report(pattern_id)
-> recalibration_safety: "safe" | "caution" | "unsafe"
-> n_cliffs, stable_band, cliffs, theta_sensitivity (per-percentile sweep)
-> interpretation, recommended_next_steps

theta_sensitivity_report wraps theta_sensitivity and reads the band / cliff structure into a single recalibration_safety verdict, so you do not have to interpret the raw band/cliff lists yourself:

  • safe — a contiguous stable band exists and no cliffs; moving anomaly_percentile shifts the threshold smoothly. Recalibration anywhere in the swept range is safe.
  • caution — a stable band exists but cliffs sit outside it; keep anomaly_percentile inside stable_band and avoid the boundaries in cliffs[].
  • unsafe — no stable band; every percentile step shifts θ materially (heavy-tail region). Do not recalibrate by percentile without re-measuring the flagged population.

Use raw theta_sensitivity(pattern_id) directly only when you want the per-percentile ratios without the interpreted verdict.


Dim-quality warnings

sphere_overview() carries an optional dim_quality_warnings[] block per pattern surfacing silent build-time failure modes that break z-score / delta_norm semantics. These were previously invisible at agent runtime — the dim sat in the delta vector contributing nothing or contributing wrong signal, and the investigator had no way to know without scrolling the calibration log.

typeTriggerWhy it breaks delta_norm
dead_dimsigma_diag[i] < 1e-10 (zero variance across population)z-score (x - mu) / sigma is undefined / explodes; the dim contributes nothing meaningful and silently dilutes other dims' signal
sparse_dimdim_percentiles[d]['p50'] == 0 AND p99 > 0 (mostly-zero with rare nonzero)gaussian z-score assumption is wrong — empirical distribution is point-mass-at-zero plus a tail; Bregman divergence with poisson / bernoulli kind tag is the correct distance
dominant_dim_masspattern-level: one dim's share of ((p99 − μ_d) / σ_d)² across dims ≥ 0.70pattern's delta_norm ranking is effectively single-dim; the sphere is a one-dim detector on this pattern, multi-dim composition adds little
negative_spaceper-dim: dim_percentiles[d]['p50'] == 0 AND dimension_kinds[i] == "gaussian"gaussian z-score is wrong — empirical distribution is point-mass-at-zero, not centered on the mode; gaussian semantics treat zero as the typical value when it is actually the absence value
heteroscedasticitypattern-level: Brown-Forsythe (median-centred Levene) p < 0.01 on delta_norm partitioned by group_by_propertyglobal θ assumption violated for this pattern; delta_norm variance differs sharply across the levels of the grouping variable, so a single global threshold produces unequal false-positive rates per group
non_normal_dimper-dim: Shapiro-Wilk (N ≤ 5000) or Kolmogorov-Smirnov (larger N) p < 0.01 on a kind='gaussian' dimgaussian z-score is wrong — empirical distribution is heavy-tailed, so (x − μ) / σ produces unequal false-positive rates per quantile of the dim; mu/sigma are stable but the percentile semantics are not

Each warning carries dim_label, reason (the offending value), and advice (concrete remediation); dominant_dim_mass and heteroscedasticity additionally carry evidence_value (the firing metric — share for dominant_dim_mass, p-value for heteroscedasticity) + threshold (the cutoff) so the agent can rank patterns by severity. Note: the heteroscedasticity warning's dim_label is the GROUPING VARIABLE name (a categorical line property), not a δ-dim — unlike the per-dim auditors. Triage rules:

Pattern-level calibration auditorsdominant_dim_mass, negative_space, and heteroscedasticity are sphere-design-quality signals; if they fire, raise a calibration ticket rather than chasing the entities flagged by find_anomalies on the affected pattern — those entities are likely noise.

  • Any dead_dim warning: drop the dim from the pattern, OR investigate the data source for missing values / constant column. Builder-time issue — won't fix itself on rebuild without a YAML edit.
  • sparse_dim warning on a binary-like signal (e.g. structuring flag, fraud label): switch to Bregman with kind: bernoulli. The warning is not a bug — it's the gaussian assumption being wrong for the data shape.
  • sparse_dim warning on a sparse counter (e.g. tx-count where most accounts have zero): split into is_active (bernoulli) + tx_count_when_active (poisson) dims. The single-dim representation conflates two regimes.
  • dominant_dim_mass warning: cross-check per-polygon reliability_flags.single_dim_driven incidence on find_anomalies top-N for the same pattern — pattern-level dominance ⟹ high per-polygon incidence agreement. Raise a calibration ticket; consider splitting the dominant dim into its own pattern or re-weighting via dimension_weights so the other dims actually contribute.
  • negative_space warning: re-declare the dim with kind='bernoulli' (presence/absence) or kind='poisson' (count), or split into a binary is_active dim plus a continuous value_when_active dim. Same remediation family as sparse_dim but the trigger is gaussian-declared, not empirical-distribution-shaped.
  • heteroscedasticity warning: per-group θ calibration is statistically warranted on the named grouping — the pattern already carries it via group_by_property, so the warning is confirmation, not a prescription for new work. If per-group θ is undesirable downstream (e.g. cross-group comparison of anomaly scores), apply a variance-stabilizing transform — log1p on delta_norm before thresholding — to make scores comparable across groups. Re-check after rebuild: variance-stabilizing should push the Levene p-value back above 0.01.
  • non_normal_dim warning: the empirical distribution of a gaussian-declared dim is heavy-tailed — z-score percentiles are unstable. Remediation in priority order: (a) re-declare kind as 'poisson' (counts) or 'bernoulli' (binary) if the data shape fits; (b) apply variance-stabilizing transform in the column source script (log1p for skewed positive, sqrt for right-skewed) and rebuild; (c) accept the warning if the dim is rarely top-of-rank — non-normal dims rarely dominate delta_norm rankings on their own. Composes with negative_space: if negative_space already fires on the same dim, non_normal_dim is suppressed (the kind itself is the bug, not the empirical departure).
  • No dim_quality_warnings block: pattern passed all five checks. Don't infer "perfectly healthy" — the warnings only catch the five specific silent-failure modes; other quality issues (correlated dims, stale data, drifted calibration) need separate diagnostics.

Regime changes

find_regime_changes(pattern_id, n_regimes=5)

Interpreting regime change results

  • 1 unidirectional shift = regime change (external event, policy change)
  • 2 shifts in opposite directions = oscillation (seasonal, cyclical)
  • ALL entities dropping simultaneously = data boundary artifact, not real change
  • Multiple small shifts = gradual evolution

Use compare_time_windows(pattern_id, pre_start, pre_end, post_start, post_end) to identify which dimensions shifted and by how much.


Emerging anomalies

find_anomalies(pattern_id, top_n=10, include_emerging=True)

Emerging entities are trending toward the anomaly boundary but haven't crossed yet. Only act on reliability=high forecasts.

If edge table available: contagion_score_batch(emerging_keys, pattern_id) — emerging entities with high neighborhood contamination are higher-priority early warnings than those with clean neighborhoods. Pass timestamp_cutoff (Unix seconds) to compare contagion at the previous monitor tick vs now — a jump between the two is a hard alert signal.


Handing off to other skills

Monitor flags, investigator digs. When you find:

  • Specific entity with source_count >= 2 — hand to gds-investigator
  • Sudden trajectory change on one entity — hand to gds-investigator
  • Population-level shift — report as finding, no entity drill needed

Anti-patterns

Anti-patternFix
Using detail="full" by defaultStart with detail="summary" — "full" adds I/O per pattern and can take minutes on >100K entities
Treating drift as anomalyDrifters may still be within normal range — check is_anomaly
Binary geometry drift analysisBinary geometry produces degenerate drift results — needs continuous geometry
Investigating low-magnitude driftersFocus on top-N by displacement — low-magnitude drift is noise

When things don't work

  • Tool returns empty results — try different parameters, wider sample, or a different pattern. Check that the pattern has temporal data.
  • Tool errors — check pattern_id and version, verify sphere is open. If the error persists, report it rather than retrying in a loop.
  • No anomalies found — not every sphere has every anomaly type. Report "no signal detected" as a valid finding.
  • find_drifting_entities returns no drifters — the population may be stable, or the pattern lacks sufficient temporal slices. Both are valid findings worth reporting.
  • find_regime_changes returns no changepoints — the population geometry has been stable over the observed period. Report stability as a finding.
  • check_alerts returns no alerts — geometric health is clean, but still run find_regime_changes and find_drifting_entities to check for behavioral shifts. No alerts + no drift + no regime changes = truly healthy.

Skill delegation

NeedSkill
Root cause tracing, entity 360, hypothesis testinggds-investigator
Event rates, Simpson's, temporal bursts, drift recipesgds-detective
Cross-pattern, neighbor, trajectory, segment scansgds-scanner
Orientation, profiling, clusteringgds-explorer

Full monitoring examples: references/examples.md

When alerts say population shifted unexpectedly

If compare_calibrations between two epochs shows large RMS drift on mu or sigma and you don't have an obvious data-source change to explain it, run find_calibration_influencers to see WHICH entities had highest impact on the new calibration. The hidden-influencer cell often catches data-quality regressions (duplicated records, miscategorised entities) that warped μ/σ across the population.

mcp__hypertopos__find_calibration_influencers(
    pattern_id="<pattern>",
    classify="all",
    top_n=10,
)

Inspect the cell_counts distribution — a healthy population is dominated by "normal". A spike in "hidden" or "distorter" per epoch is a signal that recalibration was driven by a small subset, not population-wide drift.

Gives 0 of the 12 instructions most mcp tooling skills give in ~5.5k tokens

Counted across 638 of the 750 authors here whose files we hold, read 2026-08-06

  • create ten complex read-only evaluation questionsin 71 of 638, across 17 files
  • test servers using MCP Inspectorin 60 of 638, across 18 files
  • provide actionable error messagesin 56 of 638, across 14 files
  • prioritize comprehensive API coverage over specific workflowsin 54 of 638, across 12 files
  • use TypeScript and Streamable HTTP for remote serversin 53 of 638, across 7 files
  • define structured output schemas where possiblein 51 of 638, across 9 files
  • use Zod or Pydantic for input schemasin 48 of 638, across 6 files
  • fetch MCP specification pages with markdown suffixin 46 of 638, across 4 files
  • load framework documentation using WebFetchin 45 of 638, across 3 files
  • verify each evaluation answer independentlyin 45 of 638, across 3 files
  • implement API client with authentication and paginationin 45 of 638, across 3 files
  • Define input schemas with validationin 28 of 638, across 10 files

Said here and by no other author read

  • check temporal data availability before monitoring
  • check population health before drilling to entities
  • run temporal checks even without alerts
  • respond to alerts by severity
  • triage deteriorating entities first
  • investigate single large dimensional changes

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.