You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Child threads: hidden from the sidebar, opened and messaged from the parent's Agents panel #8
Threads started by another thread (Model Router jobs, send) are real T3 threads that stay out of the sidebar, appear in the parent thread's Agents panel, open on click, and can be messaged there. This is the production version of spike #3 / draft PR #4, and the fork capability Model Router's send (toolboxmd/model-router#92) and T3-thread jobs build on.
Acceptance criteria
A real parent link on threads: prefer an optional parentThreadId on thread.create carried to the thread shell over the spike's sub.<parent>.<suffix> id convention; if the contract change is too invasive for a thin fork, keep the id convention and say why.
Child threads are hidden from the sidebar (no extra section).
The parent's Agents panel lists its child threads with status, and a row opens the child thread; the normal composer messages it.
The threads MCP toolkit from the spike (create, message, read) ships, with its safety rule: no message to a child that has not finished starting.
Upstream edits minimal and listed with files and lines in the PR body; new code in new files.
Upstream checks pass: vp run -r typecheck, vp lint, vp run -r test, vp fmt --check.
Proven live on an isolated T3 instance (never the user's instance on port 3773 or ~/.t3/userdata) with at least a Codex and an OpenCode child.
Non-goals
A back-link UI from child to parent (Model Router puts the parent link in the child's first message), mobile, OpenBot.
Blockers
None.
Objective contribution
Second completion criterion of the fork Objective: Model Router jobs run as T3 threads.
Submitted to Model Router as job t3code-8-1101 (source runner at model-router e837872, state dir ~/.local/share/durable-runner-planner-f1213, planner: Claude thread f1213d48). One PR will follow; not merged.
Production child threads are ready for review in #10 (branch feat/8-child-threads, commit 8e53f4376).
What shipped: threads spawned by another thread are real T3 threads with a sub.. id (kept over a real parentThreadId — the contract, projector, persistence and migration change was too invasive for this fork; reasoned in the PR body), hidden from both sidebars, listed with status in the parent's Agents panel, openable there and messageable via the composer, plus the threads MCP toolkit (spawn, message, read, list) with the still-starting guard.
Proof: install/typecheck/lint/fmt all exit 0; repo tests pass except one pre-existing unrelated failure (scripts/build-desktop-artifact.test.ts Windows-payload case, deterministic, zero overlap). New unit tests cover the status vocabulary, effort routing, delivery rule and id helpers. Live on an isolated instance (/tmp home, port 14768): a Codex child and an OpenCode child each ran to idle with exact-match replies, the starting guard fired with its exact retryable error, failed status surfaced with the provider error, list/read tracked all three children, and the composer path replied COMPOSER_OK. Details and upstream-edit line list are in the PR body.
Delivered in #10, squash-merged as dbc38af on main.
Root cause of the failing test suite: the threads toolkit handlers acquired engine.subscribeDomainEvents while their layer built. That layer builds with the HTTP routes, and the route-layer engine in apps/server/src/server.test.ts does not implement that method. Every server.test.ts case failed at startup with UnimplementedError: ... Unimplemented method "subscribeDomainEvents" (193 tests). The bridge now consumes the hot engine.streamDomainEvents, as the upstream reactors do. No test or assertion changed.
Proof (local; fork CI cannot run), on a7de0cd rebased onto main c98dafd:
vp run -r typecheck, vp lint and vp fmt --check all exit 0. GLOSSARY.md was reformatted so fmt passes.
Tests were run per package on the branch and on main in the same environment, then compared with comm. No test fails on the branch that passes on main.
apps/server has the same 50 environment-dependent failures on both: ThreadSettlementReactor worktree-retention, UsageService, CodexDriver npm-prefix and symlink cases.
scripts and apps/desktop now pass fully. Every other package passes.
Live UI check: isolated dev instance (T3 home under /tmp, ports 14768/6728, headless Chromium; the user's instance and data untouched).
The sidebar lists only the parent thread, not its children.
The parent's Agents panel lists every child with its status: Idle, or Failed with the provider error.
Clicking a row opens /<env>/sub.<parent>.<suffix>. The normal composer messaged that child, and it replied UI_COMPOSER_OK.
A new codex child spawned on the fixed build appeared in the panel, reached Idle with POSTFIX_CHILD_OK and reported back into the parent.
Codex and OpenCode children were already proven live in the earlier run.
Parent link: the sub.<parent>.<suffix> id convention is kept instead of a parentThreadId contract field. The PR body gives the reasons.
Activity
lukemaj commentedon Sep 25, 2026
Submitted to Model Router as job
t3code-8-1101(source runner at model-router e837872, state dir~/.local/share/durable-runner-planner-f1213, planner: Claude thread f1213d48). One PR will follow; not merged.lukemaj commentedon Sep 25, 2026
Production child threads are ready for review in #10 (branch feat/8-child-threads, commit 8e53f4376).
What shipped: threads spawned by another thread are real T3 threads with a sub.. id (kept over a real parentThreadId — the contract, projector, persistence and migration change was too invasive for this fork; reasoned in the PR body), hidden from both sidebars, listed with status in the parent's Agents panel, openable there and messageable via the composer, plus the threads MCP toolkit (spawn, message, read, list) with the still-starting guard.
Proof: install/typecheck/lint/fmt all exit 0; repo tests pass except one pre-existing unrelated failure (scripts/build-desktop-artifact.test.ts Windows-payload case, deterministic, zero overlap). New unit tests cover the status vocabulary, effort routing, delivery rule and id helpers. Live on an isolated instance (/tmp home, port 14768): a Codex child and an OpenCode child each ran to idle with exact-match replies, the starting guard fired with its exact retryable error, failed status surfaced with the provider error, list/read tracked all three children, and the composer path replied COMPOSER_OK. Details and upstream-edit line list are in the PR body.
lukemaj commentedon Sep 25, 2026
Delivered in #10, squash-merged as dbc38af on main.
Root cause of the failing test suite: the threads toolkit handlers acquired
engine.subscribeDomainEventswhile their layer built. That layer builds with the HTTP routes, and the route-layer engine inapps/server/src/server.test.tsdoes not implement that method. Every server.test.ts case failed at startup withUnimplementedError: ... Unimplemented method "subscribeDomainEvents"(193 tests). The bridge now consumes the hotengine.streamDomainEvents, as the upstream reactors do. No test or assertion changed.Proof (local; fork CI cannot run), on a7de0cd rebased onto main c98dafd:
vp run -r typecheck,vp lintandvp fmt --checkall exit 0. GLOSSARY.md was reformatted so fmt passes.comm. No test fails on the branch that passes on main.Live UI check: isolated dev instance (T3 home under /tmp, ports 14768/6728, headless Chromium; the user's instance and data untouched).
/<env>/sub.<parent>.<suffix>. The normal composer messaged that child, and it replied UI_COMPOSER_OK.Parent link: the
sub.<parent>.<suffix>id convention is kept instead of aparentThreadIdcontract field. The PR body gives the reasons.