Skip to content

harvest: user messages wrapped in <pasted_content …> are treated as meta, so pasted briefs never become tasks #318

Open

Description

@ESitaly

Version examined

  • microsoft/SkillOpt main @ 343db229dbd5ddaf9df6b1d5540d8bcdb2604d5c (2026-10-06), package skillopt_sleep.
  • Claude Code plugin skillopt-sleep 0.1.0 from the same commit.
  • Windows 11 Pro (build 26300), Python 3.12.13, plugin runner started from Git Bash 5.3.
  • Transcripts written by the Claude Code desktop app (Code tab), version 2.1.271.

Observed behavior

_is_meta_prompt() (skillopt_sleep/harvest.py, lines 137-155) treats any text that starts with < and ends with > as system noise (line 142).

The desktop app stores pasted text in the user message wrapped in a tag pair carrying the same id: <pasted_content id="…"> … </pasted_content id="…">. We verified this on our own transcripts by checking only the opening and closing tag, without exporting their content. A pasted brief is therefore dropped, and it is often the main request of the session.

Three consequences, all reproduced below with synthetic data:

  1. Wrong intent. If the user then writes a short follow-up such as "Yes, go ahead with option A.", that follow-up becomes the mined task intent, because heuristic_mine() takes the first surviving prompt (skillopt_sleep/mine.py, line 175).
  2. Session silently lost. If the pasted brief is the only user message, n_user_turns is 0. _is_headless_replay() (harvest.py, lines 217-218) then classifies the session as one of the engine's own replays, and the whole session is dropped, although it contains real assistant work.
  3. Related. A user message that starts with a host-injected <system-reminder>…</system-reminder> block and then contains the real request does not end with >, so it is kept, but the reminder block is copied verbatim into the task intent.

In a real run, 2 of 5 hand-picked sessions were mined from the wrong message for reason 1.

Expected behavior

  • Treat <pasted_content …> blocks as user content: strip the wrapper tags and keep the inner text as the user's intent.
  • Limit the "meta" heuristic to known host and system tags (for example <command-message>, <command-name>, <local-command-stdout>, <system-reminder>) instead of any text wrapped in angle brackets.
  • Strip host-injected <system-reminder> blocks from intents.
  • Do not classify a session that has real assistant turns as a headless replay only because all its user turns were filtered out.

Minimal synthetic reproduction

No model calls and no network. Run from the repository root, or set SKILLOPT_REPO to it.

"""Synthetic repro: pasted briefs are dropped by the harvest meta filter (no model calls, no network)."""
import json
import os
import sys
import tempfile

sys.path.insert(0, os.environ.get("SKILLOPT_REPO", "."))
from skillopt_sleep.harvest import _is_meta_prompt, harvest  # noqa: E402
from skillopt_sleep.mine import heuristic_mine  # noqa: E402

ROOT = tempfile.mkdtemp(prefix="skillopt-d19-")
PROJECT = os.path.join(ROOT, "proj")
TRANSCRIPTS = os.path.join(ROOT, "projects")
os.makedirs(PROJECT)

BRIEF = ('<pasted_content id="a1b2">\nInstall tool X into a dedicated folder, pin the version, '
         'back up the configs first and write a short report.\n</pasted_content id="a1b2">')
REMINDER = ('<system-reminder>\nStatus note injected by the host app.\n</system-reminder>\n\n'
            'Yes: run the third review on range r2..abc1234 and update the report.')


def session(sid, turns):
    folder = os.path.join(TRANSCRIPTS, "proj")
    os.makedirs(folder, exist_ok=True)
    with open(os.path.join(folder, sid + ".jsonl"), "w", encoding="utf-8") as f:
        for i, (role, text) in enumerate(turns):
            f.write(json.dumps({"type": role, "cwd": PROJECT, "sessionId": sid,
                                "timestamp": f"2026-01-01T10:{i:02d}:00Z",
                                "message": {"role": role, "content": text}}) + "\n")


session("s1-pasted-then-followup", [("user", BRIEF), ("assistant", "Plan: ..."),
                                    ("user", "Yes, go ahead with option A."), ("assistant", "Done.")])
session("s2-pasted-only", [("user", BRIEF), ("assistant", "Plan: ..."), ("assistant", "Done.")])
session("s3-reminder-prefix", [("user", REMINDER), ("assistant", "Running the review.")])

print("_is_meta_prompt(BRIEF) =", _is_meta_prompt(BRIEF))
digests = harvest(TRANSCRIPTS, scope="invoked", invoked_project=PROJECT)
print("harvested sessions:", sorted(d.session_id for d in digests))
for t in heuristic_mine(digests):
    print(f"task from {t.source_sessions[0]}: intent = {t.intent!r}")

Output at the commit above:

_is_meta_prompt(BRIEF) = True
harvested sessions: ['s1-pasted-then-followup', 's3-reminder-prefix']
task from s3-reminder-prefix: intent = '<system-reminder>\nStatus note injected by the host app.\n</system-reminder>\n\nYes: run the third review on range r2..abc1234 and update the report.'
task from s1-pasted-then-followup: intent = 'Yes, go ahead with option A.'

s2-pasted-only is missing from the harvested sessions: the pasted brief was its only user message.

Related

Not verified

  • Whether the Claude Code terminal CLI, or other clients, use the same <pasted_content> wrapper. We observed it only in the desktop app.
  • Whether other host tags that wrap a whole user message exist and are dropped the same way.

Activity

  1. Yif-Yang commented on Oct 18, 2026

    @Yif-Yang
    Contributor

    #321 fixes the original pasted-brief loss, including pasted-only sessions and follow-up requests. The new review also finds two regressions: literal user examples containing a system-reminder tag lose their content, and a known host-only record can consume the session cap ahead of a real request. Both have current-main controls and independent verification. The issue stays open while the author retains the useful unwrap behavior and corrects those content/cap boundaries.

  2. Yif-Yang commented on Oct 23, 2026

    @Yif-Yang
    Contributor

    The updated #321 fixes leading-reminder contamination, the host-only session-cap regression and genuine pasted-brief recovery. It still globally strips <pasted_content> tags from user-authored inline and fenced parser examples, changing the digest and mined intent; those examples survive on current main. The requested follow-up is to distinguish host wrappers from literal user text while preserving the passing reminder, pasted-brief and Copilot privacy controls. This issue remains open and the current PR should not merge with that regression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions