Skip to content

humd: stop routing prompts on unverified capability claims - #67

Merged
adiled merged 3 commits into
mainfrom
routing/trust-announces
Oct 4, 2026
Merged

adiled merged 3 commits into
mainfrom
routing/trust-announces

Conversation

@adiled

@adiled adiled commented Oct 4, 2026

Copy link
Copy Markdown
Owner

Closes the routing hole I flagged an hour after landing #64.

What was wrong

A prompt with no local worker was routed to whichever peer advertised the model. That claim is self-declared, so any connected peer could announce a model it does not have and be handed the prompt.

Read from the code, not inferred:

  • publish_with_dusk never feeds the local subscriber, so hive_discover_all only ever sees announces relayed from peers
  • handle_gossip published and relayed any announce without checking the announced humd_id against the peer that sent it
  • hive_discover_all keys the table by humd_id taken from the payload
  • pick_remote_worker filtered on exactly two things: that claimed Hid is in ens.peers(), and that the manifest claims bee: ["worker"] + the model

So a peer could name any Hid and any model, and be selected.

Two defects, fixed separately

Claiming someone else's Hid — handle_gossip now rejects an announce whose humd_id is not the sender's, at the single point every announce funnels through. This also stops relaying it, so the mesh agrees.

Over-advertising for your own Hid — no check on an announce can catch this, because the claim is indistinguishable from an honest one. Refusing outright would break discovery entirely, so remote routing is now opt-in via HUM_TRUST_REMOTE_WORKERS, default off. A claim alone no longer moves prompt content.

That default is a product decision, not a technical limit — the honest fix is proof-of-possession or stake, and neither exists yet. Worth an issue; say the word and I'll write it.

Proof

sim/tests/remote_routing_trust.rs:

  • a_prompt_is_not_forwarded_on_an_unverified_capability_claim — the claiming peer receives nothing
  • opting_in_restores_discovery_routing — opt-in still reaches the worker

Both directions fail if the gate is removed (if false → 1 passed, 1 failed). New provenance tests in ensemble/src/lib.rs fail the same way when announce_claims_sender is neutered.

Full suites: ensemble --lib 107, humd --lib 38, sim 18/18 binaries, clippy clean on all three.

Note: sim humds set trust_remote_workers: true so #64's discovery tests still exercise routing. spawn_humd_not_trusting_remote_workers is the production default.

adiled added 3 commits October 4, 2026 23:07
find-the-worker routed a prompt to whichever peer advertised the model.
The claim is self-declared, so any connected peer could announce a model
it does not have and receive the prompt.

Two defects, addressed separately:

A peer could announce under a Hid it does not own. handle_gossip
published the payload and relayed it without checking that the announced
humd_id was the sender. Reject that at the gossip entry point, where
every announce funnels through.

A peer can still over-advertise for its own Hid, and no check on the
announce can distinguish that from an honest claim. Refusing the prompt
would break discovery entirely, so remote routing is now opt-in via
HUM_TRUST_REMOTE_WORKERS. Default off: a claim alone no longer moves
prompt content.

sim/tests/remote_routing_trust.rs covers both directions — a claiming
peer gets nothing by default, and opting in still reaches the worker.
Both fail if the corresponding gate is removed.
The provenance gate compared the payload's humd_id against the peer the
tone arrived on. Multi-hop gossip breaks that: A advertises, B relays,
C sees arrived_from=B while the payload claims A, so a legitimate
advertise was refused after one relay.

Compare against the tone's own from field, which is preserved across
hops. An added test covers A-B-C directly.
@adiled

adiled commented Oct 4, 2026

Copy link
Copy Markdown
Owner Author

Two fixes after review, both CI-caught rather than local-caught.

needless_borrow clippy lint — CI runs -D warnings; I ran clippy without it locally and missed it. Fixed.

The provenance gate broke multi-hop gossip. It compared the payload's humd_id against the peer the tone arrived on. With A—B—C, A advertises, B relays, C sees arrived_from=B while the payload claims A — so a legitimate advertise was refused after a single relay. ensemble/tests/hives_integration.rs caught it.

Now compares against the tone's own from field, which survives relaying. Added an_announce_relayed_by_a_third_peer_is_still_accepted covering A—B—C explicitly.

Rule 0 on the function body: 107 passed; 1 failed. My first attempt at this check disabled the call site while the unit tests call the function directly — reported green on a neutered gate. Corrected.

All 8 checks green.

@adiled
adiled merged commit febc862 into main Oct 4, 2026
8 checks passed
@adiled
adiled deleted the routing/trust-announces branch October 4, 2026 19:24
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