Skip to content

Regression in 1.0.89: ACP sessions stop indexing conversation history and usage in session-store.db #5053

Description

@yfoel

Describe the bug

After switching from Copilot CLI 1.0.88 to 1.0.89, completed ACP sessions no longer populate the local session-store.db conversation and usage index.

A fresh direct ACP session completes normally, returns OK and stopReason: end_turn, and retains its messages, a positive session.usage_checkpoint, and a session.shutdown event in session-state/<sessionId>/events.jsonl. However, the corresponding sessions, turns, and assistant_usage_events rows are absent, including after session close and process exit.

The same workload indexes correctly in 1.0.88 ACP and in ordinary CLI prompt mode on both versions. This breaks local conversation lookup and indexed usage accounting for ACP integrations. It is not evidence of increased pricing or lost event-log messages.

Affected version

GitHub Copilot CLI 1.0.89.
Run 'copilot update' to check for updates.

The ACP agent's initialize response also reports agentInfo.version: "1.0.89". Known-good control: actual ACP agent version 1.0.88.

Version caveat: on this installation, copilot --no-auto-update alone runs the bundled 1.0.88 agent despite an ordinary copilot --version reporting 1.0.89. The controls below explicitly select the cached version and assert the initialized agent version.

Steps to reproduce the behavior

  1. Authenticate with Copilot and make the 1.0.88 and 1.0.89 packages available to the launcher. Use an empty test directory, with no project-specific MCP configuration.

  2. Launch the ACP server:

    env -u COPILOT_CLI_DIST_DIR -u COPILOT_CLI_VERSION \
      COPILOT_AUTO_UPDATE=false \
      copilot --no-auto-update --prefer-version 1.0.89 \
        --no-custom-instructions --disable-builtin-mcps \
        --context default --model gpt-6-sol --max-ai-credits 30 --acp

    This sends a paid prompt. The CLI requires a minimum credit cap of 30; that cap is not the amount charged.

  3. Connect a minimal ACP client over stdio. Send these newline-delimited requests in order, waiting for each response. Replace TEST_DIRECTORY with the absolute test-directory path and SESSION_ID with the ID returned by session/new. Assert initialize.result.agentInfo.version is 1.0.89 and the new session's selected model is gpt-6-sol.

    {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{"fs":{"readTextFile":false,"writeTextFile":false},"terminal":false},"clientInfo":{"name":"indexing-regression-probe","version":"1.0.0"}}}
    {"jsonrpc":"2.0","id":2,"method":"session/new","params":{"cwd":"TEST_DIRECTORY","mcpServers":[]}}
    {"jsonrpc":"2.0","id":3,"method":"session/prompt","params":{"sessionId":"SESSION_ID","prompt":[{"type":"text","text":"Reply with exactly OK. Do not use tools."}]}}
    {"jsonrpc":"2.0","id":4,"method":"session/close","params":{"sessionId":"SESSION_ID"}}

    The prompt returns OK and stopReason: end_turn. No tools, editor integration, resume, event-log edits, or headless initialization are needed. After close, terminate the ACP server normally with SIGTERM and wait for it to exit; the tested processes exited with code 0 and retained shutdown events.

  4. Inspect only this session's checkpoint and index rows. Set SESSION_ID to the returned UUID, then run this read-only check with Python 3:

    export SESSION_ID='UUID_RETURNED_BY_SESSION_NEW'
    python3 - <<'PY'
    import json, os, pathlib, sqlite3
    
    home = pathlib.Path(os.environ.get("COPILOT_HOME", pathlib.Path.home() / ".copilot")).resolve()
    sid = os.environ["SESSION_ID"]
    events = [json.loads(line) for line in
              (home / "session-state" / sid / "events.jsonl").read_text().splitlines()]
    checkpoints = [e for e in events if e["type"] == "session.usage_checkpoint"]
    print("checkpointNano:", checkpoints[-1]["data"]["totalNanoAiu"])
    print("shutdown:", any(e["type"] == "session.shutdown" for e in events))
    dbfile = home / "session-store.db"
    if not dbfile.exists():
        print("database: absent")
    else:
        db = sqlite3.connect(dbfile.as_uri() + "?mode=ro", uri=True)
        try:
            for table, key in [("sessions", "id"), ("turns", "session_id"),
                               ("assistant_usage_events", "session_id")]:
                count = db.execute(
                    f"SELECT count(*) FROM {table} WHERE {key}=?", (sid,)
                ).fetchone()[0]
                print(f"{table}:", count)
            nano = db.execute(
                "SELECT coalesce(sum(total_nano_aiu),0) "
                "FROM assistant_usage_events WHERE session_id=?", (sid,)
            ).fetchone()[0]
            print("indexedNano:", nano)
            print("quick_check:", db.execute("PRAGMA quick_check").fetchone()[0])
        finally:
            db.close()
    PY

    Representative 1.0.89 ACP result:

    checkpointNano: 4867600000
    shutdown: True
    sessions: 0
    turns: 0
    assistant_usage_events: 0
    indexedNano: 0
    quick_check: ok
    
  5. Repeat with only the selected agent version changed to 1.0.88, asserting that version in initialize. The completed control has one session row, one turn row, and one usage row; indexed nano-credits exactly match its checkpoint. As a mode control, run the same prompt through ordinary copilot --prompt mode on 1.0.89: indexing succeeds.

Expected behavior

Completed ACP sessions should retain their indexed conversation turns and usage, as they do in 1.0.88 ACP and ordinary CLI mode. For the single-turn reproduction, the exact user/assistant exchange should be queryable and indexed nano-credits should match the retained cumulative checkpoint.

Additional context

Environment: macOS 26.7 (build 25G229), Apple Silicon/arm64; Homebrew standalone launcher with cached agent packages. The minimal client was a Node.js 24.21.0 process using stdio pipes, not an editor or terminal-emulator integration. Both versions used the same model, prompt, context tier, directory, and client implementation.

Ten completed differential probes produced:

Actual agent version Mode State Completed probes Indexed session / turn / usage rows per probe
1.0.88 ACP Existing profile 2 1 / 1 / 1
1.0.89 ACP Existing profile 2 0 / 0 / 0
1.0.88 ACP Isolated profile 2 1 / 1 / 1
1.0.89 ACP Isolated profile 2 0 / 0 / 0
1.0.88 CLI Existing profile 1 1 / 1 / 1
1.0.89 CLI Existing profile 1 1 / 1 / 1

The isolated profile had no settings, MCP configuration, or pre-existing database. It reused cached executable packages and non-secret account references for existing credential-store authentication. Without resetting that profile, the sequence was 1.0.89 fail -> 1.0.88 pass -> 1.0.89 fail -> 1.0.88 pass. The initial 1.0.89 ACP probe did not create a database at all; 1.0.88 then created and populated it. Switching back to 1.0.89 still failed against that working database.

All ten probes retained the completed exchange and positive checkpoint. All passing probes had exact equality between indexed nano-credits and checkpoint totals. Both existing and isolated databases passed PRAGMA quick_check. Reads before session close, after close, and after process exit showed the same failure; later verification still found no rows more than six minutes after one failed probe. Four earlier completed 1.0.89 integration sessions also still have checkpoints but no indexed turns or usage.

Fresh ACP session.start.copilotVersion headers on this installation say 0.0.0; version attribution above uses the actual initialize.agentInfo.version, not those headers.

Targeted searches did not find an exact duplicate. Related but distinct: #3046 concerns a missing database on Windows/WSL2. #4363 and #4233 concern ACP usage protocol reporting; this report is about regressed local SQLite persistence, and the tested 1.0.89 ACP sessions did emit usage_update notifications.

The version/mode boundary is reproducible; the upstream source-code cause has not been identified, and a newer-version fix has not been tested. These excerpts contain only accounting/protocol results, not full session logs, credentials, or repository content.

Activity

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions