Skip to content

0.10.0

Released 2026-07-30.

Delete provenance and host-scoped endpoints — the producer-alignment release. 0.10.0 ratifies an alignment round with the reference producer: the change feed now says who authored every disappearance, loopback endpoints stop collapsing across hosts, and the producer contract gains the rules that prevented a real flapping incident from being diagnosable.

Not a wire-contract break, no data migration. Every change is additive; newly written events carry schema version 1.1, older events read back unchanged.

Delete provenance — delete_source

Before 0.10.0, an entity expired by the liveness backstop and an entity deleted by its producer without a motive were rigorously indistinguishable on every read surface — and a removed relation covered three origins with no discriminant at all. That is exactly the question a flapping incident asks: "did my agent delete this, or did Toise reap it after a missed heartbeat?"

Every entity.deleted and relation.removed now carries its author (ADR 0033):

Value Meaning
producer an explicit entity.delete, or an edge dropped by absence on the source's re-emit
liveness_expiry Toise's backstop: no producer re-asserted it within entity.report.interval
cascade an endpoint entity died and took the edge with it
  • MCP: delete_source on recent_changes, entity_history, and graph_diff — including the entities_transient bucket, which turns the flap surface into a one-call triage.
  • GraphQL: ChangeEvent.deleteSource.
  • delete_reason is untouched in both directions: it stays the producer's verbatim motive, and the source is never derived from it.
  • Events recorded before 0.10.0 read back with an unknown source (null / omitted) — never re-labeled producer.

The 3-key endpoint identity {server.address, server.port, network.transport} exists so that two observers dialing the same routable address land on the same node. For addresses whose scope is narrower than the observation domain, that join is a lie: every host's 127.0.0.1:5432 collapsed into one node.

Per the ADR 0032 addendum, endpoints in exactly 127.0.0.0/8, ::1, 169.254.0.0/16, fe80::/10 now carry the observing host's id as a fourth identity key (host.id, byte-identical to the host entity identity). Everything else — including RFC1918 and CGNAT — keeps the 3-key form and its cross-observer join.

The read-time resolution honors the scope: a scoped endpoint resolves only against its own host's listeners (or the host itself), never through the fleet-wide bind scan. The conformance fixture pins the 4-key form on both sides of the contract.

Producer contract additions

  • telemetry.relay.* — the vendor-neutral spelling for "this telemetry passed through this agent on this host" on relayed spans: telemetry.relay.host.id / .host.name / .instance.id. First relay wins, the set of three is inserted atomically, and the keys are provisional pending upstream semconv#759.
  • Interval sizing rule — the recommended ×3 slack on entity.report.interval applies to the effective re-emission cadence (what the consumer can observe, e.g. an unchanged-state suppression cadence), not the internal heartbeat tick. Sizing on the tick gave a real-world producer ×1.5 effective slack and zero tolerance to a single missed re-emission — a mechanical flap.
  • Address canonicalization frozenroute.destination is explicit-prefix, zeroed-host CIDR; every IPv6 identity value is RFC 5952 text form; zone indices ride verbatim, lowercased, never fabricated.

Security

grpc v1.82.1 (GO-2026-6061) and Go toolchain 1.26.5 (GO-2026-5856, crypto/tls) in both modules; govulncheck is symbol-clean. Producers get the same grpc bump via pkg/emit/v0.5.1.