codemode rip, part 3: delete the domain#1447
Conversation
Bugbot findings: (#1446 High) the agent loop shipped without the slack cap, breaking Slack bang commands and LLM replies at this point in the stack — the slack (full guidance text, including the quiet-reply rule and the Promise.all acknowledgment pattern, addressing the #1447 Medium) and agents caps move down from part 3 to where the loop lands, with the SlackCapability call() adapter and allowlist entries. (#1447 High at its source) ensureItxContext seeding is now versioned: bump AGENT_CONTEXT_CAPS_VERSION and existing agents re-define caps on next wake (defines upsert; capability-noted idempotency keys dedupe). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
e173b4f to
bdda255
Compare
71f4f41 to
14b7083
Compare
|
Both Bugbot findings addressed by moving the fixes down into #1446 where they belong (commit bdda255 there; this branch rebased on top in 14b7083): versioned re-seeding covers agents whose child context predates a deploy, and the seeded slack instructions carry the full quiet-reply + acknowledgment guidance from the deleted default provider. |
Bugbot findings: (#1446 High) the agent loop shipped without the slack cap, breaking Slack bang commands and LLM replies at this point in the stack — the slack (full guidance text, including the quiet-reply rule and the Promise.all acknowledgment pattern, addressing the #1447 Medium) and agents caps move down from part 3 to where the loop lands, with the SlackCapability call() adapter and allowlist entries. (#1447 High at its source) ensureItxContext seeding is now versioned: bump AGENT_CONTEXT_CAPS_VERSION and existing agents re-define caps on next wake (defines upsert; capability-noted idempotency keys dedupe). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bdda255 to
68e6d30
Compare
14b7083 to
8673d28
Compare
Bugbot findings: (#1446 High) the agent loop shipped without the slack cap, breaking Slack bang commands and LLM replies at this point in the stack — the slack (full guidance text, including the quiet-reply rule and the Promise.all acknowledgment pattern, addressing the #1447 Medium) and agents caps move down from part 3 to where the loop lands, with the SlackCapability call() adapter and allowlist entries. (#1447 High at its source) ensureItxContext seeding is now versioned: bump AGENT_CONTEXT_CAPS_VERSION and existing agents re-define caps on next wake (defines upsert; capability-noted idempotency keys dedupe). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
68d00ca to
7b6c9e2
Compare
dc0559b to
1a34568
Compare
domains/codemode is gone — 8.3k lines deleted. What remains and where it
went:
- CodemodeSession DO → a tombstone class (src/durable-objects/
codemode-session-tombstone.ts). The class and CODEMODE_SESSION binding
MUST keep existing: production streams carry durable callable
subscribers that dial it by name (see the 2026-06-10 legacy-subscriber
incident). The tombstone accepts those dials and no-ops; removing the
namespace properly is a follow-up with a DO deletion migration +
subscriber cleanup.
- AiCapability/OrpcCapability → src/rpc-targets/os-capabilities.ts.
- ExecuteCodemodeFunctionCallInput → src/rpc-targets/
legacy-codemode-call.ts; entrypoints keep the legacy method while
callers migrate to call({ path, args }) (Slack gains a real call()).
- Agent caps grow slack + agents (SlackCapability path-call,
AgentCapability members) — the full pre-itx provider surface.
- ctx.workspace: child contexts get per-context workspaces
(itx:<contextId>, derived identically in handle.ts and the agent's
workspace prep) — agents re-clone iterate-config once into the new id.
- slack-integration bootstrap stops subscribing codemode to routed
streams.
- oRPC: project.codemode contract + router + UI queries deleted;
agents/new.tsx loses the tool-provider compiler (the Agent DO seeds
caps on wake); codemode-sessions routes + session controls deleted.
- e2e: codemode suites + e2e-test-map (codemode-builder-based) deleted —
the itx suite covers the replacement model; agents.e2e converted to
itx events (per-call event asserts dropped with the mechanism; the
event-mediated deadlock + ordering tests died with the machinery).
typecheck (repo) / lint / format / unit (205) green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…demode rip Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1a34568 to
9dd5fb6
Compare
…txError test fix
- Single-flight ensureItxContext in the Agent DO and MCP connection
(Bugbot High: wake-time workspace prep vs script runs could mint two
context ids; concurrent exec_js likewise).
- MCP session seeding gains MCP_CONTEXT_CAPS_VERSION (same re-seed-on-
version-bump semantics the agent already had).
- runItxScript gains convention: "ctx" — agent/LLM scripts (async (ctx)
=> …) are invoked directly, killing the async ({ itx, vars }) wrapper
so the execution record carries exactly what the model wrote. vars is
an "itx"-convention concern only.
- ItxError e2e test corrected: capnweb 0.8.0 reconstructs unknown error
names as plain Error and DROPS the name (ERROR_TYPES[name] || Error;
props loop skips "name"), so name identity is untransmittable — the
test (which merged in #1456 with its e2e check skipped, so it never
ran) now asserts the duck-typed code/details contract; errors.ts doc
corrected to match reality.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Review round addressed in 24365a0: Parallel itx context initialization (High) — single-flight Also in this commit: the failing |
- runItxScript knows exactly one calling shape, script(itx). The convention option and vars are gone from the runner; parameterization is the caller's concern (/api/itx/run keeps its vars API by baking vars into the source before submitting — client-helper-side wrapping). - Agent scripts run verbatim; extractCodemodeScript accepts the legacy async (ctx) prefix from old histories (the parameter name is the author's business — the single argument is the handle either way). - Vocabulary sweep: system prompt, capability instructions and notes, bang-command codegen, MCP exec_js docs (which still taught the destructured shape — a real bug with the one-shape runner), tests, e2e expectations, ItxFn in types.ts/handle.ts, README glossary, and the workspace preview example (renamed) all speak itx. - iterate-mcp-server DO test: assertions moved to itx/execution-*; the provider-matrix test died with the machinery it exercised. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts: # apps/os/e2e/vitest/codemode-mcp-provider-stack.e2e.test.ts # apps/os/src/domains/codemode/example-provider-registrations.ts # apps/os/src/domains/codemode/examples.ts # apps/os/src/durable-objects/codemode-session.test.ts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e59ceec. Configure here.
|
|
||
| #ensureItxContextPromise: Promise<string> | undefined; | ||
|
|
||
| async #ensureItxContextOnce(params: AgentDurableObjectStructuredName): Promise<string> { |
There was a problem hiding this comment.
Stale capability notes after reseed
Medium Severity
When AGENT_CONTEXT_CAPS_VERSION changes, #ensureItxContextOnce re-runs itxDefine with updated cap instructions but appends agent/capability-noted events using the same agent-capability-noted:${cap.name} idempotency keys as the initial seed. The stream likely dedupes those appends, so the agent processor never re-renders tool guidance while runtime caps already changed—models can follow outdated itx.slack (and other) instructions after deploy.
Reviewed by Cursor Bugbot for commit e59ceec. Configure here.
Final follow-up to the codemode rip (#1445/#1446/#1447). MCP's streamable HTTP transport is a stateless protocol — fetch with metadata — so nothing about an MCP client belongs in a Durable Object. ## What - **`OutboundMcpFromOurClientCapability` DO deleted** — class, worker export, alchemy namespace + `OUTBOUND_MCP_FROM_OUR_CLIENT_CAPABILITY` binding, vitest harness wiring. Nothing has dialed it since the codemode rip (its only caller was the deleted provider registration). - **Core helpers promoted** to `src/itx/caps/mcp-client-core.ts` with clean names: `connectMcp` (custom-fetch aware, closes on failed connect), `listMcpTools`, `executeMcpToolCall`. `McpClient` dedupes onto them; the mock-server unit test moved and adapted. - **The DO allusion is gone from the docs**: `McpClient`'s header now states statelessness as the design ("connect → call → close, per invocation; deliberately no Durable Object anywhere in this path") instead of presenting connection caching as a future optimization. ## Deploy note This is the repo's first Durable Object class deletion. The DO had no SQLite (in-memory cache only) and no inbound subscribers, so deletion is data-safe; alchemy is expected to emit the `deleted_classes` migration on deploy — **this PR's preview deploy is the proof**. If it refuses, the fallback is a tombstone class like `CodemodeSession`'s. ## Testing Repo typecheck / lint / knip / unit suite green locally (incl. the moved mock-server core test). The `McpClient` e2e remains gated on a reachable MCP server. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CLOUDFLARE_PREVIEW --> ## Environment Config Lease <!-- CLOUDFLARE_PREVIEW_STATE --> <!-- { "apps": {}, "environmentConfigLease": { "dopplerConfig": "preview_4", "leasedUntil": 1781109925654, "leaseId": "f7427e44-72e2-4e04-8617-122e174b3c57", "slug": "preview-4", "type": "environment-config-lease" } } --> <!-- /CLOUDFLARE_PREVIEW_STATE --> Lease: `preview-4` Doppler config: `preview_4` Type: `environment-config-lease` Leased until: 2026-06-10T16:45:25.654Z <!-- /CLOUDFLARE_PREVIEW --> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… it in transit (#1462) Narrowed after #1447 landed: that PR fixed the e2e test's assertions (asserting the real wire shape, `name === "Error"` + raw `code`), which unblocks preview e2e on main. What it did NOT fix is the detection helper itself — `getItxErrorCode` still requires `error.name === "ItxError"`, and capnweb 0.8.0 drops custom error names in transit (the receiver maps only builtin names to classes; the props loop skips `name` on both ends). So after any capnweb hop, every runtime consumer of the helper — react hooks, `stream-tail`, `isItxAccessError` retry predicates — fails to recognize kernel errors and treats NOT_FOUND/FORBIDDEN like connection noise. Probed against a live preview deployment: ``` name: Error ← dropped by capnweb code: NOT_FOUND ← survives (own enumerable prop) details: {"projectIdOrSlug":"definitely-not-a-project"} ← survives ``` ## Fix `getItxErrorCode` duck-types on the closed five-code set alone; `name` is not consulted (it cannot be, after capnweb). Set membership keeps foreign coded errors (`ECONNREFUSED`, …) out. The unit-test `simulateCapnwebCrossing` helper no longer reattaches `name` by hand — that hand-modeled reattachment is exactly how the original bug stayed green in unit tests while failing on the real wire. Docs in `errors.ts` updated to match (merged with #1447's wording). ## Verification - The capnweb-crossed shape (plain `Error` + `code`) is now detected; unit tests assert it - `pnpm test:itx-stream-subscribe` (real Workers RPC boundary, which legitimately preserves `name`) still passes - Full apps/os suite, typecheck, lint clean; e2e verified earlier against a live preview deployment (preview_6) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes shared error-classification used for retry vs access-failure handling across capnweb clients; behavior widens slightly (code-only shapes now match) but is constrained by the five-code allowlist. > > **Overview** > **`getItxErrorCode` no longer requires `error.name === "ItxError"`** — it treats any object whose `code` is one of the five itx codes as an ItxError. That matches errors after a capnweb RPC crossing, where the receiver rebuilds a plain `Error` and **drops** the name while `code` / `details` still arrive as own props. > > Docs on `getItxErrorCode` in `errors.ts` now spell out why `name` must not be used and how the closed code set avoids colliding with other `code`-bearing errors (e.g. `ECONNREFUSED`). > > Unit tests were aligned with real capnweb: `simulateCapnwebCrossing` no longer re-attaches `name`, duck-typed cases use plain `Error` + `code` only, and rejection cases use foreign codes instead of wrong `name`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5c3e6d3. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Conflict resolutions: - packages/iterate/src/cli.ts: took this branch's version wholesale. Main's only change was the superadmin->admin rename (#1453), and every renamed region (auth strategies, impersonation dance, device flow, --superadmin login flag) was already deleted here in the OAuth PKCE rewrite — there is nothing to port. - apps/os/e2e/vitest/e2e-test-map.e2e.test.ts: accepted main's deletion (codemode rip #1447); this branch had only touched a doc comment. - event-stream-terminal.tsx (auto-merged, needed follow-up): main's new listChildren itx walk gets the authedFetch arg, matching the getState adaptation from the previous merge. - apps/iterate-com skills-registry.ts: took main's regenerated copy; this branch carried a stale-formatted version of the generated file. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>


Stacked on #1446. The codemode domain is deleted — net -8.3k lines.
What went where
CodemodeSessionDO → tombstone. The class +CODEMODE_SESSIONbinding deliberately keep existing: production streams carry durable callable subscribers that dial the namespace by name, and a vanished class is exactly the 2026-06-10 legacy-subscriber outage. The tombstone acceptsrequestStreamSubscriptiondials and no-ops (with a warning log). Proper removal = follow-up with a DO deletion migration + stream subscriber cleanup, after this soaks.AiCapability/OrpcCapability→src/rpc-targets/os-capabilities.ts(they're itx caps now, not codemode examples).ExecuteCodemodeFunctionCallInput→src/rpc-targets/legacy-codemode-call.ts; capability entrypoints keep the legacy method while callers migrate tocall({ path, args }).SlackCapabilitygains a realcall().slack+agentscaps (SlackCapability path-call with the old etiquette instructions, AgentCapability members for pipelined subagents) — restoring the full pre-itx provider surface.ctx.workspaceon a child context now maps to workspaceitx:<contextId>(derived identically inhandle.tsand the agent's workspace prep). Existing agents re-clone iterate-config once into the new workspace id.project.codemodecontract + router, codemode-sessions routes, session controls, and the new-agent tool-provider compiler are deleted — the Agent DO seeds caps (and the LLM-visible capability notes) on wake, so the form stops compiling registration events.Test changes
codemode-builder, ande2e-test-map.e2e.test.ts(built entirely on the codemode fixture; the itx e2e suite covers the replacement model).agents.e2econverted to itx events. Coverage honestly lost with the per-call event mechanism: function-call-level assertions (workspace op sequence, slack-call payload echo, debug-output sanitization) — those now verify via generated code + execution-completedok+ the real side effects.Follow-ups (noted in itx-next.md territory)
executeCodemodeFunctionCalllegacy methods on capability entrypoints → delete once nothing dials them.packages/shared/src/codemode/*(json-schema type generation) still used by OrpcCapability's listProcedures — rename/move later.🤖 Generated with Claude Code
Note
High Risk
Large removal of script execution, providers, and oRPC routes touches agent/Slack flows and production stream subscribers; behavior changes until tombstone subscribers are cleaned up.
Overview
Removes the codemode domain (~8k lines): the
CodemodeSessionDO implementation, stream processor, default/example providers, UI session controls, and the entireproject.codemodeoRPC surface (sessions,executeScript,streamEvents,describe).CodemodeSessionbecomes a tombstone — same class/binding so existing stream callable subscribers keep dialing without outage;requestStreamSubscriptionno-ops with a warning until subscriber cleanup lands.Agents run on itx instead of codemode events: script runs use
runItxScriptwithconvention: "ctx"and direct LLM code; workspaces areitx:<contextId>(aligned with the itx handle), with single-flightensureItxContext. Capability types move torpc-targets/legacy-codemode-callandos-capabilities; tests/assertions shift fromcodemode/*and per-call function events toitx/execution-*andagent/capability-noted.E2E: codemode suites,
CodemodeBuilder, ande2e-test-mapare deleted;agents.e2eis updated for itx (some granular function-call assertions dropped).Reviewed by Cursor Bugbot for commit 24365a0. Bugbot is set up for automated code reviews on this repo. Configure here.
Environment Config Lease
No active environment config lease.
OS
Status: released
Commit:
e59ceecPreview: https://os.iterate-preview-9.com
Summary: Preview app released.
Workflow run
Updated: 2026-06-10T15:39:06.376Z
Semaphore
Status: released
Commit:
e59ceecPreview: https://semaphore.iterate-preview-9.com
Summary: Preview app released.
Workflow run
Updated: 2026-06-10T15:38:51.403Z