Skip to content

Telegram Task Card self-heal needs a loaded-runtime drift diagnostic before refresh #987

Description

@huangzesen

What's wrong

PR #984 correctly adds one-time replacement recovery when Telegram refuses to delete an old resident Task Card. However, that recovery can only run after the live Telegram manager has loaded the new code. If the checkout is updated underneath an older long-lived manager process, the disk contains the self-heal fix while the live manager still holds the old implementation. The old card then remains visibly stale, /taskcard still reports a healthy enabled setting, and there is no resident-health or loaded-runtime diagnostic telling the user that one refresh is required.

This is not a regression in #984 and not a request to force-delete Telegram-nondeletable history. It is a bootstrap/observability gap around applying the already-merged self-heal code.

Where

  • Component: Telegram Task Card resident lifecycle / runtime diagnostics
  • Existing repair: src/lingtai/mcp_servers/telegram/manager.py in PR fix(telegram): recover non-deletable task card #984
  • Settings command: account.py::_cmd_taskcard
  • Related implementation commit: fcf86b7618be1f1e77a01ed8d6243439676b8616
  • Related merge commit: bdf2c5573505eadfb46d9190074aa4fb742ae78b

Reproduction

  1. Start the agent/Telegram manager before the Task Card repair is present in the running process. In the observed case, the process started at 2026-07-19T00:37:50Z.

  2. Update the on-disk checkout without restarting that process. The observed checkout became clean detached HEAD e5c86af6e991188619804f29572a3eb34fda8906 at 2026-07-19T04:01:45Z; fcf86b76 was confirmed as its ancestor.

  3. Confirm the Task Card setting remains enabled: taskcard=true, normal_rows=3.

  4. From a fresh subprocess, import lingtai.mcp_servers.telegram.manager from that checkout. It reports the new repair is present and recognizes both exact terminal descriptions:

    bad request: message can not be deleted for everyone
    bad request: message can't be deleted for everyone
    

    This proves the disk/import target contains the fix, but not that the already-running manager loaded it.

  5. Send one ordinary Telegram message and perform one read-only tool call to advance the per-chat high-water mark. Do not toggle /taskcard off/on. The human observer confirmed that no replacement Task Card appeared.

  6. Perform exactly one authorized agent refresh, with no pull, checkout switch, or config change. The new process started at 2026-07-19T06:57:30Z on the same clean e5c86af6 checkout and the same Task Card config.

  7. Perform the same read-only post-refresh activity. The human observer immediately confirmed that a new Task Card replacement appeared. The old nondeletable card remained in history, which is expected.

What you expected

When the installed checkout already contains the nondeletable-resident repair, the system should provide one of these safe outcomes:

  • the relevant lifecycle layer reloads the manager before advertising the new behavior; or
  • a diagnostic surface clearly reports that the live manager predates the installed runtime and that one refresh is required.

At minimum, /taskcard or a related health/status surface should distinguish enabled from resident healthy and repair code loaded.

What actually happened

/taskcard exposed only the enabled setting and normal-row count. The old frozen card looked like a failed self-heal even though the checkout already contained PR #984. A controlled event/tool probe produced no replacement. Only a manual refresh loaded the existing repair and allowed the one-time replacement to appear.

Severity

minor

The workflow was not blocked and one refresh resolved it, but the current status surface is misleading and the remediation is non-obvious. It can cause users to mistake a frozen historical resident for an active task or a failed new self-heal.

Suggested fix (optional)

Keep PR #984's bounded one-replacement semantics unchanged. Add a lifecycle-level loaded-runtime diagnostic rather than making /taskcard off/on a repair path.

Possible approaches:

  1. Record a non-secret build/source identity and manager start time when the Telegram manager launches.
  2. Compare the loaded identity with the currently installed runtime through a stable lifecycle/health surface outside the hot module, and report a deterministic refresh required to apply installed Task Card repair state when they differ.
  3. Extend /taskcard or an adjacent diagnostic with resident health, tracked resident state/ID, manager start/build identity, and the actionable stale-runtime hint. The plain settings response should not imply resident health.
  4. Add an integration regression for: old manager starts → disk gains the repair → controlled event advances high-water → status reports stale loaded runtime → one refresh → exactly one replacement is created → subsequent automatic/programmable frames edit the same replacement ID.
  5. Do not auto-toggle Task Card and do not repeatedly delete/send. If automatic lifecycle reload is unsafe, emit one bounded diagnostic instead.

The key boundary is that application-level self-heal cannot execute code the live process has not loaded; the missing piece is detecting and explaining that bootstrap condition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions