Skip to content

fix(honcho): fallback to durable peer cards for profiles#17124

Open
stephenschoettler wants to merge 1 commit into
NousResearch:mainfrom
stephenschoettler:fix/honcho-profile-card-fallback
Open

fix(honcho): fallback to durable peer cards for profiles#17124
stephenschoettler wants to merge 1 commit into
NousResearch:mainfrom
stephenschoettler:fix/honcho-profile-card-fallback

Conversation

@stephenschoettler

@stephenschoettler stephenschoettler commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes honcho_profile(peer="user") returning an empty profile hint when Honcho already has a durable peer card for the user.

The lookup keeps the existing assistant observer-target card check first. If that is empty, it falls back to the target peer's own card. For the current user peer only, it also tries migrated default-session cards stored as user-default-<peer>.

Related to #13375. This PR keeps the scope to the minimal peer-card fallback path and does not include the broader memory-file backfill work from #13375.

Related Issue

No linked GitHub issue.

Related PR: #13375

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • plugins/memory/honcho/session.py
    • Add fallback lookup paths for direct target cards and migrated user-default-<peer> cards.
  • tests/honcho_plugin/test_session.py
    • Add regression tests for target-peer fallback and legacy default user peer fallback.

How to Test

  1. Run the focused regression tests:

    python -m pytest \
      tests/honcho_plugin/test_session.py::TestPeerLookupHelpers::test_get_peer_card_uses_direct_peer_lookup \
      tests/honcho_plugin/test_session.py::TestPeerLookupHelpers::test_get_peer_card_falls_back_to_target_peer_own_card \
      tests/honcho_plugin/test_session.py::TestPeerLookupHelpers::test_get_peer_card_falls_back_to_legacy_default_user_peer_id \
      -q -o 'addopts='
  2. Run the session test module:

    python -m pytest tests/honcho_plugin/test_session.py -q -o 'addopts='
  3. Run the Honcho plugin suite:

    python -m pytest tests/honcho_plugin -q -o 'addopts='
  4. Optional live check with local Honcho:

    honcho_profile(peer="user") returns existing user facts for an anonymized local test user.
    

Validation Status

  • Regression tests fail without the production change: 2 failed.
  • Targeted regression tests pass: 3 passed.
  • python -m pytest tests/honcho_plugin/test_session.py -q -o 'addopts=': 117 passed.
  • python -m pytest tests/honcho_plugin -q -o 'addopts=': 268 passed.
  • Local live harness returned existing facts for honcho_profile(peer="user") with an anonymized local test user.
  • GitHub checks are not currently all green.
  • Failed checks: test, nix (ubuntu-latest), nix-lockfile-check.
  • Cancelled check: nix (macos-latest).
  • Full-suite checklist is not marked complete because pytest tests/ -q / GitHub checks are not green.

Checklist

Code

Documentation and Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior or N/A

For New Skills

N/A. This PR does not add a skill.

Screenshots / Logs

Live harness result from the original validation:

honcho_profile(peer="user") returned existing user facts for an anonymized local test user.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins tool/memory Memory tool and memory providers labels Apr 28, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #13375 — this PR is a minimal scoped subset of that broader honcho profile fallback + backfill PR.

@stephenschoettler

stephenschoettler commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

CI audit after opening #17124:

  • This PR only changes:
    • plugins/memory/honcho/session.py
    • tests/honcho_plugin/test_session.py
  • Targeted local validation passed:
    • RED check: the two new regression tests fail without the production change.
    • python -m pytest tests/honcho_plugin/test_session.py::TestPeerLookupHelpers::test_get_peer_card_uses_direct_peer_lookup tests/honcho_plugin/test_session.py::TestPeerLookupHelpers::test_get_peer_card_falls_back_to_target_peer_own_card tests/honcho_plugin/test_session.py::TestPeerLookupHelpers::test_get_peer_card_falls_back_to_legacy_default_user_peer_id -q -o 'addopts=': 3 passed.
    • python -m pytest tests/honcho_plugin/test_session.py -q -o 'addopts=': 117 passed.
    • python -m pytest tests/honcho_plugin -q -o 'addopts=': 268 passed.
    • Local live harness returned existing facts for honcho_profile(peer="user") with an anonymized local test user.

Current CI red checks appear unrelated to this PR:

  • test failed with the same current-main failure family seen on main run 25071418290 at head 7d464846, including normalize_whatsapp_identifier import failure, Firecrawl patch failures, MCP structured content failures, provider config validation failures, and TUI gateway protocol failure.
  • nix (ubuntu-latest) failed with the same current-main Nix issue seen on main run 25071418279 at head 7d464846: fixed-output hash mismatch for npm-deps, then failure building hermes-web-0.0.0.
  • nix-lockfile-check failed before reporting stale status with fix-lockfiles exited without reporting stale status. This PR does not touch Nix, web, npm, lockfile, or package files.

Passing CI checks: check-attribution, e2e, and supply chain scan.

@stephenschoettler

Copy link
Copy Markdown
Contributor Author

Updated against current green main (49c3c2e0).

What changed on the branch:

  • Merged current main into fix/honcho-profile-card-fallback.
  • PR is now mergeable.

Focused local validation:

  • python -m pytest tests/honcho_plugin/test_session.py::TestPeerLookupHelpers::test_get_peer_card_uses_direct_peer_lookup tests/honcho_plugin/test_session.py::TestPeerLookupHelpers::test_get_peer_card_falls_back_to_target_peer_own_card tests/honcho_plugin/test_session.py::TestPeerLookupHelpers::test_get_peer_card_falls_back_to_legacy_default_user_peer_id -q -o addopts='': 3 passed
  • python -m compileall plugins/memory/honcho tests/honcho_plugin/test_session.py -q: passed
  • git diff --check origin/main...HEAD: passed

Current CI notes:

  • nix, e2e, attribution, and supply-chain checks are green.
  • ruff + ty diff is red because the advisory workflow tries to post a PR comment from a fork PR and GitHub returns 403 Resource not accessible by integration. The generated lint summary reports 0 ruff issues.
  • test is red with broad failures outside this Honcho change set, including Bedrock, gateway restart, update, browser Chromium, delegate, and sandbox tests. Focused Honcho validation is clean.

erosika pushed a commit to erosika/hermes-agent that referenced this pull request May 27, 2026
honcho_profile(peer="user") returned an empty card even when Honcho
held a populated peer card for the user. Two independent bugs combined
to produce the symptom:

1. Read path: get_peer_card() called _fetch_peer_card(observer, target=user),
   which hits GET /peers/{observer}/card?target={user} — the observer's local
   card of the user. On self-hosted Honcho v3 this slot is empty unless writes
   also use it. The peer card lives on the user peer itself
   (GET /peers/{user}/card). Add a fallback: when the observer-target slot is
   empty and a target exists, retry against the target peer's own card.

2. Write path: set_peer_card() resolved only the target peer and called
   user_peer.set_card(card). The read path uses the assistant peer as
   observer, so writes and reads addressed different Honcho card scopes.
   Align set_peer_card() with _resolve_observer_target() so writes go to
   assistant_peer.set_card(card, target=user_peer_id), matching the read.

Both paths now use the same observer/target resolution, and the read
path additionally falls back to the target's own card for compatibility
with deployments where cards were written directly to the peer.

Closes: related to NousResearch#13375, NousResearch#17124, NousResearch#20729
kshitijk4poor pushed a commit that referenced this pull request May 27, 2026
honcho_profile(peer="user") returned an empty card even when Honcho
held a populated peer card for the user. Two independent bugs combined
to produce the symptom:

1. Read path: get_peer_card() called _fetch_peer_card(observer, target=user),
   which hits GET /peers/{observer}/card?target={user} — the observer's local
   card of the user. On self-hosted Honcho v3 this slot is empty unless writes
   also use it. The peer card lives on the user peer itself
   (GET /peers/{user}/card). Add a fallback: when the observer-target slot is
   empty and a target exists, retry against the target peer's own card.

2. Write path: set_peer_card() resolved only the target peer and called
   user_peer.set_card(card). The read path uses the assistant peer as
   observer, so writes and reads addressed different Honcho card scopes.
   Align set_peer_card() with _resolve_observer_target() so writes go to
   assistant_peer.set_card(card, target=user_peer_id), matching the read.

Both paths now use the same observer/target resolution, and the read
path additionally falls back to the target's own card for compatibility
with deployments where cards were written directly to the peer.

Closes: related to #13375, #17124, #20729
mathias3 pushed a commit to mathias3/hermes-agent that referenced this pull request May 28, 2026
honcho_profile(peer="user") returned an empty card even when Honcho
held a populated peer card for the user. Two independent bugs combined
to produce the symptom:

1. Read path: get_peer_card() called _fetch_peer_card(observer, target=user),
   which hits GET /peers/{observer}/card?target={user} — the observer's local
   card of the user. On self-hosted Honcho v3 this slot is empty unless writes
   also use it. The peer card lives on the user peer itself
   (GET /peers/{user}/card). Add a fallback: when the observer-target slot is
   empty and a target exists, retry against the target peer's own card.

2. Write path: set_peer_card() resolved only the target peer and called
   user_peer.set_card(card). The read path uses the assistant peer as
   observer, so writes and reads addressed different Honcho card scopes.
   Align set_peer_card() with _resolve_observer_target() so writes go to
   assistant_peer.set_card(card, target=user_peer_id), matching the read.

Both paths now use the same observer/target resolution, and the read
path additionally falls back to the target's own card for compatibility
with deployments where cards were written directly to the peer.

Closes: related to NousResearch#13375, NousResearch#17124, NousResearch#20729
Bryce-huang pushed a commit to wbkunlun/hermes-agent that referenced this pull request May 29, 2026
honcho_profile(peer="user") returned an empty card even when Honcho
held a populated peer card for the user. Two independent bugs combined
to produce the symptom:

1. Read path: get_peer_card() called _fetch_peer_card(observer, target=user),
   which hits GET /peers/{observer}/card?target={user} — the observer's local
   card of the user. On self-hosted Honcho v3 this slot is empty unless writes
   also use it. The peer card lives on the user peer itself
   (GET /peers/{user}/card). Add a fallback: when the observer-target slot is
   empty and a target exists, retry against the target peer's own card.

2. Write path: set_peer_card() resolved only the target peer and called
   user_peer.set_card(card). The read path uses the assistant peer as
   observer, so writes and reads addressed different Honcho card scopes.
   Align set_peer_card() with _resolve_observer_target() so writes go to
   assistant_peer.set_card(card, target=user_peer_id), matching the read.

Both paths now use the same observer/target resolution, and the read
path additionally falls back to the target's own card for compatibility
with deployments where cards were written directly to the peer.

Closes: related to NousResearch#13375, NousResearch#17124, NousResearch#20729

#AI commit#
mosaiq-systems pushed a commit to mosaiq-systems/hermes-agent that referenced this pull request May 29, 2026
honcho_profile(peer="user") returned an empty card even when Honcho
held a populated peer card for the user. Two independent bugs combined
to produce the symptom:

1. Read path: get_peer_card() called _fetch_peer_card(observer, target=user),
   which hits GET /peers/{observer}/card?target={user} — the observer's local
   card of the user. On self-hosted Honcho v3 this slot is empty unless writes
   also use it. The peer card lives on the user peer itself
   (GET /peers/{user}/card). Add a fallback: when the observer-target slot is
   empty and a target exists, retry against the target peer's own card.

