# d6e Design Philosophy

日本語版: [design-philosophy.ja.md](./design-philosophy.ja.md)

This document explains the design principles behind d6e. It is written for
developers and architects who are deciding how much of their system should
depend on d6e — and how much should not. Everything described here reflects
the actual implementation, not aspirations.

## What d6e is

d6e is a self-hostable AI work platform. An **instance** is deployed into
your own environment (on-premise or private cloud) and hosts **workspaces**.
A workspace bundles the things an AI agent needs to do real work:

- a PostgreSQL-backed workspace database
- file storage (uploads, generated reports, Google Drive sync)
- STFs (State Transition Functions — your business logic)
- workflows and schedules
- SaaS credentials (freee, Money Forward, Google Workspace, Salesforce,
  Notion, Box, GitHub, Chatwork, Zendesk, ...)
- a chat console where the AI agent operates on all of the above

The central account site (https://www.d6e.ai) only handles accounts, login,
and OAuth client registration. Your data lives in your instance.

## Background: why loose coupling?

Fat frameworks are fast at first and expensive later. When features are
tightly coupled to the framework, replacing the framework becomes a
breaking change for everything built on it — this is how frameworks turn
into technical debt.

AI-assisted development changes the trade-off. You no longer need a fat
framework to move fast; a loosely coupled platform plus composable,
standard parts is now fast *and* keeps your options open. d6e is
deliberately designed to stay loosely coupled to the systems you already
own: it should host your work, not absorb your system.

The principles below are the concrete form of that intent.

## Principle 1: Your data and AI stay in your environment

The instance — API, database, file storage, agent runtime — runs on
infrastructure you control. Workspace data is not sent to d6e-operated
servers. The central site never sees workspace contents; it only brokers
authentication.

## Principle 2: Everything is a public API

There is exactly one API surface. The d6e console (the built-in web UI) is
a client of the same public REST API (`/api/v1/*`) that you can call with
an API key. The instance's MCP server exposes the same tools the built-in
chat agent uses — roughly 90 `d6e_*` tools covering SQL, files, Drive,
SaaS calls, STF execution, and workflow management.

Practical consequences:

- Anything the console can do, your scripts, backends, and custom
  frontends can do.
- Your local AI coding agent (Codex CLI, Claude Code, Cursor, ...) can
  connect to the instance MCP server and develop against the real
  workspace with tool-for-tool parity with the hosted agent. There is no
  separate SDK to learn.
- Custom frontends are ordinary web apps. They authenticate users via
  standard OAuth2 (authorization code flow) and then call the instance
  API. They are not built "inside" d6e.

## Principle 3: Portable assets, loose coupling

The things you build on d6e are deliberately kept in formats that survive
outside d6e:

| Asset | Format | Portability |
|---|---|---|
| JS STF | Plain JavaScript: read the `$input` value, `return` a JSON-serializable result | A pure function. No d6e SDK, no imports required |
| Docker STF | Any container image: JSON on stdin, `{"output": ...}` on stdout, errors on stderr | Runs anywhere Docker runs; d6e-agnostic |
| Effect | A declarative HTTP call (URL, method, header/body/query mappings) | Re-expressible in any HTTP client in minutes |
| Prompts | Markdown | Copy-paste portable |
| Workspace DB | Plain PostgreSQL (`user_data` schema) | Standard SQL; dump and restore with standard tooling |
| Files | Regular files with paths | Download or sync out at any time |
| Custom frontend | An independent web app you own and deploy | Already outside d6e |
| Plugin | `template.yaml` + the files above, in a plain git repository | Human-readable declaration of all of the above |

What d6e itself provides is the **glue**: authentication, workspace
membership, credential storage, policy enforcement, audit logging,
scheduling, and orchestration. The glue is the part you would rewrite if
you ever migrated to another platform — your logic, data, and prompts move
as-is. Migration cost is bounded to the glue, and that is by design.

## Principle 4: Adopt incrementally

d6e does not require a big-bang adoption. A typical path:

1. **Console only** — deploy an instance, upload data, let the team work
   with the AI agent in chat.
2. **Harden the instructions** — recurring procedures move from ad-hoc
   chat into prompt files, then into `files:` references, then into STFs
   and workflows where reproducibility matters.
3. **Package as a Plugin** — a `template.yaml` bundles prompts, files,
   STFs, effects, and workflows so other workspaces (or other companies)
   can install the same capability in one click.
4. **Custom frontend** — when a task deserves a dedicated UI, build a
   normal web app against the public API. The workspace stays the system
   of record; the frontend stays yours.

Each step is optional. Stopping at any step leaves you with a working
system.

## Principle 5: Governance at the boundary

Because every consumer goes through the same API, controls are enforced in
one place:

- **Table policies, deny by default** — access to workspace tables is
  denied unless an allow policy matches; deny policies are evaluated
  first. This applies equally to the console, the agent, MCP clients, and
  API-key callers.
- **Audit logs** — workspace operations are recorded and reviewable.
- **Usage analytics** — token consumption is tracked per model, user, and
  request type, so cost is visible before it is a surprise.
- **Encrypted credential storage** — SaaS credentials and STF secrets are
  stored encrypted server-side. STF secrets are write-only through the
  API (admin-only) and are injected into containers at run time; agents
  and plugin authors reference them by name (`__SECRET_REF_ONLY__`), never
  by value.

## The dependency boundary

A short rule of thumb for what belongs where:

**Put in d6e: the state the AI operates on, and the credentials it uses.**

- Workspace tables the agent reads and writes
- Files the agent produces and consumes
- SaaS connections the agent operates on your behalf
- STFs/workflows that must run reproducibly next to that data

**Keep outside d6e: everything you already own.**

- Your frontend (any framework, any host)
- Your backend — API routes, workers, servers. d6e does not ask you to
  move server-side logic into it; call d6e's API from your backend where
  useful, and call your own services directly where not.
- External databases and systems of record. The workspace SQL surface
  (`d6e_sql`) is intentionally restricted to the instance's own
  `user_data` schema — d6e will not silently become a client of your
  production database. When the agent must touch an external system, do
  it explicitly: a Docker STF (containers run with network access,
  credentials injected from STF secrets) or an Effect. You integrate the
  boundary; you do not migrate the database.

## Related resources

- Frontend and instance relationship:
  https://github.com/d6e-ai/d6e-custom-frontend-skills/blob/main/docs/frontend-and-instance.md
- Local AI agent development guide:
  https://github.com/d6e-ai/d6e-plugin-skills/blob/main/docs/local-ai-development.md
- Plugin development (template.yaml spec, skills):
  https://github.com/d6e-ai/d6e-plugin-skills
- Docker STF development:
  https://github.com/d6e-ai/d6e-docker-stf-skills
- Custom frontend development:
  https://github.com/d6e-ai/d6e-custom-frontend-skills

---

Last updated: 2026-07
