Skip to content

itx: pay down the parked debts — delete codemode protocol, tombstone, legacy define compat, nested workspace.git#1476

Merged
jonastemplestein merged 10 commits into
mainfrom
itx-debts
Jun 10, 2026
Merged

itx: pay down the parked debts — delete codemode protocol, tombstone, legacy define compat, nested workspace.git#1476
jonastemplestein merged 10 commits into
mainfrom
itx-debts

Conversation

@jonastemplestein

@jonastemplestein jonastemplestein commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

The parked debts from itx-next.md, bandaid pulled to the max per review — no backcompat anywhere (prd/preview/dev itx data is erasable).

CodemodeSession tombstone — deleted

The tombstone DO class, its codemode-session-local namespace, the CODEMODE_SESSION binding, and the vitest wrangler entries are gone. Alchemy emits the deleted_classes migration (mechanism proven in #1464). Streams that still carry durable subscriber events dialing the namespace will error on delivery — accepted, the data is being erased.

executeCodemodeFunctionCall — protocol fully deleted (~2.5k lines)

Every capability entrypoint loses its legacy dispatch method (agents, gmail, repos, secrets, slack, streams, workspace, openapi-bridge, AiCapability, OrpcCapability, test entries), along with legacy-codemode-call.ts and each wrapper's dead arg-validation helpers. Two callers were still alive and got clean replacements:

  • the agent chat/debug tool path now dials AgentDurableObject.callAgentTool({ tool, path, args, callId })
  • the ingress test entry upserts secrets via OrpcCapability.call({ path: ["secrets", "upsert"], … })

packages/shared/src/codemode/packages/shared/src/type-tree/ (context-proxy deleted — only importer was a deleted legacy test provider); generated typing identifiers de-codemoded (ItxConsole, generateContextTypesFromJsonSchema, …).

Registry legacy compat — deleted

caps.define takes a target (SerializableCapTarget) only, end to end (registry, ContextDO, Project DO, handle, REPL typings): the legacy source/kind: "worker" | "facet" inputs, the codeId spelling of cacheKey, stored worker/facet kinds, the source_json rollback column + sync writes, and all read-side normalization are gone. All callers (browser REPL examples, every e2e suite) spell rpc/source targets directly.

Nested itx.workspace.git.* — deleted

Nested RpcTargets returned from entrypoint getters don't survive RPC boundaries; the flat gitClone/gitAdd/gitCommit/gitPush/gitStatus methods are the surface. The agent preset prompt was actively teaching the broken nested spelling — fixed.

allowedHosts debt — closed as misdiagnosis

The config is allowedHosts: true; the 403/502s came from a wedged vite process behind the still-connected cloudflared tunnel. Documented in itx-next.md; e2e through os.iterate-dev-jonas.com verified passing.

Verification

pnpm typecheck / lint / knip / format green; apps/os unit tests green; workerd suites (test:project-ingress 6/6, test:itx-server-handle 5/5 pre-#1472, test:type-tree 113/113) green; itx e2e (itx, fork, http, subscribe — 20 tests) green against a local dev server on the merged tree, including the post-#1474 capnweb fork.

🤖 Generated with Claude Code


Note

High Risk
Large breaking change to capability registration, MCP/ingress execution paths, and production streams that may still dial removed CodemodeSession subscribers; preview/dev data is intentionally erasable.

Overview
This PR removes the last codemode-era wiring and tightens the itx capability model with no read-side backcompat.

CodemodeSession is fully removed: the tombstone Durable Object, CODEMODE_SESSION binding/namespace in Alchemy and vitest wrangler configs, worker exports, and the dedicated test script. MCP and tests now assume execution goes through the shared itx runner.

Legacy executeCodemodeFunctionCall dispatch is deleted across capability entrypoints (~2.5k lines), along with legacy-codemode-call.ts and shared codemode/context-proxy. Call sites move to itx-native paths (callAgentTool, OrpcCapability.call, OpenAPI call({ path, args })). packages/shared codemode is renamed to type-tree with de-codemoded type-generation names.

caps.define is target-only: required SerializableCapTarget, no source/kind/codeId, no source_json column or normalizeCapTarget on read—stored rows use target_json verbatim. Docs, REPL typings, e2e, and browser REPL examples all use { type: "rpc", worker: { type: "source", source: { cacheKey, … } } }.

Workspace git drops the nested git RpcTarget getter; agents, presets, e2e, and preview scripts use flat gitClone / gitAdd / gitCommit / gitPush / gitStatus. itx-next.md records resolved debts (legacy define, nested git, allowedHosts misdiagnosis).

Reviewed by Cursor Bugbot for commit 9cf0edd. 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: 9cf0edd
Preview: https://os.iterate-preview-6.com
Summary: Preview app released.
Workflow run
Updated: 2026-06-10T20:42:28.488Z

Semaphore

Status: released
Commit: 0f50df9
Preview: https://semaphore.iterate-preview-6.com
Summary: Preview app released.
Workflow run
Updated: 2026-06-10T20:42:17.584Z

jonastemplestein and others added 9 commits June 10, 2026 19:27
The §1 litmus test's user-space half, live: export a class from your
repo's worker.js, point a cap at it, call it as itx.<name> — same shape
as first-party.

- protocol: { type: "rpc", worker: { type: "project-worker" } } is
  definable (entrypoint names YOUR export; durable-object refs remain
  the one unimplemented kind).
- registry: project-worker refs resolve to a custom dispatch — the call
  crosses to the Project DO as data, because loader entrypoints cannot
  cross an RPC boundary. Props = definer parameterization + injected
  { cap, context, projectId } attribution, same discipline as loopback.
- Project DO: itxProjectWorkerCall() builds the fresh checkout, loads
  the worker (loader extraction shared with the default-entrypoint
  path), instantiates the named export per call via
  getEntrypoint(name, { props }), and replays members or path-calls.
  ContextDO delegates to the owning project's DO.
- e2e litmus: pushes a worker.js exporting PetstoreClient to the
  project's iterate-config repo (via an itx script using the flat
  workspace git methods — the nested workspace.git.* RpcTarget is
  broken over RPC, noted as a debt), defines the cap, asserts calls,
  definer props, and spoof-proof attribution. Proven against a live
  dev deployment.
- itx-next.md refreshed: §4 marked shipped, the day's decisions logged
  (one script shape, DO deletion proven, capnweb error-name drop,
  project-worker mechanism), new debts section (workspace.git nesting,
  vite allowedHosts vs dev tunnel, prd tombstone soak).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lowlists

The remaining itx-next.md roadmap, one PR (with the ProjectWorker
forwarder already on this branch):

- url refs (§1): UrlDial loopback entrypoint dials remote Cap'n Web
  servers — ONE WebSocket session per call, terminating in the stateless
  worker (Law 7). Handshake headers pass through the same getSecret()
  substitution as project egress, resolved via the SecretsCapability
  loopback, so credentials never appear in registry rows. Never an HTTP
  batch: new lint rule iterate/no-capnweb-http-batch bans
  newHttpBatchRpcSession repo-wide.
- code-context defaults (§8): defineCodeContext is the authoring surface;
  ContextRegistryHost.defaults is the chain's final fallthrough link. Own
  rows shadow, describe() reports owner "platform:project", child
  contexts inherit through the existing parent delegation. First default:
  ai (BindingCapability over env.AI).
- addressing (§3): itx.streams.get takes "/path", "ns:/path", and
  { namespace?, path } — absolute forms are sugar through ItxStreams
  .namespace, whose access check now admits named access sets and masks
  refusals as NOT_FOUND like projects.get. Global registry node stays
  descoped (§8 gives it a cheap birth when something needs it).
- config allowlists (§2): APP_CONFIG_ITX dialableBindings/Loopbacks merge
  with the hardcoded defaults via resolveDialableTargets — widen-only, so
  a misconfigured deployment never loses first-party caps.

e2e (all green against a live dev server): url cap dials this
deployment's own /api/itx back over the network; platform default ai is
inherited and shadowable; absolute stream refs round-trip and a project
handle cannot fully-qualify its way out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… protocol

No backcompat (prd data is erasable): the tombstone DO class, its
namespace/bindings, every executeCodemodeFunctionCall method, and the
legacy wire type are gone. AgentToolsCapability now dials a clean
AgentDurableObject.callAgentTool; the ingress test entry upserts secrets
through OrpcCapability.call; packages/shared/src/codemode is renamed to
type-tree with codemode identifiers neutralized (context-proxy deleted —
its only importer was a deleted legacy test provider).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	apps/os/src/itx/e2e/itx.e2e.test.ts
Bugbot: revoke on a default-only cap returned ok and emitted capRevoked
while invoke/describe kept serving it through the code context. Defaults
cannot be revoked, only shadowed — say so. (A shadowing own row still
deletes normally; the default resurfaces.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	apps/os/package.json
…misdiagnosis

- Registry legacy compat deleted: define() requires target; codeId,
  worker/facet stored kinds, source_json column+sync, and read-side
  normalization are gone. All callers (browser REPL examples, e2e suites)
  spell rpc/source targets directly.
- Nested itx.workspace.git.* RpcTarget deleted — nested RpcTargets from
  entrypoint getters don't survive RPC boundaries; the flat
  gitClone/gitAdd/gitCommit/gitPush/gitStatus methods are the surface.
  Agent preset guidance updated (it was teaching the broken spelling).
- allowedHosts debt closed as misdiagnosis: config is allowedHosts: true;
  the 403/502 came from a wedged vite process behind the live tunnel.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	apps/os/docs/itx-next.md
#	apps/os/package.json
#	apps/os/src/itx/protocol.ts
#	apps/os/src/itx/registry.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0f50df9. Configure here.

Comment thread apps/os/src/domains/agents/agent-presets.ts
Comment thread apps/os/src/domains/workspaces/entrypoints/workspace-capability.ts
The preview example script and the agent workspace e2e assertions still
spoke the deleted nested git surface; both now use the flat
gitClone/gitAdd/gitCommit/gitPush/gitStatus methods, and the no-cloning
assertions match the flat spelling.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jonastemplestein jonastemplestein merged commit a6c5251 into main Jun 10, 2026
9 checks passed
@jonastemplestein jonastemplestein deleted the itx-debts branch June 10, 2026 20:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant