Skip to content

Record executor status history and RIPE Atlas-style tags (API 1.17, schema 24) - #399

Merged
vincent10400094 merged 1 commit into
mainfrom
feat/probe-status-and-tags
Oct 6, 2026
Merged

vincent10400094 merged 1 commit into
mainfrom
feat/probe-status-and-tags

Conversation

@vincent10400094

Copy link
Copy Markdown
Member

Stacked on #396 (feat/public-probe-addresses). This branch contains #396's two commits; review only the last commit (Record executor status history and derive RIPE Atlas-style tags). Merge #396 first; this PR then shows only its own change.

Summary

RIPE Atlas-style status history and tags in the executor listing (API 1.17, dispatcher schema 24).

  • Status. GET /executors entries gain status {name, since}, status_since, first_connected, last_connected, total_uptime and tags. Names: connected (has a control session), disconnected (last connected at most 30 days ago), abandoned (last connected more than 30 days ago; since = last_connected + 30 d), never_connected (enrolled or owned executor ID that has never registered). The threshold is wire.AbandonedAfter, documented in docs/operations/executor-discovery.md#probe-status-and-tags.
  • Listing compatibility. Without a parameter the listing is unchanged (connected executors only), so dbl run selection and DiscoverExecutors are not affected. ?status=disconnected,abandoned,never_connected (comma-separated or repeated) also lists the others with id, display, version, last_seen, admission: offline, status fields, host tags and their last recorded addresses (under the same is_public rule); other fields are zero/null. If the history cannot be read, the default listing reports registration times instead of failing; a filtered listing answers 500.
  • Storage (schema 24, 00024_probe_status.sql). probe_status (one row per executor) and probe_addresses (runs of one address per family). A registration upserts the row; once a minute the existing maintenance loop advances last_connected, total_uptime and address runs of registered executors and closes every other connected row at its last record (this also closes rows left open by a stopped dispatcher). A registration within 120 s of a connected row's last record (a replacement session or a quick dispatcher restart) continues the streak. Address runs ended > 91 days ago are pruned hourly, keeping every family's latest run. The migration fills probe_status from attribution_chains, so known executors keep first/last registration; uptime and addresses start empty. storagecheck minimum raised to 24 (the listing reads the tables), so upgrade with make deploy-upgrade-db before starting.
  • Host tags. Fixed vocabulary home, office, datacentre, academic, cloud, dsl, cable, fibre, wifi, mobile, satellite, nat (max 8) in [metadata] host_tags, or dbl executor join --host-tag. Validated by the executor (it refuses to start), by join (before anything is sent), and by the dispatcher (drops a malformed list). Read at registration. Proto: VantagePointReport.host_tags = 14.
  • System tags (connected executors only):
    • system-ipv4/ipv6-works: a fresh measured connectivity check, or a current observed address (the control connection, or a reflection in the last 25 min).
    • -capable: an address of the family observed in this session, or a fresh check.
    • system-ipv4-rfc1918: the executor reports only the boolean "my local IPv4 source toward the dispatcher is RFC 1918", taken from a UDP connect that sends nothing, and the observed IPv4 address is global.
    • system-ipv4/ipv6-stable-1d/30d/90d: from the address runs.
    • system-resolves-a/aaaa-correctly: cheap, because the PR 1 observation round already resolves the dispatcher's name. The tag means the resolver's A/AAAA answer reached the dispatcher and passed its TLS identity check. This is stricter than RIPE, since the family must also work.
    • Proto: AddressSelfCheck address_check = 15. It expires with the vantage report.
  • dbl nodes --status ... (can't be combined with the ready-executor filters), STATUS and TAGS columns (non-tag text is not printed); client.Probes(ctx, statuses...) requires 1.17 via Debuglet-API-Version, so an older dispatcher refuses rather than ignoring the filter.
  • OpenAPI, api/spec.go (1.17), CHANGELOG [Unreleased], docs/versions.md, docs/api.md, configuration (schema 24 tables, retention), onboarding (--host-tag), privacy table, and the canary's strict node-document check.

Example connected entry (other fields elided):

{
  "id": "eth-zurich-1",
  "status": {"name": "connected", "since": 1791000000},
  "status_since": 1791000000,
  "first_connected": 1780000000,
  "last_connected": 1791257000,
  "total_uptime": 9504000,
  "tags": ["home", "fibre", "system-ipv4-works", "system-ipv4-capable", "system-ipv4-stable-1d", "system-ipv4-stable-30d",
           "system-ipv6-capable", "system-ipv4-rfc1918", "system-resolves-a-correctly"]
}

Coordination

Testing

  • internal/dispatcher/database/probe_status_test.go: migration from schema 23 with existing chains and owned executors, streak/grace/uptime arithmetic, out-of-order address observations, pruning keeps latest runs.
  • internal/dispatcher/probe_status_test.go: lifecycle connected → disconnected → abandoned with a controlled clock, uptime, host and system tags (works/capable/stable/rfc1918/resolves), last addresses offline, private offline entries, never_connected.
  • internal/dispatcher/transport/api/probe_addresses_test.go: status filter over HTTP validated against OpenAPI, SDK Probes, Nodes unchanged.
  • cmd/dbl: --status request and version header, columns, refusal of unknown status and combination with filters; join --host-tag written and validated.
  • Locally on Linux (Docker, Go 1.26.8): internal/dispatcher/..., internal/executor, cmd/dbl, cmd/dispatcher, cmd/executor, internal/demo/..., internal/acceptance/canary, internal/storagecheck, pkg/... all pass. scripts/ci-generate.sh check, gofmt, vet.

Follow-ups

  • A RIPE-style DNS self-check against names other than the dispatcher's.
  • Ansible variables for address_opt_out and host_tags in the executor template.
  • System tags for disconnected executors (RIPE keeps the last ones).

🤖 Generated with Claude Code

API 1.17 adds status (connected, disconnected, abandoned after 30
days, never_connected), status_since, first_connected,
last_connected, total_uptime and tags to GET /executors, and a status
query parameter that also lists executors that are not connected. The
default listing is unchanged and degrades to registration times if the
history cannot be read.

Dispatcher schema 24 keeps probe_status and probe_addresses. A
registration records the executor as connected; once a minute the
maintenance loop advances uptime and address runs of registered
executors and closes the others at their last record, which also closes
rows a stopped dispatcher left open. A registration within two minutes
of a connected row continues its streak. The migration fills
probe_status from the recorded TESLA chains, and the build requires
schema 24.

Host tags come from a fixed vocabulary in [metadata] host_tags, also
set with dbl executor join --host-tag; executor and dispatcher both
validate them. System tags are derived from connectivity and the
observed addresses (works, capable), the address history (stable
1d/30d/90d), and the executor's address self-check: whether its local
IPv4 source toward the dispatcher is RFC 1918, reported as a boolean
only, and whether its resolver's A or AAAA answer for the dispatcher
name passed the dispatcher's TLS check. dbl nodes gains --status and
STATUS and TAGS columns, and the client gains Probes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vincent10400094
vincent10400094 force-pushed the feat/probe-status-and-tags branch from 331a45f to 725362b Compare October 6, 2026 13:25

@vincent10400094 vincent10400094 left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed rebased head 725362b. The incremental change persists executor status and address history in a schema migration, keeps address history bounded, exposes disconnected and never-connected states through explicit filters, and derives tags from dispatcher-observed or executor-reported evidence. The focused dispatcher, API, database, and executor tests passed; all required hosted CI checks are green. A local listener test fails identically on current main because its expected occupied port remains available in this environment; it is unrelated to this PR. GitHub does not permit author self-approval, so this comment records the completed review before the authorized administrator merge.

@vincent10400094
vincent10400094 merged commit 588f6b0 into main Oct 6, 2026
16 checks passed
@vincent10400094
vincent10400094 deleted the feat/probe-status-and-tags branch October 6, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant