Skip to content

fix(sessions): stop a /skill's own text becoming the session title - #71843

Merged
OutThisLife merged 4 commits into
mainfrom
bb/skill-title-leak
Jul 26, 2026
Merged

fix(sessions): stop a /skill's own text becoming the session title#71843
OutThisLife merged 4 commits into
mainfrom
bb/skill-title-leak

Conversation

@OutThisLife

Copy link
Copy Markdown
Collaborator

A /skill invocation expands into a message that embeds the whole skill body before it reaches the agent. Two surfaces summarize a user turn from that raw content, and both were reading the skill's prose as if the user had written it.

Titles. generate_title() sent the first 500 characters of the turn to the auxiliary model — on a /skill turn, that's the skill's opening lines. /work sessions came back titled "Isolated Git Worktree Setup" and "Timeline idle optimization in worktree" instead of describing the actual request.

Previews. preview is the head of the first user message, and it's the title fallback on every surface: sidebar rows, pickers, exports, the desktop's sessionTitle(). An untitled skill session read [IMPORTANT: The user has invoked the "work" skill, indicatin... wherever it appeared.

describe_skill_invocation() sits next to the existing extract_user_instruction_from_skill_message() and reuses its markers, recovering /work — fix the title leak from an expanded turn. The titler and the preview queries both route through it, as does the /rewind picker.

Previews are computed on read, so existing sessions correct themselves with no migration. A title already written to the DB doesn't, so hermes sessions retitle-skills regenerates those — dry-run by default. Two guards earned on a real store: a candidate that isn't title-shaped is rejected rather than replacing a serviceable title with echoed command output, and a unique-title collision dedupes through the lineage the way the live auto-titler does.

While in there, the six copies of the preview subquery and four copies of its shaping collapse into one expression and one helper.

Verified against a copy of a real 1274-session store: 12 affected sessions, previews corrected on read, --apply re-titled 11 and correctly declined the 12th.

A /skill invocation expands into a message that embeds the whole skill body.
Anything that summarizes a user turn from its raw content reads the skill's
prose as if the user had written it.

describe_skill_invocation() sits next to the existing extractor and reuses its
markers, returning `/work — fix the title leak` for an invocation with an
instruction and `/work` for a bare one. It also exports the SQL LIKE pattern
and excerpt-joint sentinel that listing queries need to recognize scaffolding
before a row reaches Python.
generate_title() sent the first 500 characters of the user turn to the
auxiliary model. On a /skill invocation those characters are the skill's own
opening prose, so the session got named after the skill instead of the request
— /work sessions came back as "Isolated Git Worktree Setup".

Route the turn through describe_skill_invocation() first, so the titler sees
what the user typed. Also keep only the first line of the response: a model
that ignores "return ONLY the title" and answers the prompt would otherwise
have a shell transcript stored as the title, truncated mid-command.
`preview` is the head of the first user message and the title fallback on
every surface — sidebar rows, pickers, exports, the desktop's sessionTitle().
An untitled /skill session therefore read `[IMPORTANT: The user has invoked
the "work" skill, indicatin...` wherever it appeared.

A scaffolded row now selects a wide enough excerpt to reach the typed
instruction (head + tail spliced for a long body) and shapes it through
describe_skill_invocation(). Because previews are computed on read, existing
sessions are corrected without a migration.

The six copies of the preview subquery and four copies of its shaping collapse
into one expression and one helper along the way, and the /rewind picker gets
the same treatment.
Previews correct themselves on read, but a title already written to the DB
stays wrong. This regenerates those titles from what the user actually typed,
dry-run by default.

Two guards, both hit on a real store: a candidate that isn't title-shaped is
rejected rather than replacing a serviceable title with command output, and a
unique-title collision dedupes through the lineage the way the live auto-titler
does instead of leaving the leaked title in place.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard tool/skills Skills system (list, view, manage) area/sessions Session lifecycle, resume, persistence, history sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Jul 26, 2026
@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 16042b0

ℹ️ Info

Desktop E2E visual evidence · View test artifacts · View job

1 visual diff.

inline evidence upload failed.

Failed to upload diff-665a0833239e-onboarding-overlay-diff.png with gh image (exit code 1): Error uploading /home/runner/work/_temp/e2e-evidence/diff-665a0833239e-onboarding-overlay-diff.png: step 0 (get upload token): uploadToken not found on repo page — do you have write access to NousResearch/hermes-agent? (or, if NousResearch enforces SAML SSO, authorize at https://github.com/orgs/NousResearch/sso)

@OutThisLife
OutThisLife merged commit d64ab9e into main Jul 26, 2026
41 checks passed
@OutThisLife
OutThisLife deleted the bb/skill-title-leak branch July 26, 2026 08:53
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…e-leak

fix(sessions): stop a /skill's own text becoming the session title
33hodl pushed a commit to 33hodl/hermes-agent that referenced this pull request Aug 12, 2026
…e-leak

fix(sessions): stop a /skill's own text becoming the session title
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state tool/skills Skills system (list, view, manage) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants