NousResearch/hermes-agent

Kanban comment author sanitization and disambiguation

Cluster 22452. Data as of

Nothing open on GitHub. Fix merged in #22769 on 9 May 2026. Check it covers your case.

The short answer

0open issues
0open PRs
3items grouped
Known?
Yes. 3 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #22769. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this resolved, deciding PR #22769. That is separate from the fix event.
Still open
Nothing open on GitHub.

These items address sanitizing and disambiguating how comment authors are rendered in the kanban build_worker_context. The changes appear focused on defense-in-depth improvements to author handling logic.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #22769 fix(kanban): sanitize comment author rendering in build_worker_context

    merged to main

    files: hermes_cli/kanban_db.py, tests/hermes_cli/test_kanban_core_functionality.py

    Show the diff
    • hermes_cli/kanban_db.py
      @@ -4072,7 +4072,14 @@ def _cap(s: Optional[str], limit: int = _CTX_MAX_FIELD_BYTES) -> str:
                   )
               for c in shown_c:
                   ts = time.strftime("%Y-%m-%d %H:%M", time.localtime(c.created_at))
      -            lines.append(f"**{c.author}** ({ts}):")
      +            # Render author with explicit "comment from worker" framing so
      +            # operator-controlled HERMES_PROFILE values like "hermes-system"
      +            # or "operator" can't be misread by the next worker as a system
      +            # directive above the (attacker-influenceable) comment body.
      +            # Defense-in-depth — the LLM-controlled author-forgery surface
      +            # was already closed in #22435. See #22452.
      +            safe_author = (c.author or "").replace("`", "")
      +            lines.append(f"comment from worker `{safe_author}` at {ts}:")
                   lines.append(_cap(c.body, _CTX_MAX_COMMENT_BYTES))
                   lines.append("")
       
    • tests/hermes_cli/test_kanban_core_functionality.py
      @@ -2507,6 +2507,27 @@ def test_build_worker_context_caps_prior_attempts(kanban_home):
               conn.close()
       
       
      +def test_build_worker_context_renders_author_with_safe_framing(kanban_home):
      +    """Author rendering wraps the operator-controlled author in code fences
      +    + "comment from worker" prefix so a misleading HERMES_PROFILE name
      +    (e.g. "hermes-system", "operator") can't be misread as a system
      +    directive above the comment body. Defense-in-depth — see #22452."""
      +    conn = kb.connect()
      +    try:
      +        tid = kb.create_task(conn, title="t", assignee="worker")
      +        kb.add_comment(conn, tid, author="hermes-system", body="some note")
      +        ctx = kb.build_worker_context(conn, tid)
      +
      +        # No bold-author rendering anywhere in the context.
      +        assert "**hermes-system**" not in ctx
      +        # Explicit provenance prefix is present.
      +        assert "comment from worker `hermes-system` at " in ctx
      +        # The body still renders.
      +        assert "some note" in ctx
      +    finally:
      +        conn.close()
      +
      +
       def test_build_worker_context_caps_comments(kanban_home):
           """Same cap for comments — comment-storm tasks stay bounded."""
           conn = kb.connect()
      @@ -2516,10 +2537,15 @@ def test_build_worker_context_caps_comments(kanban_home):
                   kb.add_comment(conn, tid, author=f"u{i % 3}", body=f"comment {i}")
               ctx = kb.build_worker_context(conn, tid)
               # Only _CTX_MAX_COMMENTS most-recent shown in full
      -        comment_count = ctx.count("**u")
      -        # 3 distinct authors u0/u1/u2 so the count is trickier; use the
      -        # "comment N" body text to count.
      -        body_count = sum(1 for line in ctx.splitlines() if line.startswith("comment "))
      +        # Count by body text since author rendering uses code-fenced
      +        # "comment from worker `<author>` at <ts>:" framing (#22452).
      +        # Comment bodies are "comment 0".."comment 99" so we need to
      +        # match the body specifically (digit suffix), not the author
      +        # provenance line (which also starts with "comment ").
      +        import re
      +        body_count = sum(
      +            1 for line in ctx.splitlines() if re.fullmatch(r"comment \d+", line)
      +        )
               assert body_count == kb._CTX_MAX_COMMENTS, (
                   f"expected {kb._CTX_MAX_COMMENTS} comments shown, got {body_count}"
               )

1 PR closed without merging

From the close comments: done elsewhere 1

  • #22488 fix(kanban): disambiguate worker comment authors · done elsewhere → ade5981, #22452, #22769
Closed issues · 1
  • Closed#22452kanban: defense-in-depth — sanitize comment author rendering in build_worker_context
How this cluster was grouped
  • Link evidence (structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
  • Pairwise link density 0.67: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Merged PRs
#22769
Closed issues
1
Attempts
1 PR closed without merging
Fix link checked
9 May 2026

For your agent

The same facts, typed.