Skip to content

Source notice tracer: one safe waiting notice only for a proven origin #1049

Open

Description

@DoodleBears

Parent

#1019

Confirmed refinement — 2026-10-25 (Asia/Tokyo)

The Human approved prioritizing safe source-conversation waiting notices, reusing this issue rather than creating a duplicate specification. Two product choices were explicitly confirmed:

  • Default on, with a per-conversation off switch. This preference applies only within an existing authorized Bot/App Binding and conversation. It never creates posting authority, expands reception, or turns ordinary group members into Approvers.
  • First slice sends only the waiting notice. Approval settlement does not emit an extra approved/rejected/expired message. Normal task replies retain their existing behavior and authorization.

The first runnable candidate is a QQ group tool-approval notice, independent of native QQ approval controls. This is a scope/sequence refinement, not a claim that QQ controls or same-Orchestrator non-blocking continuation have shipped.

Problem

An IM-connected PersonaBot can still receive and durably admit messages while its Orchestrator waits on a native tool approval. Without a configured supported management destination, the pending card is visible only in the local management surface; the source conversation receives no explanation.

Existing work-failure alerts (#1041) observe committed failures, not pending approvals. Current external approval delivery is qualified for Lark private management conversations. Binding a QQ app does not automatically configure an Approval destination or establish a QQ approval interaction.

A public source notice and a detailed management notification have different audiences. The former explains why this request cannot continue; the latter lets an authorized Human inspect and decide. Keep them separate.

First runnable slice

One authorized QQ group Source Event causes one actual tool-approval request. After that request commits and while its owner remains pending, the Host attempts one fixed, safe notice to the proven source conversation, using this PersonaBot's own bound identity and existing Messaging Outbox. The Human can inspect and decide the original request in Web; the exact original operation retains the existing decision owner.

Suggested localized copy:

  • zh: 这条请求正在等待管理员确认,暂时无法继续。
  • en: This request is waiting for administrator approval and cannot continue yet.

Do not say “the administrator has been notified” without evidence of management delivery. No operation command/input, filesystem path, credentials, private management link, login token, other-platform content or private waiting reason belongs in the source notice.

The notice is Host-generated from committed approval state, not model-authored reassurance and not a failed-turn alert.

Source and lifecycle contract

  • Establish trusted request-to-source correspondence through owning intake/work context and the actual Session/call. Being the first/latest batch item, temporal proximity, historical Session text or the most recently active group is not causation.
  • Start with a single positively proven IM source. Multiple candidate sources, unknown origin, unrelated steering or a Schedule with no supported source correspondence emit no guessed notice. Record the reason through bounded developer diagnostics.
  • One request must not broadcast to every bound conversation. A new request in another conversation does not authorize disclosing why private work elsewhere is waiting.
  • Only an already committed, currently pending request is eligible. Recheck current Bot, Binding/account identity, source authorization, conversation preference and request state immediately before actual dispatch.
  • A preference change applies prospectively and fences unsent work. Re-enabling, reconnecting or restarting does not backfill historic requests or replay ambiguous sends. Default-on is not authorization to notify historical sources.
  • A disabled conversation receives no notice. Place this per-conversation preference in existing conversation/connector management, with an equivalent online CLI read/write path; do not create another destination picker.
  • Deduplicate by the canonical approval request and qualified source. Repeated observations of the same request do not create another notice. Different requests remain distinct; this slice does not introduce periodic reminders or notification batching.
  • Use a separately identified notice intent in the existing Outbox. It must not consume the ordinary final-reply identity, resolve Bot Inbox responsibility, mark the source “answered,” or decide the approval.
  • Known-unsent failures and Unknown Outcome remain distinguishable. Do not blindly retry ambiguous effects or automatically switch to a proactive send.
  • Notification failure does not cancel, reject, expire or clear the original approval. Canonical approval expiry/cancellation remains owned by the existing broker.
  • Delivery work must not wait for the model or a later Human decision. Platform acceptance is not proof of Human receipt or reading.

QQ qualification and delivery limits

QQ source replies depend on current checked Provider authority, including process-local source evidence and the applicable reply window/budget. A persisted Source Event or a connected app does not prove that a reply is currently possible.

Attempt the notice when the pending request commits, subject to current qualification. If a long-running task reaches approval after reply eligibility expires, expose an honest unavailable/failed outcome; do not silently borrow another identity or turn a passive reply into a proactive post. Proactive posting remains separately authorized and qualified outside this first slice. Do not promise that a day-old pending request can be retroactively notified.

Qualify the actual QQ group path and visible rendering using an explicitly authorized test conversation. Do not infer QQ support from a Lark fixture or an SDK capability flag.

Architecture direction

Deepen the existing source-notice module at the Messaging seam rather than copying a second origin/expiry/Outbox implementation.

Relevant prior art:

  • workspaces/tool-approval.ts: canonical committed approval notices and the existing native decision owner; the current notice does not itself identify an IM Source Event.
  • runtime/bot-runtime.ts: current accepted-source correlation used by private input, with ambiguity and lifetime checks.
  • credentials/mount.ts and credentials/private-inputs.ts: existing source-bound owner-action notice consumer.
  • messaging/outbound.ts: privateInputNotice uses an independent Outbox intent and does not count as the final answer.
  • messaging/approval-messaging.ts: explicit management route, qualified external decision delivery.
  • messaging/failure-alerts.ts: committed-failure notifications and their separate event semantics.

Keep approval decisions and private-input submissions in their respective owning modules. In particular, do not copy private input's notice-failure expiry behavior into tool approvals. ADR-0172 records the private-input design (its document remains Proposed); existing implementation is reusable evidence, not blanket qualification for this new flow. Preserve ADR-0141/0151/0176 authority and delivery constraints.

The goal is locality for source/notification checks and leverage across the existing request consumers. Avoid a generic notification framework, a second approval store, a second transcript or a substitute executor. Concrete interface design belongs to implementation.

Acceptance — notification-only QQ slice

  • Through a real authorized QQ group message, cause a real pending tool approval and show the original Web card plus exactly one safe source notice.
  • Prove request / Session / call / Source Event / Outbox correspondence; retained evidence contains no private commands, credentials or unrelated conversations.
  • Demonstrate default-on behavior for newly committed eligible requests on an authorized conversation; turn off through the existing UI and equivalent online CLI, prove suppression, then turn on and prove no historic replay.
  • Duplicate pending observations do not duplicate a notice; different committed requests retain distinct identities.
  • Positive single-proven-source and negative ambiguous/unknown/cross-conversation cases run through the owning module's public interface.
  • No notice marks the source answered, resolves its Inbox responsibility, consumes the final reply or changes approval outcome.
  • After Web approval or rejection, only the original operation settles; no extra settlement notice is sent and a permitted normal reply remains possible.
  • Cancellation before dispatch, conversation-off, Bot pause, Binding replacement/revocation and stale source authority prevent unsent effects.
  • Exercise reply expiry/budget refusal and Unknown Outcome without fallback posting or duplicate retries; the original approval remains pending unless its own owner settles it.
  • Reconnect/restart does not replay notices, revive old approvals or reconstruct an execution continuation.
  • Distinguish notification pending/accepted/failed/unavailable/unknown in bounded diagnostics and the existing authenticated inspection/CLI surfaces; do not claim a separate durable approval authority.
  • Add matching CLI commands for any changed Host method/route, bilingual CLI documentation, focused behavioral tests and real Host runs.
  • Retain real sanitized QQ and Web evidence and maintain affected English/Chinese guides. UI changes include matched before/after light/dark evidence and a runnable exact-version review path.
  • Obtain first-slice Human QA before extending providers, request kinds, destinations or automatic reminders. Merge, deployment and production receiver windows remain separately authorized.

Retained wider goal and explicit exclusions

The original end-to-end goal remains a safe waiting notice while unrelated messages continue normally. The notification-only slice does not complete that goal.

Dependency handling

The existing native dependencies below are retained for the full original acceptance goal. Notification-only delivery is proposed as a separately reviewed intermediate milestone; it does not justify closing this issue, deleting dependencies or claiming that unrelated Inbox work already continues.

If an executable child is needed to schedule that milestone independently, create and attach one only when its implementation contract and review path are ready. Do not create a speculative platform ticket tree.

Blocked by

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:fullstackEnd-to-end Host and Client implementationfeature:messagingMessaging module and external providersready-for-agentFully specified, ready for an AFK agentscope:tracerHuman-testable implementation slice

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions