Repository navigation
Conversation
Draft for user confirmation (2026-09-25): the fork becomes the user's single working surface, stays a thin rebasable layer on upstream, runs Model Router jobs as T3 threads and hosts OpenBot as a UI mode. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Confirmed by the user on 2026-09-25. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Name the stable desktop build Chromeria with its own bundle id (md.toolbox.chromeria), Electron userData directory and icon set, so it installs and runs beside upstream T3 Code. Threads stay in the shared T3 home (~/.t3 or T3CODE_HOME). Desktop builds no longer embed a GitHub update feed, so the updater can never replace Chromeria with an upstream T3 Code release. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The #12 branding points production web favicons at assets/chromeria/, but two brand-assets tests still expected the upstream production icons. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…MCP toolkit (#8) (#10) * spike(server): threads MCP toolkit that spawns and messages child threads (#3) Adds a threads toolkit (spawn_thread, message_thread, read_thread, list_child_threads) next to device, preview and pullRequests. A bridge mirrors each child thread's lifecycle into its parent's activities as the task.* rows the Agents panel already folds, and can send each finished turn back to the parent. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * spike(web): group child threads in a collapsible Subagents sidebar shelf (#3) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * spike(server): report steer for every provider and refuse messages to a starting child (#3) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * spike(web): hide child threads from the sidebar and open them from the Agents panel (#3) Replaces the Subagents shelf: child threads are filtered out of the sidebar, and their Agents panel rows link to the child thread. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(threads): production child threads with Agents panel listing and toolkit guards (#8) Child threads spawned through the threads MCP toolkit are real T3 threads whose sub.<parent>.<suffix> id carries the parent link, hidden from both sidebars and listed with status in the parent's Agents panel. Production hardening over spike/3-threads-toolkit: documented the id-convention tradeoff against a real parentThreadId (contract, projector, persistence migration too invasive for this fork), extracted the steer/new-turn delivery rule, pinned per-driver effort options, and refused messages to still-starting children with a retryable error. Built with OpenCode (Muse Spark). * fix(desktop): run bundle self-check probe under plain Node (#8) verifyPackagedBundleIsSelfContained spread ambient process.env into the probe, so a shell with ELECTRON_RUN_AS_NODE=1 leaked the flag into the validation command and broke the no-Electron-probe invariant the Windows payload test asserts. Scrub the flag like the neighboring fff probe curates its own env. Built with OpenCode (Muse Spark). * fix(tests): make failing gates hermetic without weakening assertions (#8) - desktop: run the bundle self-check probe without ELECTRON_RUN_AS_NODE so validation does not depend on the orchestrator's ambient runtime flag. - server: resolve the entrypoint fixture dir, matching the fully-resolved module URLs Node reports (macOS symlinks TMPDIR through /private/var). Built with OpenCode (Muse Spark). * fix(threads): consume the hot domain-event stream in the threads toolkit (#8) The toolkit handlers layer builds with the HTTP routes. Acquiring subscribeDomainEvents at build time failed every route-layer test whose engine does not implement it (193 server.test.ts cases). Use streamDomainEvents, as the upstream reactors do. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * style: format GLOSSARY.md so vp fmt --check passes (#8) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The sidebar wordmark, setup screen, assistant author heading, link-target and theme labels, splash screen and boot error still said "T3 Code". They now read APP_BASE_NAME, whose browser fallback is "Chromeria", and the T3 glyph renders the Chromeria obelisk icon. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* docs(fork): rebase routine, stack check and fork CI Fork stays a small topic-commit stack on upstream main: docs/fork.md describes the model, scripts/fork-rebase.sh absorbs upstream updates with per-file conflict reports and proof-gated pushes, scripts/fork-check.sh enforces the model, and .github/workflows/fork.yml runs it on every PR. No upstream-owned files are modified. Refs #6 * fix(fork): fork-rebase listing must survive head closing the pipe * test(fork): focused tests for the rebase routine safety rules fork-check.sh and fork-rebase.sh are driven against throwaway git fixtures: new-file pass, unallowlisted-edit fail, allowlist pass, merge-commit fail, missing-doc fail, no-proof push refusal and no-main push refusal. Refs #6 * docs(fork): list maintenance tests and fix formatter whitespace Refs #6 * fix(fork): run proof in a subshell cleared of ELECTRON_RUN_AS_NODE * docs(fork): Chromeria install, squash-plus-absorption model and GitHub-hosted CI Document building, installing and updating the Chromeria desktop app, land absorptions on main with --force-with-lease after proof, allowlist every fork edit of upstream files, remap the PR and main CI workflows from Blacksmith to GitHub-hosted runners, and run the routine's proof in a host-neutral environment. Refs #6. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci(fork): check the PR head, not GitHub's merge ref Refs #6. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(fork): allowlist the #14 web branding edits Refs #6. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): remove unused threads toolkit export * fix(web): provide branding in bundled dev fixture --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
) (#18) * feat(web): Prism spawns, collapsed child tree and parent breadcrumb (#17) The Agents panel now separates threads Model Router (Prism) started for this thread from the thread's own spawns, grouped by job with status and route. Router threads are recognized from the [model-router job ...] tag in their first message, read once per thread and cached. Rows with child threads show a collapsed chevron with the child count that reveals compact nested rows. A child thread's header shows the parent title as a link plus a menu to switch between siblings. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): keep Agents tree internals unexported for knip (#17) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ovider snapshot (#22) * feat(contracts): Prism role kits and provider snapshot schema (#19) Role kits (instructions, runtime mode, skills, thread-tool scope) and ordered model preferences for the six Prism roles, stored as the project-scoped server setting prismRoles, with a per-role patch. Adds the GET /api/prism/snapshot response schema for the router. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(server): Prism MCP toolkit, spawn_thread(role) and provider snapshot endpoint (#19) Adds prism_submit, prism_status, prism_questions and prism_answer, which run the installed Model Router CLI with the calling thread as the T3 planner and a server URL plus an orchestration-scoped token supplied by the server. spawn_thread takes a Prism role, applies its kit and first eligible preferred model, and each role's thread-tool scope is enforced. GET /api/prism/snapshot returns providers, models, usage windows with resetsAt and the role kits resolved for a project. OpenCode usage now refreshes on the provider health interval. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: drop unused Prism exports flagged by knip (#19) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(contracts): Prism model lists per role and lane (#19) Each role keeps an ordered list of {instanceId, model, effort} per lane (easy, medium, hard): the first entry is the primary choice, the rest are fallbacks, and one model at another effort is its own entry. Adds PrismLane (default medium) and per-lane patching. The snapshot carries the same structure through PrismRoleKits. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(server): pick role models by lane in spawn_thread and prism_submit (#19) spawn_thread takes an optional lane (default medium) and walks that role's lane list, primary first then fallbacks. prism_submit takes easy, medium or hard and maps them onto the installed router's small, default and hard lanes. PRISM_LANES stays module-local for knip; PrismLane.literals lists the lanes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* wip: add Prism role preferences and capacity settings (#21) * wip: edit easy medium and hard lanes for every Prism role * wip: derive Prism lanes from the exported schema * wip: serialize Prism saves through the settings snapshot * wip: retain Prism save guard across scope navigation
* feat(fork): map fork features and report upstream overlap * fix(fork): register report entry point and validate feature ids * docs(fork): point edit guidance to the feature map
…ker (#26) (#35) * feat(contracts): single model lists outside Worker, Retry and Escalation switchable (#26) Only the worker keeps easy/medium/hard lists; every other role has one ordered list under models, and a saved per-lane list keeps its medium entry as that list. Retry (correction) and Escalation (recovery) gain enabled. The snapshot still repeats each single list in every lane until toolboxmd/model-router#127 reads single lists. spawn_thread accepts retry and escalation next to the old names. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(web): Prism settings in the Providers layout with autosave (#26) A role list (icon, name, description, toggle) and a detail pane with one ordered model list per role, reorderable by drag or arrows and saved on every change. Only Worker shows easy/medium/hard tabs. Retry and Escalation can be switched off; Dispatcher, Worker and Reviewer show locked on with the reason. Planner is no longer on the page. The Agents panel shows each Prism job as a heading without a status dot. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): show locked Prism roles with a lock and keep model rows on one line (#26) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore(web): drop unused applyPrismRoleUpdate export flagged by knip (#26) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Upstream main is now 113 commits past the fork base, so the `--depth 100` fetch no longer contains the merge base and fork-check.sh exited 1 silently under set -e. Fetch upstream main with full history but no blobs, and print a clear error when the merge base cannot be found. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d status (#25) (#37) * feat(web): show parent threads as working while child threads work (#31) (#33) * feat(web): show parent threads as working while child threads work (#31) Child threads are hidden from the sidebar, so their work never reached the parent row. A shared pure helper derives descendant child-thread activity from thread shells; the sidebar row feeds it through the existing status resolvers (Working pill and timer with "· N agents", child approvals as the parent's approval), and the auto-settle sweep keeps such parents active like threads with live background work. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(fork): record PR for sidebar-child-working (#31) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): surface child input, time from the earliest child (#31) Review fixes: a child waiting on user input now shows the parent's awaiting-input state, and children waiting on input or with any background work (monitoring included) keep the parent from auto-settling. An idle parent's Working timer starts at its earliest working child, and the "· N agents" count sits outside the aria-hidden timer. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(web): browse GitHub Issues next to PRs (#27) (#32) * feat(web): browse GitHub Issues next to PRs (#27) The Pull Requests page gains a PRs/Issues toggle (`view=issues`) and the sidebar an Issues icon. Issues from every GitHub repository of the user's projects are read live through `gh` (one GraphQL search per host page, within the existing GraphQL budget and rate-limit handling), merged across connected environments, and shown as Open, Done or Not planned. Search, sort, repository/label/milestone/parent filters, a parent tree that marks sub-Issues outside the user's projects, and a side panel with body, comments, comment, close and reopen. The command palette searches the listed Issues while the page is open. No storage: upstream tables, migrations and events are unchanged. Upstream edits are allowlisted and mapped under the `issues-browse` feature. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(fork): map the Issues browse PR (#27) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): surface Issues list failures and address review (#27) - Show a failed server or "Load more" page with Retry above the rows that stay, and stop offering "Load more" while it failed. - Toasts for comment and close/reopen carry GitHub's reason. - Locked Issues keep the comment box (GitHub has no viewerCanComment); a note explains and GitHub's refusal is shown. - Count non-GitHub repositories once by host and repository across worktrees, pages and servers. - Palette Issues group follows Actions and appears only once typed. - Remove unused scoreIssueMatch and knip-flagged exports; table tests for issueStateOf and issueSearchQuery; typecheck fix in the live suite. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(server): link GitHub Issues to threads (#28) (#34) * feat(server): link GitHub Issues to threads (#28) Store only non-derivable Issue links in the fork-owned fork_thread_issue_links table (created by the fork, outside upstream migrations and the event log). Derive branch links from conventional <type>/<number>-<slug> branches and closing-reference links from the thread's linked pull requests (real gh) or, for Issues, from the closing pull requests the caller already read. Expose issueLinks.* RPCs (for thread, batched threads for Issues, link, unlink, change push) behind an issueLinks capability, link_issue/unlink_issue/list_thread_issues MCP tools, an Issues section in the "Linked PRs and Issues" panel, and a start-thread-from-Issue action that opens a draft in the matching project, prefills it and links it at once. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): keep retried threads' Issue links and refresh on batched changes - Prune deleted threads' links only once deleted over a week ago: a failed first-send bootstrap deletes a thread and the retry re-creates its id. - Deliver change pushes to the client one batch at a time and match a batch if any change names the thread or Issue. - Render the Issues section only where the server advertises issueLinks. - Enable and rename the command palette entry for the linked surface. - Cover caller-supplied closing references in CI with real rows. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(web): computed Issue status with grouping and filters (#29) (#36) * feat(web): computed Issue status with grouping and filters (#29) Each Issue gets one status from the #25 table, first match wins: GitHub state and close reason, open native blockers, closing pull requests (open, draft) with the trusted `review/independent` mark on their head, task-branch links, and whether a linked thread or any descendant child thread works now. The Issues page read gains blockers, closing pull requests with head SHA and the review mark in the same per-page GraphQL query (cost 2 -> 3 per 100 rows); marks count only when the query's viewer posted them. The view groups by status with Done and Not planned collapsed, adds Status and Linked filters, shows linked threads on rows, wires Start thread on rows and the side panel, and opens the side panel from a thread's linked Issue through the `issue` search parameter. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): count thread-linked PRs, trust marks across servers, drafts pause (#29) Review fixes for PR #36: - A PR into a non-default branch makes no closing reference, so the Issue's PRs are now its closing PRs plus the open PRs linked to its linked threads, deduped by repository and number. Each host's first search page reads those thread-linked PRs as `resource(url:)` aliases in the same GraphQL request (cost stays 3 per 100 rows with 50 aliases; a missing PR answers null instead of failing the page), and `threadsForIssues` returns each thread's PR keys. - Threads are looked up on every server that keeps Issue links, and a review mark is trusted when any server that listed the Issue runs as its poster; the server now returns the mark's creator and its viewer. - An open draft PR with nobody working reads as Paused; merged PRs keep not counting while the Issue is open. - The status table moves to contracts so the live suite checks it too. - The Issues view subscribes to a working-thread key atom instead of all thread shells, and a row's Start thread waits and ignores repeat clicks. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): read only PRs of Issue-linked threads, also without a search (#29) Re-review fixes for PR #36: - Thread-linked pull request candidates now come from threads that link to an Issue (a stored, non-dismissed link or a task branch), through a new `IssueLinks.pullRequestsOfIssueThreads`. Last-synced snapshot state no longer filters them: the same GraphQL read returns GitHub's state. The 50 cap stays as a bound and logs when it truncates. - A server whose repositories a filter excludes still reads its candidates and viewer in a small aliases-only request. - While one row starts a thread, every row's Start button is disabled. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): close Issues integration gaps (#25) (#38) * fix(web): close Issues integration gaps (#25) - Servers advertise an `issues` capability; the Issues list, the sidebar Issues icon, the palette's "Open issues" action and the PRs/Issues switch use only servers that have it, so upstream and older servers no longer answer `issues.list` with an unknown-tag error. - The side panel shows the Issue's linked threads (open one) and its closing and thread-linked pull requests (open on GitHub), read for the one Issue, so it works when opened from a thread's link too. The Issue detail read now carries closing pull requests. - The command palette finds threads by linked Issue: `#N`, `owner/repo#N` or an Issue URL asks `threadsForIssues` on servers with Issue links, debounced and bounded to 20 repositories per server. - Start thread prefers a project on a server that keeps Issue links. - User docs cover linking by hand, unlinking and the MCP tools. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): find closing-reference threads from the palette (#25) Review fixes for PR #38: - The palette's Issue lookup sends the Issue's closing pull requests: from the loaded Issues list entry, else, for `owner/repo#N` or a URL, from one debounced Issue read on a server that lists Issues. A bare `#N` the list does not hold finds stored and branch links only; the user docs say so. - An `issue=` link without a usable `selectedEnvironmentId` resolves to a server that lists Issues, one keeping Issue links first, and never to a server without `issues.*`. - The detail read's mapping moves to `issueDetailOf`, with a CI test decoding a fixture with one closing pull request and one null node. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(web): open PRs from Issues and chat links in the app (#40) The Issue side panel's pull requests opened GitHub, and GitHub `/issues/N` links in chat (including `#N` autolinks, which GitHub numbers together with pull requests) opened GitHub or nothing. Pull request links inside an Issue body updated the PR panel while the Issues view stayed in front. - Issue panel PR rows open through the existing change request opener, with a separate "Open on GitHub" button. - A new on-click resolver reads N as a pull request, then as an Issue, and opens the PR panel, the Issues side panel, or the browser. Nothing is read on render; every failed read falls through to the browser. - The PR opener leaves the Issues view when it navigates the PR page. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): address review of Issue and PR link opening (#40) - On the web, when the click's user activation lapsed during the reads, the browser fallback shows a toast with an "Open on GitHub" action instead of a window.open the popup blocker would swallow. - Leaving the Issues view to open a pull request pushes a history entry, so Back returns to the Issue. - A repeat click while a link is being read joins that read. - The user guide says the fallback follows the "Open links in" setting. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): ask for a fresh click only when the fallback opens a web tab (#40) The "Open on GitHub" toast now appears only when the fallback would open a new browser tab on the web after the click's activation lapsed, not when "Open links in" sends the link to the in-app browser or on desktop. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(web): Issues filters use the PR Filters menu (#42) The Issues toolbar had its own State dropdown, a sort button labelled with the current sort and one long Filters list. It now uses the pull request list's Sort button, Filters trigger and per-filter submenus. Project, Labels and Parent search like the Author filter. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): keep active Issue filters visible and test filter search (#42) Milestone and Parent keep an active value listed after the loaded rows stop carrying it. The Filters count includes State like PR mode, and Clear filters resets State too. The searched submenu option logic moves into a pure helper with unit tests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
) * fix(web): PR panel no longer shows "All fibers interrupted" on open (#52) Opening a pull request starts its detail read twice within a few ms. The server lets the second read join the first read's shared lookup while the first read's cancellation is tearing it down, and answers it with an interrupt. The client query atom stored that as a failure, so the panel showed "All fibers interrupted without error" until Retry. An atom never observes its own cancellation, so an interrupt-only failure in an environment query is the server's. The query now reads once more instead of surfacing it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(fork): link the query-interrupt-retry feature to PR #54 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tart (#48) (#49) * fix(server): child threads keep reporting to their parent after a restart (#48) The threads toolkit bridge kept each child's reportBack flag and the last reported message only in memory, so after a server restart no child turn was reported back to its parent. Write both into the parent's task.* rows and restore them from there the first time a child's session changes after a restart. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): restore child report state without trusting the activity window (#48) Review of #49: the parent's thread detail holds only its newest 500 activities, so a child's task.started row and last reportedMessageId row can fall out of it. Every idle task.progress row now carries reportBack and the latest reportedMessageId, and restore reads the newest row. A child with no surviving row treats its current last reply as already reported. One parent read restores all of that parent's children. The restart test now covers a reportBack:false child. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Harnesses that defer tool schemas show agents only tool names, and Grok not even those, so planners missed prism_submit and spawn_thread and opened terminal sessions instead. Every harness's launch prompt now carries a short t3-code tool guide: prism_submit for an authorized job that ends in one PR, spawn_thread for small work or a named model and effort, plus the browser, device and Issue tools. The text lives in apps/server/src/mcp/toolInstructions.ts. The launch prompt stays its home: MCP server instructions would reach Claude Code, Codex, OpenCode and Grok, but a live ACP run showed Cursor does not show them to the model, and Antigravity only writes them to a file. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
fork-check.sh failed any PR once the fork stack exceeded 20 commits, an arbitrary limit from PR #9 with no evidence behind it. Main is already at 20 commits, so every fork PR fails the check now. Rebase cost comes from upstream-file edits, which the allowlist and feature map already enforce; the count adds nothing. Drop the --max-commits option and the failure branch, keep the informational "stack: N commit(s)" line and commit list, and update docs/fork.md accordingly. No test asserted the cap. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…el (#56) * feat(server): Prism stream clock for worker liveness, plus prism_cancel Model Router measured worker silence from ~100-char message segments with a fixed window, so a dead turn went unnoticed for minutes and a slow but healthy model risked being killed. Prism also had no way to cancel a job. Every provider event already passes through the shared native and canonical event loggers, including each token, reasoning and tool output delta and Claude thinking_tokens. A new in-memory StreamClock wraps those loggers and stamps each thread's lastStreamAt, tracks open tool calls, and at each turn end records one hidden prism.stream-stats activity with time to first token, max gap while no tool was open, event count, provider, model and outcome. GET /api/prism/liveness?threadId= returns it with the server's now. prism_cancel checks the job belongs to the calling thread, then runs the Router CLI cancel and recover with a Prism token and returns the final state. Closes #55 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(fork): map the Prism stream clock feature to its PR (#55) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): build the tapped event loggers on the upstream layer; drop unused exports (#55) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(server): child threads no longer flood the mobile thread list (#59) The store mobile app has no Agents panel, so every child thread spawned through spawn_thread or Prism showed up in its thread list and buried the threads the user started. The server now leaves child threads (sub.<parent>.<suffix>) out of the shell it sends to mobile connections: the WebSocket shell snapshot, replayed and live shell events, the archived shell snapshot, and the HTTP shell snapshot, which looks up the surface the session last connected with. Web and desktop still get child threads for the Agents panel. No mobile build is needed; a phone drops cached children on its next connection because new sessions reload the HTTP snapshot. Until upstream Orchestrator V2 ships, child threads cannot be opened on mobile; they stay reachable from web and desktop. Done by Claude Opus 5.5 in Claude Code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(fork): link #60 to the child-threads feature Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…63) * feat(server): threads resume on their own after a usage limit resets (#61) When a provider's usage limit stopped a thread, nothing brought it back: the user had to return after the reset and type "continue". Three threads stopped this way on 2026-09-28 alone. When a thread the user started fails while its provider instance has an exhausted usage window with a known reset (the data the Usage panel shows), the threads toolkit sends one "Continue. (Sent automatically after the usage limit reset.)" a minute after the latest reset. Starting another turn or archiving the thread first cancels it. Child threads are skipped: Model Router reroutes or blocks Prism jobs itself, and the planner decides what to do with a blocked job once it resumes. Pending resumes live in memory, so a server restart drops them. Upstream Orchestrator V2 has its own "Resume at reset", so this goes away with the V2 port. Done by Claude Opus 5.5 in Claude Code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(fork): link #63 to the child-threads feature Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): keep the usage-limit settle delay private Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): keep mobile shell helpers private (#60 follow-up) Knip flagged three exports only used inside mobileShell.ts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(server): detect stale turns from measured stream gaps * feat(server): monitor stale children and notify their parent once * test(server): encode saved stream samples through the schema * fix(server): keep notifyStaleParent module-private (#62) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…LIs they replace (#67) * feat(server): delegation tools are always loaded and name the shell CLIs they replace (#66) spawn_thread, read_thread, message_thread and prism_submit carry _meta["anthropic/alwaysLoad"], so Claude Code shows their descriptions from the first turn instead of deferring them behind tool search. The spawn_thread and prism_submit descriptions and the launch paragraph now say when to use them and name codex exec, claude -p, opencode run and grok in the shell as what they replace. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): spawn_thread description says a role applies its kit (#66) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ir GitHub state (#70) * fix: prism_submit names its workspace default; linked Issues show their GitHub state - prism_submit's description says workspace defaults to this thread's current directory and must be set for another repository or worktree (#68). AGENTS.md notes running vp as `pnpm exec vp` where it is not on PATH. - The Linked PRs and Issues panel read no state for Issues and drew every row with the open icon; the footer counted only pull requests. The panel now reads each linked Issue's current state, rereads it on each pull request sync, draws GitHub's state glyph, and counts open Issues in the footer (#69). Closes #68 Closes #69 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: linked Issues read state alone, refresh on an interval, show unknown Review of d6434a1 (Luna): - Failed or missing reads are their own `unknown` state: shown with a question glyph and not counted open. Before the first read a row is `pending` and is not counted either. - The panel's states query refreshes every 60s while shown, besides mount and each pull request sync. - New `issues.states` RPC reads only `state stateReason` for all linked Issues in one aliased GraphQL request per host, instead of one full `issues.detail` read (body, comments, closing references) per Issue. Tests: IssueService.states with a fake gh (request shape, null for a missing Issue, failure on a gh error, no request for no Issues); the query runtime rereading on its refresh interval; the panel's state transitions pending -> open -> done, and failed or missing -> unknown. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: read every linked Issue's state in chunks of 50; render-test the panel Re-review of 4435f31 (Luna): - The panel no longer slices linked Issues to 50. It reads them in chunks of at most ISSUE_STATES_MAX, one states query per chunk, and a failed chunk leaves only its own Issues unknown. - ThreadLinksPanel.test.tsx renders the panel for pending, failed, missing, open, done and not-planned states and checks each row's icon and the footer's open and linked counts, including an Issue closed after linking. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…Chromeria (#77) The sidebar sized the square Chromeria icon at 1cap (about 10px), a height meant for the old wide T3 wordmark. It is now 20px and centered with the name; the welcome screen mark gets the same fix. t3.json points the project icon at the Chromeria mark instead of the T3 blueprint. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s Mac (#78) * docs: AGENTS.md lets agents stage the merged build on the maintainer's Mac Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(ci): allowlist fork edits to AGENTS.md and the PR panel; drop an unused export Main's Fork Stack Model and knip checks failed after #70 and #76. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…a fix (#86) (#87) The launch paragraph and prism_status now say: have a reviewer child thread confirm a Prism defect from prism_status and the durable-runner outputs, then open or update the model-router Issue with that confirmation, then start a worker child on the fix in its own worktree, while the job keeps going. Unconfirmed suspicions become a comment on an existing Issue or are dropped. Tests pin the steps and their order. Closes #86 Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…untimeMode (#89) * fix(server): spawn_thread no longer lets agents set runtimeMode An agent set approval-required on a background child on its own, so every approval went to the user and the child sat blocked while the parent reported it running. The child's mode now comes only from the role kit, else the parent thread. A runtimeMode passed anyway is dropped. Closes #88 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): children start in full access; drop the role-kit runtimeMode A child's approvals go to the user, never to the planner, and the planner cannot see or answer them, so any restricted mode stalls a child unseen. Copying the parent's mode was also wrong: a read-only dispatcher would make its implementers read-only. Children now always start in T3's default full-access mode, and the unused role-kit runtimeMode is removed. Saved settings that still carry it load and drop the key. Refs #88 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Upstream: pingdotgg/t3code#13970 by @asonawalla, plus fork-map registration and a khroma@2.1.0 MIT license override. Co-authored-by: Azim Sonawalla <azim.sonawalla@gmail.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Mission: Prism chooses model, harness and effort per delegated role and runs every agent as a visible T3 thread. Objective: dispatcher on spawn_thread, one set of role names with every thread tool, runner retired. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ames (#93) (#101) * feat(server): every Prism role has every thread tool; roles use six names (#93) Delete the per-role thread-tool levels (threadToolRefusal, the default scope table and the threadTools kit field) so any thread in any role may call spawn_thread, message_thread, read_thread, list_child_threads and list_threads. Rename the internal role keys correction/recovery to retry/escalation. Settings saved with the old keys or a threadTools field still load, and child ids spawned as correction-/recovery- read as the new roles. The runner's snapshot route keeps its legacy keys until it retires. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: record #101 in the Prism feature entry Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
) * feat(server): interrupt_thread stops a thread's running turn (#95) New thread tool: interrupt_thread(threadId, scope) dispatches thread.turn.interrupt for a running or starting thread and returns once T3 reports the session settled (interrupted), or interrupt_requested if it has not settled within 30 seconds. An idle, failed or stopped thread returns no_active_run without a command. Result statuses mirror upstream orchestration V2's t3_thread_interrupt so callers port unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: record #102 in the child threads feature entry Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): a stale interrupt never stops a newer turn (#95) The provider reactor now drops thread.turn-interrupt-requested when it names a turn that is no longer the session's active turn, so an interrupt sampled for turn A cannot stop turn B that started before the request was handled. interrupt_thread treats the sampled turn ending as settled, even when a newer turn is already running. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): interrupt_thread never sends an unscoped interrupt (#95) A starting thread has no active turn id yet, and an interrupt without one could stop a newer turn that becomes active before the reactor handles it. interrupt_thread now waits up to 30 seconds for the thread to report its turn id and interrupts that turn only; if the thread stops being active or reports none in time, it returns no_active_run and sends nothing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tart (#94) (#103) * fix(server): report-back reaches the parent exactly once across a restart (#94) Restore every child's report state from all parent task rows, read by kind, instead of the parent's newest-500 activity window, so a child keeps its reportBack setting however many parent activities followed. Send each report with a command id derived from the reply, so the engine's command receipts drop a resend, and send it before writing the idle row. On start, report idle children whose latest turn completed after their last recorded idle row, which no bridge saw while the previous process stopped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: record #103 in the child threads feature entry Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): no idle transition is lost while report-back catches up (#94) The bridge now subscribes to domain events before its restart catch-up and drains the buffer afterwards, so an idle transition that lands during the catch-up is handled by the bridge instead of falling between the two. The catch-up reads only children whose newest parent row is not idle and writes their idle row, replacing the shell-snapshot scan (which also added a shell snapshot read that server.test.ts counts). Duplicates are dropped by lastReported and the report's command receipt. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(server): route delegated work through spawn_thread roles (#96) The tool-instruction block now tells every coordinating thread to delegate with spawn_thread roles, start a dispatcher for one-PR jobs, and recover a failed child with interrupt_thread, retry, then escalation. prism_submit stays only as the fallback until #97 removes it. spawn_thread and interrupt_thread descriptions carry the mechanics; a test pins that Prism role kits ship no default instructions. Refs #96 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): replace a child only after its interrupt settles (#96) Review on #104: interrupt_requested can leave the child running, so the replacement waits for a settled report; spawn_thread notes reportBack: false. Refs #96 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…limit (#72) * feat(server): direct child threads resume on their own after a usage limit (#71) A spawn_thread child that stopped on a usage limit waited until the user typed "continue" to the planner and the planner relayed it: #63 skipped every sub.* thread to leave Prism jobs to Model Router. The resume watcher now skips only Prism job threads, recognized by Model Router's "[model-router job ...]" first user message (titles get regenerated, so they are no marker). A resume fires at the earlier of the displayed reset plus a minute, or the first reply any thread gets from the same provider instance after the settle delay: on 2026-09-29 the displayed reset was 2.5 hours later than when requests worked again. A thread whose early resume fails again waits for the reset, so a per-model limit cannot turn replies elsewhere into a retry loop. A resumed child's parent gets one line saying so. Done by Claude Opus 5.5 in Claude Code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): interrupt_thread cancels a usage-limit auto-continue (#71) A dispatcher interrupts a limit-hit child before replacing it, but that child is already failed, so interrupt_thread had nothing to stop while the pending automatic continue would still restart it next to its replacement. interrupt_thread now cancels that pending continue and marks the stopped turn so a later limit error for it schedules none. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): continue only usage-limit errors, and past resets keep watching (#71) Only a turn whose own error reads as a usage limit schedules a continue; an unrelated runtime error while a usage window is exhausted is left alone. An exhausted window whose reset time already passed no longer ends the watch: it keeps waiting for a reply on the instance and re-reads the windows every 5 minutes, resuming at a future reset or once none is exhausted, so a stale reading cannot turn into a continue loop. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): resume at a reset only once the window shows it lifted (#71) At a future reset plus the margin the watcher resumed without reading the usage windows again, so a window still at 100 % got a continue anyway. It now re-reads them and resumes only when none is exhausted; otherwise it keeps re-reading every 5 minutes, and a reply on the instance can still resume it early. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The Python runner is retired, so its Chromeria hooks go: the five prism_* MCP tools, GET /api/prism/snapshot and /api/prism/liveness with their contracts, the stale monitor's title exception, the usage-limit resume's job-thread exception, the prism_submit fallback and router-defect guidance in the tool instructions, and the Agents panel's Prism spawns section. Stall detection, parent notification, per-turn stream statistics, Prism roles and Settings stay. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* docs: glossary names the Promachos, Satrapies and Libraries; Prism is the router Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: glossary adds Wight mode Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: glossary adds Color and Spectrum Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: a Spectrum holds Drafters of several Colors Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(web): open thread issue links in the right panel * fix(web): linked Issue buttons name the right panel Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): keep the Issues page opener module-local Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(server): spawn threads into another project * fix(server): keep spawn tool description short
* feat(prism): select the initial Promachos conversation model * style(web): wrap Prism page roles array for the formatter Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(server): drop the absolute epoch from Promachos RPC selection cases The shared TestClock advances in earlier cases, so the Promachos RPC cases saw 1970-01-03 instead of the epoch. The case still checks that the created thread and the turn share one timestamp and the selected model. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(server): retire stopped thread subtrees durably * fix(web): stopped child threads show as stopped in the Agents panel A retired thread's session is interrupted but its last turn can stay running or error, so the panel showed it as running or failed. A live or interrupted session now outranks the last turn; a restarted session still shows running. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): keep retirement turn classifier private --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(web): Promachos mode chats with the home's conversations in bubbles (#116) A switch in the sidebar header moves web and desktop between the standard view and Promachos mode. Promachos mode lists the conversations of the Promachos home (one project on one environment, chosen per client) and starts new ones there through one function, useStartPromachosConversation, which #115 later points at the Promachos's Prism role. Home threads render as a chat: the user's messages as outbound bubbles, replies as one bubble per top-level Markdown block within a single parse, so code, lists and tables stay whole and reference links resolve. Tool activity, reasoning and turn folds collapse into a static working bubble. The composer's own question and approval cards render inline in the chat through a portal, keeping their handlers and state. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): the Promachos mode switch gets its own sidebar row (#116) At the default sidebar width the switch beside the brand overflowed the titlebar into the main header. It now sits on a full-width row under the titlebar, with text labels only, so it fits at the minimum width beside any window-controls inset. The titlebar itself is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: record Promachos mode PR in the fork feature map (#116) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): Promachos cards stay with the thread whose timeline shows them (#116) During a thread switch the timeline can keep painting the previous thread while the composer already belongs to the next one, so that composer's question and approval cards rendered into the previous conversation. The inline card host now records the thread whose timeline rendered it, and the composer only uses a host its own thread owns; otherwise the cards stay attached to the composer. Also drops the unused isPromachosHome export that knip reported. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(web): new Promachos conversations start on his Prism role (#116, #115) A first send that creates a top-level thread in the Promachos home, in Promachos mode, now carries prismRole "promachos" on thread.turn.start when the home's Promachos model list has entries. The server picks the model and replaces the composer's selection, which stays as a valid placeholder. With an empty list the conversation starts normally. A Prism refusal is the send's own failure and shows in the chat; it is never retried as a normal start. The seam is withPromachosStart, one wrapper on the existing send. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): no multiple-model start where Prism picks the Promachos model (#116, #115) The multiple-model start creates top-level threads straight through startThreadTurn, so in a Promachos chat with a configured list it bypassed the Prism start. The composer now offers no multiple-model start there and sends no stale fan-out selection, so every new conversation goes through withPromachosStart. With an empty list nothing changes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(web): a hidden multiple-model selection no longer locks Promachos workspace controls (#116) Where Prism picks the Promachos model, ChatView now acts on one effective multiple-model selection, none, for the composer, the workspace mode switch and the branch toolbar's forced new worktree. The saved selection stays in its atom, so it returns when the view goes back to Code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(server): continue idle threads in Wight mode * docs: register Wight mode fork ownership * fix(server): recheck Wight eligibility at turn admission * fix(server): guard legacy resumes and share turn sender * docs: keep shared orchestration ledger ownership singular * fix(server): keep Wight continuations behind retirement guards
* feat(spectrum): add council and free discussions * fix(server): preserve Spectrum recovery on supported Node
* feat(server): record thread ownership and sharing Co-Authored-By: GPT-6.1-Sol <noreply@openai.com> * fix(server): carry thread sharing through detail streams Co-Authored-By: GPT-6.1-Sol <noreply@openai.com> * feat(web): person picker and thread sharing Devices are labelled with a person in Settings -> Connections. The standard and Promachos sidebars get a Luke / Pauli / Shared / All picker that filters threads by owner and co-owners; unsent drafts count as the device's person. Shared threads carry a Shared label in the sidebar and the thread header, where the owner can share or unshare and a co-owner can leave. Sharing activity renders as its own timeline row, and thread.sharing-set events update thread detail state live. A device refetches its own label when its window regains focus. Refs #121 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): stamp people on HTTP dispatch Co-Authored-By: GPT-6.1-Sol <noreply@openai.com> * fix(server): Spectrum threads inherit the caller's owner Co-Authored-By: GPT-6.1-Sol <noreply@openai.com> * docs: link the people feature to its PR Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): create people columns at runtime, not as migration 55 Co-Authored-By: GPT-6.1-Sol <noreply@openai.com> --------- Co-authored-by: GPT-6.1-Sol <noreply@openai.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(server): add check-gated scheduled tasks * feat(web): manage scheduled tasks in Settings Settings → Scheduled tasks lists each task's health (last run, pinned check version and verdict, failure streak, last error, chosen minute and neighbours) and manages tasks: create with a required check and reason, edit, pause and resume, run now, delete, and revert check versions with a reason. A finished turn with a failing check is shown as continuing, never as done. Adds a user guide. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(server): deliver scheduled Spectrum reports once * chore: register scheduler projector as shared with people * fix(server): preserve scheduled run ownership and recovery * fix(web): scheduled tasks follow the selected environment and needs-you rules The Scheduled tasks page now requires one selected environment and asks for one otherwise, instead of listing a stand-in environment's tasks. Search uses the environment scope. Only a verified run counts as settled: on a task that needs you, Run now resumes the same run and Delete is left to the server's quiescence check, while work in progress blocks both. Guide updated. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: link scheduler delivery pull request * fix(server): register scheduler tools and preserve run verdicts * test(server): provide scheduler subscriptions in route fixtures * fix(server): keep scheduler idle helper private * chore(web): keep scheduled task helpers private to their module Knip reported five exports used only inside ScheduledTasksSettings.logic.ts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Server-origin turn commands omitted modelSelection, so the provider reactor sent turns without it and Codex fell back to medium reasoning effort. The shared fork turn sender (threads toolkit, Wight, usage-limit resume, scheduler), the Spectrum turn builder (Colors, moderator, caller report) and the Prism stale-child notice now carry the target thread's stored modelSelection. Closes #133 Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Git appends the partial-clone filter to fetch lines in `git remote -v` (`origin <url> (fetch) [blob:none]`). The three remote-line parsers were anchored after `(fetch)`/`(push)`, so partial clones lost repository identity, listRemotes dropped the remote, and ensureRemote added a duplicate. Accept an optional trailing bracketed filter in all three. Closes #135 Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…quest (#137) Restart recovery read a Drafter's latest request and then dispatched a plain session stop, so a genuine successor request landing in between was stopped. The stop now names the request it may end by its event sequence. The engine refuses it, inside the serialized decide step, when the Drafter has a newer request, and always refuses the legacy unnamed form. A refused stop is never persisted, so neither the reactor nor any client projects it as stopped. Spectrum's outbox moves on only when that refusal is a superseded stop, live or replayed. Accepted stops precede every later request, which the reactor handles only after the physical stop finishes. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What: The Objective no longer excludes mobile builds.
Why: The user confirmed on 2026-10-02 that mobile builds are now in scope, so fork features like compact agent-message rows (#142) can reach their phone.
So what: Merging needs the user's approval; mobile follow-ups can then proceed without a direction detour.
Elon record
🤖 Generated with Claude Code