Skip to content

feat(agent-org): support post-completion chat and follow-up runs #635

Description

@ShiboSheng

Summary

Separate the long-lived Agent Org Group Chat Conversation from one bounded Agent Org Run so users can keep asking questions after a terminal result and can explicitly start a new, idempotent Follow-up Run for additional work.

Completed continues to mean “this work round is finished.” It no longer means “this Conversation is permanently closed.”

Current develop behavior

The current Group Chat send path persists the user's message as a Run-scoped AgentInbox row. It correctly accepts only running or paused Runs. A terminal Run therefore returns:

terminal runs do not accept new group messages

That protects Run finality, but it also disables ordinary post-result questions.

Current develop provides important foundations:

  • root_session_id is indexed and can anchor sequential Run history;
  • session_turn_intents.org_run_id gives active turns exact writable Run ownership;
  • Group Chat user-message history is durable and cursor-paged;
  • terminal finality, Inbox delivery, Wake, Recovery, and deletion are guarded.

One important gap remains: Worker Session ownership is still largely resolved through a parent-session walk. Reusing one Root Coordinator Session for multiple Runs without an exact Run-to-Worker-Session mapping could attach an old Worker to the newest Run.

Product model

Concept Meaning Lifetime
Conversation The long-lived Group Chat and transcript until archive/delete
Root Coordinator Session Conversation identity, transcript, and Coordinator continuity same as Conversation
Agent Org Run One bounded round of coordinated work start to terminal result
Worker Session One member's execution process for one exact Run never reused across Runs
AgentInbox Work input for Agents inside one active Run strictly Run-scoped
Follow-up proposal Durable suggestion to start another work round pending to accepted/dismissed/stale

The first implementation uses the existing Root Coordinator Session as conversation_id. It does not add a duplicate Conversation transcript table. The Root Session transcript owns long-lived user/Coordinator dialogue; AgentInbox remains active Run delivery only.

Behavior after a terminal Run

Path A — ask a question

  1. Persist the message in the Root Coordinator Session transcript, not the terminal Run Inbox.
  2. Start one Coordinator turn in explicit post-completion read-only mode.
  3. Provide bounded Run summary, Task summaries, output handles, Plan summary, and recent Conversation history.
  4. Allow detail reads such as task_get and Plan detail on demand.
  5. Return the answer without creating Tasks, writing old Inbox rows, waking old Workers, changing budgets, or mutating the source Run.

The first version routes post-completion @Reviewer and other historical member questions through the Coordinator using persisted results. Old Worker Sessions are never implicitly revived.

Path B — request additional work

  1. The same Coordinator turn decides that execution is needed; no extra classification-model call is added.
  2. Persist a structured Follow-up proposal with goal, rationale, and optional bounded task outline.
  3. Show a confirmation card. Do not start Workers yet.
  4. On confirmation, call idempotent org_follow_up_start.
  5. Create a new Run linked to the source Run, with fresh Tasks, Plans, Inbox, Recovery state, and Worker Sessions.
  6. Reuse the long-lived Root Coordinator Session while binding every active turn and Worker to the exact new Run.

Confirmation is the default to prevent accidental team token spend. Automatic start may be considered later as an explicit user setting.

Persistence and ownership

Run lineage and one-live-Run invariant

Add or normalize equivalent fields:

  • continued_from_run_id
  • originating_message_id
  • a unique idempotency index per Root Conversation
  • a partial unique index allowing at most one running or paused Run per Root Conversation

Existing databases must be audited for duplicate live Runs before enabling the unique index. Migration must not silently terminalize user data.

Exact Run-to-Session mapping

Add a canonical agent_org_run_sessions mapping with:

  • org_run_id
  • member_id
  • session_id
  • coordinator/worker role
  • creation timestamp
  • unique member and session identity within a Run

Resolution order:

  1. exact session_turn_intents.org_run_id for an active turn;
  2. exact Run Session mapping for Worker Sessions;
  3. the one live Run or selected newest historical Run for the shared Root Coordinator Session;
  4. parent walk only as a bounded legacy fallback that never overrides exact ownership.

The Root Coordinator Session may participate in sequential Runs. Worker Sessions belong to exactly one Run and are always recreated for a Follow-up Run.

Conversation-turn scope

Do not overload writable org_run_id as read-only history context. Extend the turn-intent contract with an explicit mode and optional reference_run_id:

  • agent_org_run_work: writable active Run ownership;
  • agent_org_post_completion: no writable Run, optional historical reference;
  • ordinary non-Agent-Org turns remain unchanged.

Mutation attempts in post-completion mode return a structured follow_up_run_required outcome instead of a red generic failure.

Durable proposal

Persist a bounded agent_org_follow_up_proposals record with Conversation Session, source Run, originating message, status, goal, proposal payload, timestamps, and optional created Run. Duplicate message/retry returns the existing proposal or Run.

org_follow_up_start

Within one SQLite writer transaction:

  1. load the proposal and terminal source Run;
  2. verify the Conversation exists and is not archived;
  3. verify no other live Run exists;
  4. coalesce a previously successful idempotency key;
  5. snapshot the current Agent Org definition;
  6. create the new Run and lineage;
  7. create exact Coordinator/Worker Run Session ownership rows;
  8. persist the confirmed new-Run goal;
  9. accept the proposal and record the created Run;
  10. commit.

Wake and provider calls occur after commit. A post-commit Wake failure leaves a valid recoverable Run and must not encourage a duplicate retry.

If Session materialization cannot participate in the same database transaction, use a truthful durable starting state with idempotent recovery. Do not claim atomicity across external effects or delete useful recovery evidence.

Coordinator authority after completion

Allowed:

  • read source Run Summary, Tasks, TaskOutput, Plan, and bounded Conversation history;
  • explain results;
  • create or update a Follow-up proposal;
  • start a Follow-up only under the configured confirmation policy.

Forbidden:

  • reopen or mutate the terminal source Run;
  • update old Tasks or write old Inbox rows;
  • wake old Workers;
  • clear completed_at or consume old recovery budget;
  • attach an old Worker to a new Run through parent walking.

UI behavior

  • Keep the input enabled after Completed, Failed, Cancelled, or Abandoned.
  • Show a neutral banner: This work round is complete. Ask a question or start follow-up work.
  • Render ordinary answers in the same Conversation transcript.
  • Render a durable Follow-up proposal card with confirm, edit, dismiss, loading, stale, conflict, and recovery states.
  • Show Run timeline boundaries and allow read-only historical selection.
  • Scope Team Tasks, Plan, Kanban, and Monitor to exactly one selected Run; never merge boards across Runs.
  • Only archiving the Conversation makes the input read-only.

Token and performance policy

  • no separate model call only to classify the message;
  • no old Worker Wake for historical questions;
  • bounded recent Conversation and Run summaries by default;
  • full outputs and Plans loaded only on demand;
  • no per-Run-card or per-member poller;
  • no unbounded Run timeline, proposal, transcript, or output arrays;
  • hidden and terminal views introduce no new background model or recovery work.

Delivery plan

Phase 1 — identity and exact ownership

  • Add lineage, idempotency, exact Run Session mapping, one-live-Run invariant, migration, and bounded Run timeline.
  • Make active execution prefer exact Turn/Session ownership over parent walking.

Phase 2 — post-completion read-only Coordinator turns

  • Route terminal messages to the Root transcript instead of old Inbox.
  • Add explicit read-only scope, bounded context, and structured mutation constraint.
  • Keep all old Workers asleep.

Phase 3 — durable proposal and Follow-up launch

  • Add proposal lifecycle and confirmation contract.
  • Implement transactional, idempotent launch and fresh Worker ownership.
  • Commit before Wake and recover acceleration failures safely.

Phase 4 — complete UI and restart behavior

  • Add banner, proposal card, Run timeline/selector, selected-Run views, and readable failure states.
  • Restore transcript, proposal, lineage, selected Run, and live Run across refresh/restart.

Phase 5 — migration and production hardening

  • Validate legacy databases, nested sessions, deletion, archive, crash recovery, multi-window behavior, and bounded token/context use.

Non-goals

  • Do not reopen terminal Runs or reinterpret Completed as Paused.
  • Do not implement Revision Events from feat(agent-org): add ordered revision events and incremental run sync #634 here.
  • Do not reuse Worker Sessions across Runs.
  • Do not write post-completion Conversation messages to old AgentInbox rows.
  • Do not permit multiple concurrent live Runs in one Conversation in the first version.
  • Do not add an extra intent-classification model call.
  • Do not create a second long-lived Conversation transcript store while the Root Session already owns it.

Acceptance criteria

  • Users can message after Completed, Failed, Cancelled, or Abandoned.
  • A normal question invokes only the Coordinator once.
  • The source Run, Tasks, Inbox, Sessions, interventions, and recovery budgets remain unchanged.
  • Historical member mentions do not wake old Workers.
  • Work requests create a durable proposal before starting Workers.
  • Concurrent confirmation/retry creates exactly one Follow-up Run.
  • The new Run has fresh Worker Sessions and exact Run/member ownership.
  • Old Worker Sessions always resolve to their historical Run.
  • The source Run remains terminal and readable while the new Run can execute, pause/resume, recover, and complete normally.
  • Refresh/restart restores transcript, proposal, lineage, selected Run, and live Run consistently.
  • Task, Plan, Inbox, Kanban, and Monitor projections never merge state from different Runs.
  • Large history and model context remain row/byte bounded.
  • Existing Running, Paused, Wake, Recovery, Approval, and Finality behavior does not regress.
  • Rust/database tests, production HTTP E2E, rendered WebDriver E2E, typecheck, lint, circular checks, formatting, and scoped Clippy pass.

Relationship to #634

This feature can ship using the current Snapshot plus invalidation design. If #634 lands later, Revision Events remain scoped to one exact Run, while Conversation UI separately projects Run-start, Run-terminal, and proposal boundaries. The two features are complementary but must not become one event-sourced rewrite.

Design document

Updated design: docs/architecture-audit-2026-08-01/AgentOrgPostCompletionConversationAndFollowUpRuns.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Effort: HighUXImprovements to user experience, workflow smoothnessenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions