Skip to content

P2: Structured worker result in the lead's wake notice, rendered as a card #1427

Closed

Description

@currentbits

From the T3 Code Orchestrator V2 comparison (report: reports/T3 Code orchestrator for Solenta.md on branch coder/i-want-you-to-research-t3-codes-orchestr-fae77a). This is item 3 of 4. When a fork is merged back in V2, it hands back a summary of "decisions, files changed, commands/tests run, conclusions, and unresolved issues". In Solenta, the lead gets only the first line of the worker's last reply plus its branch (queueOrchNotice, electron/runner.js:1302).

Build

Step 1 (S). Extend queueOrchNotice to add a bounded block, about 2,000 characters, built from data Solenta already stores. No LLM summary is needed.

  • git diff --stat --summary <leadSnapshotSha>..<branch>. --summary prints create mode 120000 lines, which is exactly the case where a worker merge replaced core/dist with a symlink on main.
  • The verify gate's verdict for the worker's last turn.
  • The worker's invalidated hypotheses from the hypothesis ledger.
  • Open items from the worker's review itinerary (electron/reviewItinerary.js).

Step 2 (S). Show worker-result notices as a card in the lead's transcript, with a button that opens the Integration view (git:integrateWorker, electron/ipc.js). Clicking it counts as a real human approval. The card must be visible as soon as it arrives. V2's merge-back gives no sign it worked until the next message is sent (t3code #15063).

Tests

  • The notice for a worker branch that adds a symlink includes the create mode 120000 line.
  • The block is truncated at the cap.
  • The card renders, and its button calls integrateWorker.

Size: S + S. No dependencies.

Activity

  1. currentbits commented on Oct 4, 2026

    @currentbits
    OwnerAuthor

    A code-level pass produced a design for this issue. Full detail: reports/T3 Code orchestrator deep dive.md on branch coder/i-want-you-to-research-t3-codes-orchestr-fae77a. Revised size: M, about 350–450 lines including tests (2–3 days), up from S+S.

    Corrections to the issue body

    • T3 has nothing to port here. In T3's code a child's result is just its last assistant message, and the parent is woken with a fixed pointer sentence. The "decisions, files, tests, open issues" delta exists only in T3's design docs. This is original design work.
    • The diff can miss the last turn. The checkpoint on the non-verify path is fire-and-forget (runner.js:1526-1532), so the branch can lag behind the worker's final edits. Workers must await it first. This is race R3 in the new race issue.
    • The itinerary has no open items. It has risks (reviewItinerary.js:43-53), so use those.
    • Appending text breaks the transcript fold. src/workerActivity.ts:51-62 exact-matches the canned notice text. Carry the data on the message row instead.

    Design

    interface WorkerResult {
      workerId: string; title: string; status: "done" | "failed";
      branch: string | null; baseSha: string | null;
      diffstat: string | null;   // git diff --stat=100 --summary <base> HEAD, ≤30 lines / 1,500 chars
      flags: string[];           // --summary lines matching /mode 120000|delete mode/ (the core/dist symlink case)
      uncommitted: number;       // git status --porcelain count
      verify: { ok: boolean; command: string; attempt: number; timedOut: boolean } | null;
      ruledOut: string[];        // invalidated hypotheses, ≤5
      risks: string[];           // itinerary risks, ≤5
    }
    // ChatMessage gains workerResults?: WorkerResult[] on fromNotice rows
    1. buildWorkerResult(worker) never throws and uses async git (gitTryAsync). The base comes from snapshotSha in crewIntegration.js:379-385. It returns null diffstat for worktree:false workers and remote projects.

    2. queueOrchNotice builds the result, then enqueues the P1: Durable crew notices and honest restart recovery with consent-gated resume #1426 record with result plus a text block of at most ~2,000 chars, then flushes.

    3. flushOrchNotices passes workerResults through startRun into the appendMessage extras (runner.js:8461-8474). "Not delivered" events carry them too.

    4. Renderer: a WorkerResultCard shows

      • status and verify chips;
      • the diffstat, collapsed after 8 lines;
      • a warning row for flags;
      • "Ruled out" and "Risks" lists;
      • a Review & integrate button wired to the existing onOpenCrewIntegration (ThreadView.tsx:804).

      It renders in UserMessageBlock before the worker-activity fold (ThreadView.tsx:1403-1466), so it's visible the moment it arrives. That's the lesson from T3's #15063.

    Tests

    • A worker that commits a symlink: the record and the wake row both carry create mode 120000.
    • On the non-verify path, the diff includes the last turn's files.
    • Caps and truncation hold.
    • A failed worker reports uncommitted > 0.
    • The renderer shows [data-worker-result], and rows without it still fold.

    Depends on #1426's record shape and the R3 fix.

  2. added and removed on Oct 12, 2026
  3. currentbits commented on Oct 12, 2026

    @currentbits
    OwnerAuthor

    Implemented in f0c1b70 on branch coder/p2-structured-worker-result-in-the-lead--7e14e2. Not landed yet.

    • Step 1: workerResultBlock in electron/runner-orch-notices.js adds a [worker result <id>] … [/worker result] block to the done/failed notice. The block holds the diff stat and summary of leadSnapshotSha..branch, the verify verdict (only while a verifyCommand is set), invalidated hypotheses, and review-itinerary risks. The body is capped at 2000 chars, and mode 120000 lines are moved to the top so the cap can't cut them.
    • Step 2: src/workerResult.ts parses the block. WorkerResultCard renders it in the lead's transcript, and its "Integrate into lead" button calls git:integrateWorker directly, which is a human action through IPC. Notice lines outside the block stay visible next to the card.
    • Tests: electron/test/worker-result-block.test.js covers the symlink line, the cap and itinerary risks. test/threadView.test.tsx covers rendering the card, clicking the button, and parsing the runner's real block output. Electron suite: 4672 pass. The 2 failures (automation-create-mcp trigger fields, store prLinks) also fail on clean HEAD.
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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions