How to remove stale provider records when peer roles change at runtime?

Hi everyone,
I’m new to Go and libp2p, and I’m building an application that uses Go-libp2p with the Kademlia DHT for peer discovery. I’ve run into some behavior that I don’t fully understand, and I’d appreciate guidance from people more experienced with the provider record system.

Use-case

Each peer in my system can have one or more “roles.”
Example: a peer may be both Role A and Role B at startup.

For discovery, I give each role its own DHT namespace:

  • /app/role/a

  • /app/role/b

A peer with both roles advertises itself under both namespaces.

The Issue

Roles can change at runtime.
For example, after 5 minutes the peer may drop Role B and continue as only Role A.

I expected that after the provider TTL expires, the peer would stop appearing in discovery results for /app/role/b.

However, I’m observing that:

  • Even long after the TTL has passed

  • Even after the peer stops advertising to /app/role/b

  • Even after restarting the peer with only Role A

…the peer still shows up as a provider under the old role’s namespace.

My Question

Is there a correct way to ensure that when a peer’s roles change at runtime, the peer is no longer discoverable under the stale role namespaces?

More specifically:

  • Does the Go-libp2p DHT automatically remove or expire provider records after TTL?

  • If not, what is the recommended pattern for dynamic-role discovery?

  • Is there an API for retracting or revoking a previously advertised provider record?

  • Or should I be implementing some kind of custom cleanup / re-advertisement strategy?

I feel like I’m missing something fundamental about how provider records and TTL interact, so any clarification or pointers to documentation would help a lot.

Thanks in advance!