Repository navigation
Description
Parent
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.tsandcredentials/private-inputs.ts: existing source-bound owner-action notice consumer.messaging/outbound.ts:privateInputNoticeuses 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.
- Same-Orchestrator non-blocking tool approval/continuation remains Wait tracer: Orchestrator formal requests do not stop other Inbox work #1038 / Blocked: qualify native exact-operation continuation for one Orchestrator root #1220; independent Assignment capacity work (Wait tracer: pending Assignment approvals free running capacity #1037) is not proof of it.
- Formal-question source notices remain later scope with Lark tracer: native Human questions answered from the paired DM #1031 and their own source/answer semantics.
- Shared management destinations and notification subscriptions remain Management destinations tracer: independent multi-target work-failure notifications #1492 and the applicable provider/group issues. That issue has an existing active task; do not create a parallel route registry or take over its scope.
- No native QQ approval buttons/text decisions, new Approver authority, automatic approval, new Orchestrator, execution replay, broad busy broadcast, settlement notification, periodic reminder or Host-down monitor is added here.
- Unknown or cross-source cases need a separate visibility policy before notifying another conversation; they are not silently solved by this slice.
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
Labels
Type
Projects
- StatusShow more project fieldsTodo
- StatusShow more project fieldsTodo
Activity