Skip to content

Outbound ports

Outbound ports (core/ports/outbound/*.ts) define the contracts that adapters implement: file I/O, HTTP, database, secrets, events, chat runtime, etc. This is the “driven” surface of the hexagonal core.

Source of truth: core/ports/outbound/.


Each port is a pure TypeScript interface. The core never knows the concrete implementation — it always receives an instance that satisfies the interface, provided by composition.

core/ports/outbound/filesystem.ts
export interface Filesystem {
read(path: string): Promise<string>;
readJson<T = unknown>(path: string): Promise<T>;
writeJson(path: string, value: unknown): Promise<void>;
exists(path: string): Promise<boolean>;
rm(path: string, options?: { recursive?: boolean }): Promise<void>;
// ...
}

The concrete adapter (adapters/outbound/filesystem/fs-filesystem.ts) implements the interface. For tests, an InMemoryFilesystem or a fake also satisfies the contract.


The main outbound ports shipped, grouped by responsibility.

  • clock.ts — clock (now())
  • id-generator.ts — stable ID generation
  • filesystem.ts — local file read/write (with allowlist)
  • arka-home.ts — resolution of the ~/.arka-deck/ folder
  • event-bus.ts — typed in-process event bus
  • checksum-computer.ts — checksum computation (files, artifacts)
  • chat-session-store.ts — chat sessions (SQLite)
  • chat-attachment-store.ts — session attachments
  • agent-action-card-store.ts — agent action cards
  • arkadoc-store.ts, arkadoc-manifest-store.ts, arkadoc-file-activity-store.ts — project documents
  • catalogue-cache.ts — Cortex catalogue cache
  • connector-execution-store.ts, connector-installation-store.ts, connector-action-grant-store.ts — external connectors
  • catalogue-client.ts — HYOS profiles from the public Cortex
  • catalogue-blocs-client.ts — blocs from Cortex
  • arkadoc-cortex-client.ts — ArkaDoc sync with Cortex
  • atoms-client.ts — Cortex atoms
  • cortex-lite-materialization-source.ts — project materialization source
  • chat-runtime.ts — LLM turn execution (streaming)
  • before-turn-augmenter.ts — context injection before a turn
  • agent-identity-context-client.ts — agent identity context
  • agent-workspace-materializer.ts — agents materialized as local files
  • connector-registry.ts — external connectors registry
  • secret-cipher.ts — encryption/decryption (AES-256-GCM default)

PrefixFamilyUsage
Fs*FilesystemLocal file read/write
Sqlite*SQLiteRelational local storage
Http*HTTPPublic Cortex or Cortex Lite clients
InMemory*In-memoryTests, fakes

Each port has at least one production implementation and a testable fake.


  • You need a new external dependency (new service, new data source).
  • Several implementations may exist (e.g. Fs* + Http*).
  • The interface must be mockable for tests.

Avoid creating ports for pure utilities (computation, formatting) — keep them in core/_shared/ or in the domain.