2. Write path: set_peer_card() resolved only the target peer and called
   user_peer.set_card(card). The read path uses the assistant peer as
   observer, so writes and reads addressed different Honcho card scopes.
   Align set_peer_card() with _resolve_observer_target() so writes go to
   assistant_peer.set_card(card, target=user_peer_id), matching the read.

Both paths now use the same observer/target resolution, and the read
path additionally falls back to the target's own card for compatibility
with deployments where cards were written directly to the peer.

Closes: related to NousResearch#13375, NousResearch#17124, NousResearch#20729
KKT-OPT pushed a commit to KKT-OPT/hermes-agent that referenced this pull request May 31, 2026
honcho_profile(peer="user") returned an empty card even when Honcho
held a populated peer card for the user. Two independent bugs combined
to produce the symptom:

1. Read path: get_peer_card() called _fetch_peer_card(observer, target=user),
   which hits GET /peers/{observer}/card?target={user} — the observer's local
   card of the user. On self-hosted Honcho v3 this slot is empty unless writes
   also use it. The peer card lives on the user peer itself
   (GET /peers/{user}/card). Add a fallback: when the observer-target slot is
   empty and a target exists, retry against the target peer's own card.

2. Write path: set_peer_card() resolved only the target peer and called
   user_peer.set_card(card). The read path uses the assistant peer as
   observer, so writes and reads addressed different Honcho card scopes.
   Align set_peer_card() with _resolve_observer_target() so writes go to
   assistant_peer.set_card(card, target=user_peer_id), matching the read.

Both paths now use the same observer/target resolution, and the read
path additionally falls back to the target's own card for compatibility
with deployments where cards were written directly to the peer.

Closes: related to NousResearch#13375, NousResearch#17124, NousResearch#20729
@stephenschoettler

Copy link
Copy Markdown
Contributor Author

@teknium1 quick follow-up after #24847 landed.

I refreshed this branch against current main and resolved the Honcho conflicts. Scope is unchanged: durable peer-card fallback in plugins/memory/honcho/session.py, with regression coverage in tests/honcho_plugin/test_session.py.

This is adjacent to #24847, not the same fix. #24847 made Honcho startup fail open; this branch fixes the runtime profile lookup once Honcho is available.

Focused validation is clean: scripts/run_tests.sh tests/honcho_plugin/test_session.py -- -q --tb=short passed with 119 tests.

The branch is mergeable again. The remaining red check is inherited from current main, not from this Honcho change.

gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
honcho_profile(peer="user") returned an empty card even when Honcho
held a populated peer card for the user. Two independent bugs combined
to produce the symptom:

1. Read path: get_peer_card() called _fetch_peer_card(observer, target=user),
   which hits GET /peers/{observer}/card?target={user} — the observer's local
   card of the user. On self-hosted Honcho v3 this slot is empty unless writes
   also use it. The peer card lives on the user peer itself
   (GET /peers/{user}/card). Add a fallback: when the observer-target slot is
   empty and a target exists, retry against the target peer's own card.

2. Write path: set_peer_card() resolved only the target peer and called
   user_peer.set_card(card). The read path uses the assistant peer as
   observer, so writes and reads addressed different Honcho card scopes.
   Align set_peer_card() with _resolve_observer_target() so writes go to
   assistant_peer.set_card(card, target=user_peer_id), matching the read.

Both paths now use the same observer/target resolution, and the read
path additionally falls back to the target's own card for compatibility
with deployments where cards were written directly to the peer.

Closes: related to NousResearch#13375, NousResearch#17124, NousResearch#20729
(cherry picked from commit 5d450df256695b86477ad319148cf6c84c76f285)
@stephenschoettler stephenschoettler force-pushed the fix/honcho-profile-card-fallback branch from 83c5fec to 6a0e22c Compare June 8, 2026 17:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have tool/memory Memory tool and memory providers type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants