Agentic AI Atlasby a5c.ai
OverviewWikiGraphFor AgentsEdgesSearchWorkspace
/
GitHubDocsDiscord
iiRecord
Agentic AI Atlas · Research dossier: Interface delta map — fabric adapters/kradle/genty-shells vs t3code
page:docs-specs-platform-gaps-research-delta-mapa5c.ai
Search record views/
Record · tabs

Available views

II.Record viewspp. 1 - 1
overviewarticlejsongraph
III.Related pagespp. 1 - 1
II.
Page reference

page:docs-specs-platform-gaps-research-delta-map

Reading · 25 min

Research dossier: Interface delta map — fabric adapters/kradle/genty-shells vs t3code reference

Date: 2026-09-27 · Author: platform-gaps spec research run · Status: input to 10-t3code-migration.md (and Gate A adoption-model proposal)

Pagewiki/docs/specs/platform-gaps/research/delta-map.mdOutgoing · 0Incoming · 1

Research dossier: Interface delta map — fabric adapters/kradle/genty-shells vs t3code

Date: 2026-09-27 · Author: platform-gaps spec research run · Status: input to 10-t3code-migration.md (and Gate A adoption-model proposal)

Builds on and does not repeat: research/fabric-current-state.md (R1, fabric HEAD 5e46b998) and research/t3code-architecture.md (R2, snapshot 2026-09-27). Citations: fabric: paths are relative to C:/work/fabric; t3: paths are relative to the t3code snapshot at C:/Users/tmusk/AppData/Local/Temp/claude/C--work-company/368e0399-fd11-4960-8b4d-b4dcf1d79c43/scratchpad/t3code. All new path:line cites below were read at those revisions for this dossier; claims imported from R1/R2 carry their original cites.

**Overlap % method (read this before quoting the numbers):** for each row I enumerated the functional sub-capabilities of both sides (the checklists in each section), classified each as SHARED (both implement a recognizable version), FABRIC-ONLY, or T3-ONLY, and computed overlap = SHARED / (SHARED + FABRIC-ONLY + T3-ONLY), rounded to 5%. It is a *capability-count* figure, not LOC — by LOC every overlap would round to ~0 because t3code's surfaces are 5–20× larger (R2 §2). The checklists are printed so the spec author can re-weight.

---

0. Master delta table

RowFabric sidet3code sideOverlapMust-survive (fabric-unique)Gained (t3-unique)Primary ACP/interface seam
**A**adapters harness layer: 22 drive-side codec adapters + 12 observe-side hook adapters + canonical 49-type AgentEvent unionpackages/contracts (providerRuntime.ts) + packages/effect-acp + apps/server/src/provider/* (6 drivers, generic ACP runtime)**~45%**Hook/observe lane for foreign-driven sessions; journal/run binding; trust-signed policy gates; cost records; atlas graph couplingACP client+agent protocol impl; Codex app-server typed protocol; drive-side approvals (CanUseTool); provider installers/updaters; usage/quota ingestionFabric ProviderAdapter-equivalent contract: ACP lane (Cursor/Grok/Antigravity) + 3 bespoke lanes (Claude SDK, Codex app-server, OpenCode HTTP); AgentEvent becomes a projection of ACP/ProviderRuntimeEvent (D6)
**B**kradle control plane: 69 core controllers, 81 Next.js API route files under orgs/[org], K8s CR resource model, plus adapters/gateway 17-frame WS protocolapps/server (event-sourced decider/projector, SQLite) + packages/contracts RPC (144+8 WS methods) + environment auth**~30%**Multi-tenant org control plane (K8s namespaces, Helm/GKE); 7-action approval gate taxonomy; secrets/policy/exception-request/report surfaces; gitops; inference/virtual-model routing; journal-derived kanbanEvent-sourced command/decider/projector/reactor core with replay-forever; typed single wire boundary (Effect Schema); capability-flag versioning; checkpoints; PR domain; DPoP auth; terminal; device controlt3code environment server becomes the **single-node environment** under kradle's multi-tenant plane; contracts environment descriptor + capability flags = the kradle↔environment boundary; approvals bridged to babysitter signed breakpoints
**C**genty client shells (web-app + Electron scaffold + 7 L0 device shells) + genty/ui GatewayClient + kradle/web REST/SSE data layerpackages/client-runtime (connection supervisor, ~30 atom state services) + apps/web (318k LOC) + apps/desktop (backend-bundling Electron)**~20%**Multi-org UI semantics; approval/policy/observability UI surfaces; org-admin REST/SSE pages; react-native WS transport; journal kanban viewsMulti-environment connection catalog + supervisor; reactive atom state layer; composer/diff/terminal-wasm/checkpoint UI; desktop that bundles its own serverclient-runtime platform/ service interfaces = shell plug-point; connection registry treats each kradle-managed environment as a t3code environment; kradle-web keeps org-admin, thread/run UX moves to adapted apps/web
**D**Remote access: **absent** except gateway token auth + LAN short-code pairing framespackages/ssh, packages/tailscale, apps/server/src/cloud + infra/relay (T3 Connect broker)**~5%**Trust-core key/chain machinery must become the signing substrate (not duplicated); org-awareness of any hosted relayAll four remote routes: DPoP direct pairing, tailscale endpoint, ssh launch+forward, hosted relay (broker-not-proxy, cloudflared)Gateway auth/ + pairing/ replaced by t3code environment auth (DPoP + pairing grants); ssh/tailscale packages extractable as-is (dep: effect only)

---

Row A — fabric `adapters` harness layer vs t3code `contracts` + `effect-acp` + provider adapters

A.1 What fabric actually has (corrects a simplification in R1)

R1 §3.1 describes the adapters family primarily through the hooks lane. The drive lane is real and larger than R1 implies:

  • **Drive-side adapter contract.** fabric:packages/adapters/core/src/adapter-types.ts:24 defines BaseAgentAdapterInterface with identity, capabilities (:35), detectAuth() (:42), session-file parsing (sessionDir/parseSessionFile/listSessionFiles), config read/write, model discovery, and host-detection env signals; three adapter kinds: SubprocessAdapter (:79), RemoteAdapter with connect/startServer/healthCheck (:93-104), ProgrammaticAdapter (:168-169).
  • **RunHandle.** adapter.run() returns a RunHandle that is simultaneously AsyncIterable<AgentEvent>, a typed event emitter, and a thenable resolving RunResult (fabric:packages/adapters/core/src/run-handle.ts:1-8, interface at :150), including deferred-prompt steering (DeferredPromptTarget = 'next-turn' | 'after-tool' | 'after-response', run-handle.ts:44-51).
  • **Canonical event model.** 49 event interfaces extending BaseEvent (measured: grep -c "extends BaseEvent" = 49) in fabric:packages/adapters/core/src/events.ts — session lifecycle (:21-46), turns/steps (:57-75), message/thinking deltas (:85-115), tool calls (:124-153), file ops (:164-186), shell (:196-212), MCP (:222-238), subagents (:250-265) — unioned as AgentEvent at events.ts:411. This is the "current adapters event model" that D6 demotes to an internal projection.
  • **22 concrete drive adapters** in fabric:packages/adapters/codecs/src/ (measured: ls *-adapter.ts | wc -l = 22): incl. claude-agent-sdk-adapter.ts, codex-sdk-adapter.ts, codex-websocket-adapter.ts, opencode-http-adapter.ts, cursor-adapter.ts, plus subprocess adapters for gemini/copilot/droid/amp/omp/etc., self-registering via a global factory registry (fabric:packages/adapters/codecs/src/base-adapter.ts:61, base class :75).
  • **12 observe-side hook adapters** (fabric:packages/adapters/hooks/adapter-{antigravity,claude,codex,copilot,cursor,gemini,genty,hermes,oh-my-pi,openclaw,opencode,pi}, directory listing) that instrument a harness the *user* is driving and feed events/hooks back into runs — R1 §3.1.
  • **No ACP anywhere** (R1 §3.1: zero hits for ACP under packages/adapters — re-confirmed premise for D6 greenfield).

A.2 t3code side (from R2, key cites)

ProviderAdapter contract (t3:apps/server/src/provider/Services/ProviderAdapter.ts:1-60) with typed capabilities — sessionModelSwitch, promptlessTurnContinuation, supportsConversationRollback (:46-56) — and a compaction contract (native start-call vs slash-command, :36-44); 6 built-in drivers (t3:apps/server/src/provider/builtInDrivers.ts:49-56); one generic ACP runtime + per-provider extension modules (R2 §4); packages/effect-acp implementing ACP **both directions** — client for driving agents, agent for being one (R2 §6); packages/effect-codex-app-server as the typed Codex lane (R2 §7); canonical ProviderRuntimeEvent surface in t3:packages/contracts/src/providerRuntime.ts (1,234 LOC, R2 §5).

A.3 Sub-capability checklist

Sub-capabilityFabrict3codeClass
Per-harness adapter registry + factorybase-adapter.ts:61builtInDrivers.ts:49-56 + ProviderInstanceRegistrySHARED
Canonical normalized event streamevents.ts:411 (49 types)providerRuntime.ts + Normalizer.tsSHARED
Capability declaration per harnessadapter-types.ts:35ProviderAdapter.ts:46-56SHARED
Auth detection / guidanceadapter-types.ts:42-43ProviderAuthService + per-provider flows (R2 §4)SHARED
Harness install/updatecodecs/src/adapter-install.ts (import at base-adapter.ts:44)installers incl. Antigravity version-leased downloads (AntigravityInstallation.ts)SHARED (t3 deeper)
Session-file parsing of harness-native session dirsadapter-types.ts:46-49agentSessions.ts import (claudeAgent/codex only, R2 §5)SHARED (fabric broader)
Run steering (deferred prompts)run-handle.ts:44-51turn dispatch + async question protocol (R2 §4 Codex row)SHARED
Cost/token accounting on the event streamrun-handle.ts:21-27 (TokenUsageSummary), CostRecord (run-handle.ts:9)turn token usage in providerRuntime.ts; usage/quota ingestion subsystem (R2 §3)SHARED (different shape)
**ACP protocol implementation (client+agent)**—effect-acp (R2 §6)T3-ONLY
**Typed Codex app-server protocol**— (fabric codex lane is CLI/hooks/WebSocket: codecs/src/codex-websocket-adapter.ts)effect-codex-app-server (R2 §7)T3-ONLY
**Drive-side permission callbacks** (approve tool use mid-turn)— in the drive lane (approvals live in hooks/policy/breakpoints, Row B)Claude CanUseTool, ACP permission modes (R2 §4)T3-ONLY
**Workspace checkpoint coordination with conversation rollback**—checkpointing/CheckpointStore.ts:1-15 + revert rules (R2 §3.4)T3-ONLY
**MCP endpoint injected into every provider session**— (fabric has MCP plugins, codecs/src/mcp-plugins.ts, not an injected control endpoint)mcp/McpProviderSession.ts:1-12T3-ONLY
**Observe-side hook adapters for foreign-driven sessions**12 hook adapters (dir listing above); R1 §3.1— (t3code only drives sessions it started)FABRIC-ONLY
**Journal/run binding of harness events**stop-hook → session → run binding (babysitter-sdk/src/harness/hooks/stopHookHandler.ts:209-225, R1 H7)— (events bind to t3code's own SQLite threads, not an external ledger)FABRIC-ONLY
**Trust-signed policy gating of tools/MCP**adapters/policy/src/proven-bridge.ts:92-119 (human-root chain), enforcement wiring R1 C3— (approvals are session-scoped UX, not signed)FABRIC-ONLY
**Model-proxy transport with attestation seam**adapters/transport/src/server.ts:1596-1607 (R1 H10)—FABRIC-ONLY
**Graph-derived harness metadata (atlas)**atlas dep in every hooks adapter (R1 §3.6)— (model-manifest.json is static, R2 §4)FABRIC-ONLY

Count: 8 SHARED, 5 FABRIC-ONLY, 5 T3-ONLY → **overlap ≈ 45%**.

A.4 Must-survive (fabric-unique, binding)

1. **Journal/run binding**: every harness event lane must still terminate in the babysitter journal/run model (journal write path fabric:packages/babysitter-sdk/src/storage/journal.ts:72-82; hook→session→run resolution stopHookHandler.ts:209-225). t3code has no external ledger concept; the ACP re-platforming must not silently replace the journal with t3code's SQLite event store as source of truth for *runs*. 2. **Observe lane**: the 12 hook adapters cover harnesses t3code does not (gemini, copilot, pi, oh-my-pi, openclaw, hermes, genty) and a mode t3code lacks entirely (instrumenting a user-driven session). They stay, feeding the same canonical projection. 3. **Trust-signed gates**: proven-bridge.ts:92-119 human-root verification and the policy enforcement wiring (R1 C3) must gate the new drive lane's permission callbacks, not be bypassed by them. 4. **Cost records + attestation seam** (run-handle.ts cost types; transport/src/server.ts:1596-1607) survive as projection consumers.

A.5 Gained from t3code

ACP client+agent runtime (5.2k handwritten LOC, dep = effect only, R2 §18.2/§18.9); typed Codex app-server lane (3.8k handwritten); generic-runtime-plus-extension-modules pattern for per-harness ACP quirks (t3:apps/server/src/provider/acp/{AcpSessionRuntime,CursorAcpExtension,XAiAcpExtension}.ts, R2 §4); provider installer/updater machinery with ownership proofs (providerMaintenance.ts); usage/quota ingestion; ACP mock agent for protocol tests (t3:apps/server/scripts/acp-mock-agent.ts, R2 §18.11).

A.6 The seam, precisely (D6)

D6 says ACP is canonical and the current adapters event model becomes a projection. The t3code evidence fixes the shape:

1. **One adapter contract, four lanes.** Fabric adapters gets a ProviderAdapter-equivalent contract (successor of adapter-types.ts:24 + run-handle.ts:150) with: an **ACP lane** (effect-acp client; covers Cursor cursor-agent … acp, Grok grok … agent stdio, Antigravity downloaded ACP release — R2 §18.1) and **three bespoke lanes behind the same contract**: Claude via @anthropic-ai/claude-agent-sdk in-process, Codex via app-server JSON-RPC stdio, OpenCode via HTTP server-per-thread (R2 §18.1). This is exactly t3code's shape; fabric adds its remaining harnesses (gemini, copilot, pi, …) as either new ACP lanes or retained subprocess codecs behind the same contract. 2. **Projection direction.** ACP session/update notifications and bespoke-lane events → normalizer → **fabric AgentEvent (events.ts:411) as derived view** → existing consumers (RunHandle iterators, gateway run.event frames, journal binding, cost/attestation). Consumers keep compiling; only the producer side is re-platformed. 3. **Fabric as ACP agent.** effect-acp's agent.ts service (R2 §6) lets fabric expose babysitter runs/genty sessions *as* ACP sessions — the reciprocal seam that makes fabric drivable by other ACP clients. No fabric equivalent exists today. 4. **Effect boundary (D5 input).** effect-acp and effect-codex-app-server depend only on effect (R2 §18.2) — they can be quarantined behind the lane boundary: the adapter contract surface stays plain-TS (Promise/AsyncIterable, as run-handle.ts already is), Effect lives inside the lane implementations.

---

Row B — `kradle` control-surface APIs/UIs vs t3code `apps/server` (+ contracts RPC) / `apps/web`

B.1 Fabric side

Three distinct control surfaces exist (a fact the spec must not blur):

  • **kradle/core**: 69 controller modules (dir listing; R1 §3.2) on a K8s CR resource model — dispatch, approvals, memory, persona, workspace, writeback, secrets, transport binding, triggers, subagents, gitops (argocd-gitops.js), gitea backend, event bus, control/data-plane split (control-plane.js, data-plane.js), org scoping via K8s namespaces (fabric:packages/kradle/core/src/org-scoping.js:5 re-exporting orgNamespaceName/normalizeOrgSlug/resolveResourceOrg/withOrgScope from kubernetes-controller.js).
  • **kradle/web API**: **81 route files** under app/api (measured: find app/api -name "route.js" -o -name "route.ts" | wc -l = 81), org-scoped under orgs/[org]/{agents,artifacts,assistant,external,hooks,inference,jitsi,pipelines,policies,policy-exception-requests,policy-reports,profile,repositories,resources,search,secrets,snapshot,views,webhooks,workspaces} (dir listing) plus auth/*, atlas/search, git-proxy, and an SSE watch route streaming controller watch events (fabric:packages/kradle/web/app/api/watch/[[...resource]]/route.js:1-20, createKradleApiController() at :1). Routes are untyped .js — no schema layer.
  • **adapters/gateway**: the run-facing WS control surface — HTTP + WebSocketServer (fabric:packages/adapters/gateway/src/server.ts:4,177,181,572), a zod-validated **17-frame protocol v1** (fabric:packages/adapters/gateway/src/protocol/v1.ts, 151 lines: auth:6, hello:11, subscribe:26, session.start:47, session.message:61, run.event:79, hook.request:87, hook.decision:96, hook.resolved:103, pairing.register:110, pairing.consume:117, union :151), a run manager holding live RunHandles with per-run event log + hook broker + webhook fan-out (fabric:packages/adapters/gateway/src/runs/manager.ts:103-224), token auth (auth/tokens.ts, auth/middleware.ts), and a kanban read-model built directly over .a5c/runs/ journal directories (fabric:packages/adapters/gateway/src/kanban/lib/source-discovery.ts:12-34, routes registered server.ts:24).
  • **Approvals**: kradle's AgentApproval resource with **seven first-class gate actions** — review, ai-review, tool-use, secret-access, write-back, release, escalation (fabric:packages/kradle/core/src/agent-approval-controller.js:15, boundary decl :3-9), and babysitter's signed-breakpoint enforcement chained to human trust roots (fabric:packages/adapters/policy/src/proven-bridge.ts:92-119, R1 H9).

B.2 t3code side (R2 cites)

Single-user environment server: event-sourced engine (commands → pure decider → events → projector → reactors, one SQLite transaction — R2 §3.1, t3:docs/internals/overview.md:56-72); **144 Rpc.make WS methods + 8 orchestration methods** as the sole typed wire boundary (t3:packages/contracts/src/rpc.ts:277,1394; orchestration.ts:35-44); environment auth with DPoP + pairing grants + per-method RPC authorization (R2 §3.3); checkpoints as hidden git refs (R2 §3.4); PR domain across 4 providers (R2 §3); terminal, device control, resource telemetry, usage ingestion; approval policies + pending-approvals projection + sandbox modes in contracts/orchestration.ts (R2 §5).

B.3 Sub-capability checklist

Sub-capabilityFabrict3codeClass
Create/dispatch agent run/threadagent-dispatch-controller.js; gateway session.start frame (v1.ts:47)dispatchCommand (orchestration.ts:35-44)SHARED
Live event streaming to clientsgateway run.event fan-out (manager.ts:103-110)subscribeThread/subscribeShell + ThreadLiveEventCoalescer (R2 §3.1)SHARED
Human approval gates7-action AgentApproval (agent-approval-controller.js:15) + gateway hook.request/decision (v1.ts:87,96) + signed breakpoints (proven-bridge.ts:92-119)approval policies + pending-approvals projection + ProviderApprovalDecision (R2 §5, ProviderAdapter.ts imports)SHARED (fabric taxonomy richer; t3 UX deeper)
Project/repo registry + source controlagent-project-controller.js, repository-reconciler.js, gitea backendproject/ + sourceControl/ + vcs/ (R2 §3)SHARED
Session transcript accessagent-session-transcript-controller.jsprojections (threads/messages/turns) (R2 §3.2)SHARED
Secrets handlingagent-secret-config-grant-controller.js + orgs/[org]/secrets routesServerSecretStore + keyring (R2 §3.3)SHARED (different scope: org grants vs host keyring)
Server config/probe/update surfaceagent-gateway-config-controller.js, api-controller.jscontracts/server.ts (891 LOC) + selfUpdate (R2 §5, §3.6)SHARED
Auth for the control surfacegateway bearer tokens (auth/tokens.ts); kradle web auth/[provider] OAuth routesDPoP + pairing grants + scoped sessions (R2 §3.3)SHARED (t3 stronger for device pairing; fabric has org SSO)
**Multi-tenant org control plane** (K8s namespaces, CR reconcilers, Helm/GKE)org-scoping.js:5; 81 org-scoped routes; charts + GKE deploy (R1 §3.2)— (one environment = one user's machine)FABRIC-ONLY
**Policy engine surfaces** (policies, exception requests, reports)orgs/[org]/{policies,policy-exception-requests,policy-reports} routes—FABRIC-ONLY
**Inference/virtual-model routing**kradle-inference-service-controller.js, virtual-model-controller.js, infer route (R1 CAP5)—FABRIC-ONLY
**GitOps/CI runners/jitsi realtime**argocd-gitops.js, runners-ci.js, jitsi-*.js—FABRIC-ONLY
**Journal-derived kanban read model**kanban/lib/source-discovery.ts:12-34—FABRIC-ONLY
**Event-sourced core with replay-forever discipline**— (kradle state = K8s CRs + gateway SQLite event log without decider/projector split)R2 §3.1, overview.md:70-72T3-ONLY
**Typed contract package as sole wire boundary**— (81 untyped .js routes; gateway zod frames are the only typed slice)contracts 48 modules, Effect Schema (R2 §5)T3-ONLY
**Capability-flag client/environment version negotiation**—environment.ts:1-3 + doctrine (overview.md:24-44)T3-ONLY
**Workspace checkpoints / turn diff / restore**—getTurnDiff/getFullThreadDiff (orchestration.ts:35-44), CheckpointStore (R2 §3.4)T3-ONLY
**PR lifecycle domain (4 providers), terminal, device control, resource telemetry**— (kradle has repos, not PR stacks; no PTY surface; no device control)R2 §3, §5T3-ONLY

Count: 8 SHARED, 5 FABRIC-ONLY, 5 T3-ONLY → **≈ 45%** by raw count, **but** the five t3-only entries bundle whole subsystems (PR/terminal/device/telemetry counted once). Weighting those as four distinct capabilities gives 8/(8+5+8) → **~30%**, the honest figure used in the master table.

B.4 Must-survive (fabric-unique, binding)

1. **Multi-tenant control plane**: org scoping (org-scoping.js:5), the 81 org-scoped API routes, K8s CR reconcilers and Helm/GKE deployment (R1 §3.2) are the product's SaaS spine; t3code's single-user environment model must slot *under* it, never replace it. 2. **Approval taxonomy + signed breakpoints**: the 7 gate actions (agent-approval-controller.js:15) and human-root-chained breakpoint proofs (proven-bridge.ts:92-119) are a strict superset of t3code approvals; the migrated surface must map t3code's pending-approvals projection *onto* AgentApproval, preserving secret-access/write-back/release/escalation semantics t3code has no notion of. 3. **Journal as run source-of-truth**: gateway kanban and run manager derive from .a5c/runs journals (source-discovery.ts:12-34, manager.ts:110); t3code's SQLite store may own *its* thread/turn projections but run identity/provenance stays with the babysitter journal. 4. **Process orchestration**: babysitter defineTask/breakpoints exports (fabric:packages/babysitter-sdk/src/index.ts:16) and the run lifecycle (R1 §3.4) are the orchestration substrate; t3code's decider orchestrates chat turns, not long-running processes with quality gates. 5. **Trust signing substrate**: trust-core sign/verify families (fabric:packages/trust-core/src/index.ts:1-7: payload, model-response, model-decision, agent-request/prompt, tool-result/permission-evidence, chain).

B.5 Gained from t3code

Event-sourced orchestration core with single-transaction commit and replay-forever discipline; a typed contract package with 144+8 methods and the capability-flag/schema-transform compat doctrine (R2 §18.5) — the direct cure for kradle's 81 untyped routes; checkpoint/diff/restore; PR stacks; terminal; DPoP/pairing auth; receipts + drainable-worker test pattern (R2 §18.11).

B.6 The seam, precisely

  • **Topology**: kradle (multi-tenant, K8s) ⟷ *N* t3code-style **environments** (one per workspace/runner). The boundary contract is t3code's environment descriptor + capability flags + environmentHttp.ts HttpApi groups (R2 §5). Kradle's agent-dispatch-controller/agent-workspace-controller become environment *clients* dispatching OrchestrationCommands instead of driving adapters directly.
  • **Gateway fate**: the 17-frame gateway protocol (v1.ts) is the projection ancestor of the contracts RPC surface — session.start/message ↔ dispatchCommand, run.event ↔ subscribeThread, hook.request/decision ↔ pending-approval flow. The spec must choose (D1, per-component): extend contracts with fabric's run/hook/pairing groups (tracked fork per D9) vs keep the gateway as a thin ACP-facing shim. Evidence favors the former: the gateway's zod frames are the only typed slice fabric has, and they are 151 lines vs contracts' 26,979.
  • **ACP touchpoint**: the environment server hosts Row A's four-lane provider layer; kradle never speaks ACP directly — ACP terminates inside the environment (mirrors t3code, where web/desktop never see ACP, only contracts RPC).

---

Row C — `genty` client shells + `kradle-web` data layer vs t3code `apps/*` + `client-runtime`

C.1 Fabric side

  • **genty/ui client layer**: GatewayClient + provider/hooks/store exports (fabric:packages/genty/ui/src/gateway.ts:1-8: useGateway/useAgents/useRun/useHookRequests/useConnection), WS transports for browser/node/react-native (fabric:packages/genty/ui/src/client/transports/{ws-browser,ws-node,ws-react-native}.ts), backoff logic (client/backoff.ts), and a **mirror copy of the gateway protocol** (fabric:packages/genty/ui/src/protocol/v1.ts:1-15, 151 lines, 18 exported interfaces — duplicated type-for-type from the gateway package rather than imported from a shared contracts unit).
  • **Shells**: genty/web-app = thin Vite shell (src/{App.tsx,main.tsx,layout,pages}, dir listing) — the only Playwright-gated shell (R1 §3.3); genty/desktop-app = 10-file Electron scaffold (fabric:packages/genty/desktop-app/package.json:9-13: electron . / electron-builder); 7 device shells at L0 (R1 §3.3, Spec input 7).
  • **kradle/web data layer**: Next.js server components + REST fetch to the 81 routes + **SSE** live updates — EventSource on /api/orgs/${org}/agents/events/stream with manual retry/refresh debounce (fabric:packages/kradle/web/app/components/agent/live-updates.jsx:30, retry state :8-14) and the [[...resource]] SSE watch route (route.js:1-20). No shared client runtime: kradle-web and genty-ui have zero common data-layer code (separate packages, different protocols — REST/SSE vs gateway WS).

C.2 t3code side (R2 cites)

client-runtime (256 files / 65.8k LOC): single connection supervisor owning transport retry, per-environment connection registry, compatibility negotiation, ~30 atom-based state services, credential refresh decoupled from socket lifetime, platform/ service interfaces that shells implement (R2 §8, t3:docs/internals/connection-runtime.md:1-27). apps/web 318k LOC (React 19, TanStack Router, composer, ghostty-wasm terminal, hosted app as pure client with browser-held catalog — R2 §11). apps/desktop 81k LOC Electron 44 that **bundles and spawns the server** (DesktopBackendManager/Pool, R2 §11). Mobile deferred (D13) but consumes the same stack (R2 §11).

C.3 Sub-capability checklist

Sub-capabilityFabrict3codeClass
WS client with typed frames + backoffgenty/ui/src/client/{GatewayClient,backoff}.tsclient-runtime/connection/supervisor.tsSHARED
React hooks/state over live runsgateway.ts:1-8 hooks + storestate/ atom services (R2 §8)SHARED
Web shell for run interactiongenty/web-app (Playwright-gated)apps/web chat/threads (R2 §11)SHARED
Desktop shellgenty/desktop-app Electron scaffold (package.json:9-13)apps/desktop (81k LOC, bundles server)SHARED (fabric = scaffold only)
React-native transporttransports/ws-react-native.tsExpo mobile app (deferred D13)SHARED (both exist; both out-of-depth here)
**Org-admin UI over the control plane** (policies, secrets, webhooks, inference, pipelines)kradle/web pages over 81 routes—FABRIC-ONLY
**Observability dashboards** (activity feed, health monitor)kradle/web/app/components/observability/{activity-feed,health-monitor}.jsx; genty-ui ActivityFeed.tsxagentActivity exists relay-side only (R2 §12)FABRIC-ONLY
**Journal/kanban + run-history views**gateway kanban UI routes (kanban/routes.ts); observer-dashboard (R1 §3.8)—FABRIC-ONLY
**Multi-environment connection catalog + supervisor**— (genty-ui connects to one gateway)connection/registry.ts + browser-held catalog (R2 §8, §11)T3-ONLY
**Composer/diff/terminal/checkpoint UX**—tiptap, @pierre/diffs, ghostty wasm, checkpointDiff state (R2 §8, §11)T3-ONLY
**Credential refresh decoupled from socket; compat negotiation**—authorization/service.ts, catalog compat (R2 §8)T3-ONLY
**Desktop-as-host-environment** (spawns bundled server)— (fabric desktop scaffold renders only)DesktopBackendManager.ts (R2 §11)T3-ONLY

Count: 5 SHARED, 3 FABRIC-ONLY, 4 T3-ONLY → ~40% by count, but three of the five SHARED rows are fabric scaffolds vs t3code production systems (desktop 10 files vs 258; web-app thin shell vs 1,258 files; hooks/store vs 30 services). Discounting the scaffold rows to half-credit: **~20-25%** — the master table says ~20%.

C.4 Must-survive (fabric-unique, binding)

1. **Org-admin surfaces**: policies/exception-requests/secrets/webhooks/inference/pipelines pages have no t3code analogue and stay on kradle-web (REST/SSE is adequate for admin CRUD). 2. **Observability/journal views**: activity feeds, health monitor, kanban-over-journal, observer-dashboard — these render fabric-unique data (journal runs, org events) and must be re-pointed at whatever client runtime wins, not dropped. 3. **The genty-ui hook API** (useRun/useHookRequests, gateway.ts:1-8) is the only fabric client code with real consumers *and* tests (genty-ui 18 test files, R1 §4.4); its semantics (hook-request surfacing = approvals UX) must be reproduced in any client-runtime adoption. 4. Per D2c the 7 device shells + desktop scaffold are **retired**, destroying ~0 tested functionality (R1 Spec input 7) — nothing to survive there beyond the react-native transport learning.

C.5 Gained from t3code

A real client runtime: one supervisor for reconnects across all surfaces (the exact bug-class genty-ui's per-client backoff and kradle-web's hand-rolled EventSource retry (live-updates.jsx:8-30) both re-implement, divergently — R2's design rationale at connection-runtime.md:1-27 names this failure mode); multi-environment catalog; production web app with composer/diff/terminal; a desktop app that *is* a host environment (directly serves D3 single-node UX).

C.6 The seam, precisely

  • **Plug point** = client-runtime's platform/ service interfaces (R2 §8): fabric shells (adapted web app; kradle-web where it embeds run views) implement platform services; everything above them is shared.
  • **Connection model**: each kradle-managed environment (Row B seam) appears as one entry in the client-runtime connection registry — the hosted-web pattern (browser-held catalog, direct connection to each environment, t3:docs/internals/remote.md:28-38) is exactly the multi-tenant fabric topology, with kradle acting as catalog *source*.
  • **Protocol duplication ends**: genty-ui's copied protocol/v1.ts (151 lines duplicated from gateway) is the anti-pattern the contracts package eliminates — one schema package, imported by both sides (R2 §5 doctrine).
  • **ACP touchpoint**: none direct — clients speak contracts RPC; ACP stays inside the environment (Row A). The only client-visible ACP artifact is normalized activity/permission events, already typed in providerRuntime.ts.

---

Row D — fabric remote story (absent) vs t3code ssh / tailscale / T3 Connect relay

D.1 Fabric side

R1 §3.10 confirmed: zero tailscale/relay/ssh-tunnel code in fabric. What *does* exist, and counts as the 5% seed:

  • Gateway bearer-token auth (fabric:packages/adapters/gateway/src/auth/{tokens,middleware,bootstrap,hashing}.ts, dir listing) — same-host/LAN trust only, no proof-of-possession.
  • LAN pairing: pairing.register/consume/consumed frames (v1.ts:110-122) backed by an in-memory 8-digit short-code store with 5-minute TTL (fabric:packages/adapters/gateway/src/pairing/short-code.ts:1-20).
  • kradle is *cloud-deployed* (GKE, R1 §3.2) — but that is hosted control plane, not remote access to a user's local environment; the D12 gap (reach my machine's agents from anywhere) is untouched.

D.2 t3code side (R2 §10, §12, §18.6)

Four routes: (1) direct/LAN pairing hardened with DPoP proofs + pairing grants + scoped sessions; (2) Tailscale as "an endpoint for ordinary pairing" (t3:packages/tailscale, 763 LOC, wraps user's tailscale CLI with secret-scrubbing errors); (3) SSH bootstrap + port-forward with desktop-owned lifecycle (t3:packages/ssh, 4,143 LOC, downloads server via cliRelease); (4) T3 Connect hosted relay — Cloudflare Worker + Postgres + Clerk, broker-not-proxy (relay never sees session tokens; one-time bootstrap credential bound to client DPoP key; cloudflared managed tunnels; t3:docs/internals/t3-connect.md:3-33).

D.3 Delta

Sub-capabilityFabrict3codeClass
Short-lived pairing codesshort-code.ts:1-20 (random digits, no key binding)pairing grants bound to DPoP keys (R2 §3.3)SHARED (fabric version is a toy by comparison)
Everything else — DPoP, tailscale, ssh, relay, tunnel lifecycle, self-update handoff—R2 §10, §12, §3.6T3-ONLY (4+ capabilities)

**Overlap ≈ 5%.**

D.4 Must-survive / must-integrate (fabric-unique)

1. **trust-core as signing substrate**: the relay protocol uses @noble/curves signing both directions (R2 §12); fabric already owns key-pair/chain machinery with human-root semantics (trust-core/src/index.ts:1-7, chain.ts). The spec must decide integration (relay envelopes verified against fabric trust chains) rather than shipping two parallel PKIs. 2. **Org-aware relay**: T3 Connect identity is per-user Clerk (R2 §12); a fabric relay must scope environments to kradle orgs (org-scoping.js:5) — the multi-tenant control plane is the natural place to anchor environment↔org linking, replacing Clerk. 3. Gateway pairing frames (v1.ts:110-122) are the migration shim: same UX slot, upgraded to DPoP-bound grants.

D.5 Gained

The entire D12 mandate, pre-built: extractable ssh/tailscale packages (deps: effect only, R2 §18.2), the environment-side cloud/ module (managed cloudflared tunnels, CLI tokens, self-update), and a reference relay whose trust model (broker-not-proxy, t3-connect.md:3-6) is the design fabric should adopt verbatim. Operational cost: Cloudflare Worker + Postgres + Clerk-or-replacement stack (R2 §16).

D.6 The seam

Remote access terminates at **environment auth** (Row B's boundary): every route (LAN, tailscale, ssh, relay) ultimately performs the same DPoP pairing against the environment server — t3code's discipline that "tailscale is not a separate environment type" (t3:docs/internals/remote.md:43-45) should be adopted as-is. ACP is untouched by this row: remote access is about reaching the environment's contracts-RPC surface, inside which ACP lanes run (Row A).

---

CONFIRMED vs INFERRED

**CONFIRMED** (read at cited lines for this dossier): fabric adapter contract shape and 3 adapter kinds (adapter-types.ts:24,79,93,168); RunHandle triple nature and deferred prompts (run-handle.ts:1-8,44-51,150); 49-interface AgentEvent union (events.ts, count measured); 22 codec adapters + factory registry (measured; base-adapter.ts:61,75); 12 hook adapter dirs (listing); gateway 17-frame protocol with cited frame lines (v1.ts), server WS wiring (server.ts:4,177,181,572), run manager binding (manager.ts:103-224), journal-sourced kanban (source-discovery.ts:12-34), short-code pairing (short-code.ts:1-20); kradle 81 API route files (measured) and org-route inventory (listing); approval action set (agent-approval-controller.js:15); org-scoping exports (org-scoping.js:5); SSE data layer (live-updates.jsx:8-30, watch/[[...resource]]/route.js:1-20); genty-ui exports/transports/protocol copy (gateway.ts:1-8, transport files, protocol/v1.ts 151 lines/18 interfaces); desktop-app Electron scripts (package.json:9-13); trust-core export surface (index.ts:1-7); babysitter breakpoints export (index.ts:16); t3code ProviderAdapter capabilities/compaction (ProviderAdapter.ts:29-56).

**INFERRED** (flagged): the overlap percentages (judgment over the printed checklists — method stated in §0); the claim that genty-ui's protocol/v1.ts is a *copy* of the gateway's (identical length and frame names read on both sides; a diff was not run line-by-line); the B.6 recommendation that contracts-extension beats gateway-retention (an adoption-model argument for Gate A, not a fact); the weighting notes applied to rows B and C overlap figures.

---

Spec inputs

Concrete facts the spec author (10-t3code-migration.md and 20-functionality-coverage.md) must use:

1. **Fabric already has a drive-side adapter contract** — BaseAgentAdapterInterface + SubprocessAdapter/RemoteAdapter/ProgrammaticAdapter (fabric:packages/adapters/core/src/adapter-types.ts:24,79,93,168) and RunHandle (run-handle.ts:150) with 22 codec implementations. The D6 re-platforming is a *contract replacement with lane restructuring*, not a first drive-layer build; migration WPs must enumerate the 22 codec adapters and the 12 hook adapters as distinct migration units. 2. **The projection target is fixed**: AgentEvent union at fabric:packages/adapters/core/src/events.ts:411 (49 event interfaces) becomes the derived view; its existing consumers (RunHandle iteration, gateway run.event fan-out at manager.ts:103-110, journal binding, cost summaries) define the projection's acceptance tests. 3. **Four-lane shape is copied from t3code**: ACP lane (Cursor/Grok/Antigravity) + Claude-SDK, Codex-app-server, OpenCode-HTTP bespoke lanes behind one contract (t3:apps/server/src/provider/builtInDrivers.ts:49-56, ProviderAdapter.ts:1-60); fabric's extra harnesses (gemini, copilot, pi, oh-my-pi, openclaw, hermes, droid, amp, omp, genty) need a per-harness lane decision (ACP / retained-subprocess-codec / retired) — a mandatory WP table. 4. **effect-acp gives both directions**: adopt the agent side (t3:packages/effect-acp/src/agent.ts) to expose fabric runs as ACP sessions — a new capability, zero fabric precedent, and the cleanest early win (dep = effect only). 5. **Kradle↔environment boundary**: adopt t3code's environment descriptor + capability flags (t3:packages/contracts/src/environment.ts:1-3) as the interface between kradle's multi-tenant plane and per-workspace environment servers; kradle dispatch/workspace controllers become environment clients. 6. **Typed-contract debt is quantified**: kradle-web has **81 untyped route files** (measured) vs the gateway's 151-line zod protocol as fabric's only typed wire slice (gateway/src/protocol/v1.ts) vs contracts' 26,979 LOC / 144+8 methods. The migration spec must map each of the 17 gateway frames to a contracts RPC group (session.start/message→dispatchCommand, run.event→subscribeThread, hook.request/decision→pending approvals, pairing.*→pairing grants) and schedule route-by-route typing (or replacement) of the 81. 7. **Approval mapping table required**: t3code ProviderApprovalDecision/pending-approvals ↔ kradle's 7 gate actions (agent-approval-controller.js:15) ↔ babysitter signed breakpoints with human-root chains (proven-bridge.ts:92-119). secret-access, write-back, release, escalation have no t3code counterpart and must be preserved as fabric extensions of the approval contract. 8. **Journal sovereignty rule**: t3code's SQLite event store may own thread/turn projections inside an environment, but run identity, provenance, and replay stay with the babysitter journal (storage/journal.ts:72-82; kanban reads .a5c/runs at source-discovery.ts:12-34). Any WP that lets the environment store become run source-of-truth violates this dossier. 9. **Client-runtime adoption anchor**: genty-ui's hook API (useRun/useHookRequests, gateway.ts:1-8) is the tested fabric client surface to reproduce; genty-ui's duplicated protocol/v1.ts (151 lines mirroring the gateway package) is the concrete anti-pattern the shared contracts package removes. 10. **Retirement inventory (D2c)**: 7 device shells + desktop-app scaffold (package.json:9-13) retire; apps/desktop's DesktopBackendManager pattern (bundling a host environment) becomes the single-node desktop story (also serves D3); kradle-web survives as org-admin (REST/SSE acceptable there — live-updates.jsx:30), run/thread UX moves to the adapted web app. 11. **Remote-access WPs start from the gateway pairing shim**: upgrade pairing.register/consume (v1.ts:110-122) + ShortCodeStore (short-code.ts:1-20) to DPoP-bound pairing grants; extract t3:packages/{ssh,tailscale} as-is; relay WP must specify Clerk-replacement by kradle org identity and trust-core-based envelope verification (trust-core/src/index.ts:1-7) instead of a second PKI. 12. **Overlap figures for sizing** (capability-count method, §0): A ≈45%, B ≈30%, C ≈20%, D ≈5%. Inverse reading for effort: Row D is pure adoption (nothing to merge), Row A is a true merge (two live adapter systems), Rows B/C are graft-under/graft-over operations where fabric-unique planes (multi-tenant, approvals, journal) wrap adopted t3code cores. 13. **Effect boundary rule candidates (D5)**: keep the fabric-facing adapter contract plain-TS (Promise/AsyncIterable as run-handle.ts today); Effect allowed inside lane implementations (effect-acp, effect-codex-app-server, ssh, tailscale — all effect-only deps per R2 §18.2); contracts adoption forces Effect Schema at the wire boundary — the one place Effect must be allowed to appear in kradle-adjacent code.

Article source

The article body is owned directly by this record.

Related pages

No related wiki pages for this record.

Shortcuts

Open overview
Open JSON
Open graph