Ctrl K
ComunidadGuías…

README.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Gantry

**Onboard AI employees like real ones.** Give them a seat in Teams or Slack,
only the access they need, a full audit trail, and offboarding in one command.
Self-hosted, any model.

Gantry is the open-source runtime that lets IT onboard AI agents the way it
onboards people — provision a seat in the channels where the team already works
(or inside your own product via SDK and API), grant scoped access, log every
action, revoke in one command. It gives agents a controlled host process,
durable state, approved tools, channel adapters, memory, and audit records
without tying application code to one model provider or chat surface.

Gantry is not a chatbot wrapper and not a personal assistant that staff install
on their own laptops. It is the runtime boundary between:

- human channels such as Slack, Microsoft Teams, Telegram, Discord, and
  web/SDK clients;
- application events, SDK calls, and scheduled jobs;
- approved tools, local CLIs, browser automation, skills, and MCP servers;
- Postgres-backed runtime state, artifacts, settings, credentials, and audit.

What that buys a team in practice:

- **Governed autonomy.** Capability grants, declarative per-agent `tool_rules`,
  an optional LLM auto-permission mode that relieves prompt fatigue without
  ever writing policy by itself, and one-tap durable approvals — every
  decision audited.
- **Fleet operations.** Multiple agents across conversations and channels,
  scheduled jobs with delivery guarantees, sandboxed worker and lightweight
  inline runtimes, and versioned desired-state settings.
- **Developer surface.** A typed Node SDK generated from the OpenAPI doc,
  lifecycle webhooks, a `/v1/usage` API, a provider-shaped direct LLM API, and
  runnable NestJS/Next.js examples.
- **Institutional memory.** Per-agent and shared memory with review flows, so
  what agents learn stays inspectable and survives model or provider swaps.

## Detail Documentation

- [Product brief](docs/product/BRIEF.md)
- [Architecture docs](docs/architecture/README.md)
- [Decision records](docs/decisions/README.md)
- [SDK docs](docs/sdk/overview.md)
- [Deployment docs](docs/deployment/aws-terraform.md)

## Status

This repository is being prepared as an open-source project. The intended npm
package shape is:

- `@gantry/runtime` for the runtime and `gantry` CLI binary
- `@gantry/sdk` for the Node.js SDK
- `@gantry/contracts` for shared TypeScript contracts

Until the first public package publish, build and run from source.

## Requirements

- Node.js `>=24 <26`
- npm
- Postgres for runtime state
- `ripgrep`
- For `sandbox_runtime` on Linux: `bubblewrap` and `socat`

Ubuntu prerequisites:

```bash
sudo apt update
sudo apt install -y ca-certificates curl git libatomic1 bubblewrap socat ripgrep
```

## Quick Start From Source

```bash
git clone https://github.com/knacklabs/Agent.Gantry.git
cd Agent.Gantry
npm ci
npm run dev
```

Use Node 24 and npm (not pnpm). `dev` starts/reuses local Postgres, applies all
migrations, runs core from TypeScript and serves the Web UI through Vite with
hot reload. The SDK is a client library, not another process. The ready UI link
is printed in the terminal. No built `dist/ui` assets are used.

Source-local commands:

```bash
npm run dev        # start the complete source development stack
npm run dev:doctor # verify Node, Docker and Docker Compose without changing state
npm run reset:db   # reset database schemas, preserve files, restart
npm run reset      # reset database and known runtime state, restart onboarding
npm run reset:only # reset database and known runtime state, then exit
npm run dev:stop   # stop core, Vite and this home's managed Postgres
npm run dev:core   # core only (requires an already configured database)
```

The equivalent CLI commands are `gantry local start`, `gantry local doctor`,
`gantry local reset-db`, `gantry local reset`, `gantry local reset --no-start`,
and `gantry local stop`, when the CLI is built/linked from this checkout. Without a build, use
`npm run cli:dev -- local <command>` after `npm run build:contracts`. Run these
from the source checkout.

Local development defaults to `<repo>/.gantry`, **not** `/gantry` or `~/gantry`.
Its `.env` is created securely there with local defaults and a generated
encryption key. Existing values are preserved. An exported `GANTRY_HOME` or
`--runtime-home` overrides the default directly:

```bash
export GANTRY_HOME="/absolute/path/to/my-gantry-dev"
npm run dev
```

Environment variables override `<GANTRY_HOME>/.env`. Set `GANTRY_CONTROL_HOST`
(loopback only) and `GANTRY_CONTROL_PORT` (default `3939`) to choose the public
UI origin. Existing `authentication.canonical_origin` must match it; startup
prints the exact correction if it does not. After each healthy local start or
reset, startup prints a fresh short-lived one-time authorization link; existing
browser sessions remain valid. If link issuance fails, run `gantry ui authorize`
to retry.

Reset commands run **without confirmation** and print the target first. Only a
loopback database named `gantry` may be reset. `reset:db` recreates the `gantry`
and `pgboss` schemas and reapplies every migration. Full reset also removes
settings, onboarding state, agents, data, store, logs, artifacts and runtime
projections. Both preserve `.env`, `postgres/` and unknown files. Stop other
database clients before resetting.

Ctrl-C stops core and Vite but keeps Postgres warm. `dev:stop` also stops the
verified home-owned `gantry-postgres` container, without deleting its data.
Custom databases and unrelated containers are never stopped. Docker must be
running for Gantry to manage its default Postgres container; an unreachable
custom URL is reported rather than replaced.

Production/bundled startup remains unchanged:

```bash
npm run build
npm start
```

## Runtime Configuration

Runtime home defaults to `~/gantry` unless `GANTRY_HOME` or `--runtime-home` is
set. Human-readable settings live in `~/gantry/settings.yaml`; the durable
desired-state authority is the latest Postgres `settings_revisions` row.

Runtime secrets belong in `<GANTRY_HOME>/.env` or a runtime secret provider.
Model/provider credentials must be configured through Gantry credentials and
the Gantry Model Gateway. Do not pass raw model provider keys directly to agent
processes.

Common local commands:

```bash
gantry setup
gantry doctor
gantry status
gantry start
gantry stop
gantry restart
gantry logs
gantry model list
gantry provider list
gantry settings validate
```

Bundled runtime surfaces:

- `/commands` is host-managed command help, not an SDK skill folder.
- `gantry-admin` is the maintainer skill for local runtime administration.

## Execution Surfaces

Gantry exposes three ways to run model work, all under the same permission,
credential, and audit authority:

- **Worker agents** (`runtime: worker`, the default) run in a sandboxed
  subprocess with the full reviewed capability projection: filesystem, shell,
  skills, browser automation, and stdio MCP servers.
- **Inline agents** (`runtime: inline`) run the provider loop in the Gantry
  host process for lightweight chat-style workloads: core tools, remote
  `http`/`sse` MCP servers, subagent delegation, scheduled jobs, per-agent turn
  caps, and per-message structured output (`response_schema`).
- **Direct LLM API** (`POST /llm/v1/messages`, `POST /llm/v1/chat/completions`)
  is a provider-shaped passthrough for raw model calls with Gantry-held
  credentials — point an official Anthropic or OpenAI SDK at Gantry via its
  `baseURL` option and authenticate with a Control API key holding
  `llm:invoke`.

See [docs/architecture/capability-management.md](docs/architecture/capability-management.md)
for runtime tiers and the LLM API contract.

## SDK

The Node SDK talks to the Control API over a Unix socket or HTTP endpoint.

```bash
npm i @gantry/sdk
```

```ts
import { createClient } from '@gantry/sdk';

const client = createClient({
  apiKey: process.env.GANTRY_CONTROL_API_KEY!,
  baseUrl: 'http://127.0.0.1:3939',
});

const health = await client.health();
console.log(health.status, health.processRole);
```

See [packages/sdk](packages/sdk/README.md) and
[examples/control-api-local](examples/control-api-local/README.md).

## Security Model

Gantry treats model output, provider SDKs, workers, browser backends, MCP
servers, and local tools as untrusted execution surfaces. Risky tool execution
passes through Gantry-owned permission policy, sandbox policy, credential
brokering, and audit.

Public deployments should expose only the routes they need:

- `/v1/*` is the authenticated Control API and should be restricted to trusted
  admin or application networks.
- `/webhooks/*` is for provider webhook ingress when enabled.
- `/healthz`, `/readyz`, and `/metrics` are operational endpoints and must stay
  internal.

For details, read [docs/SECURITY.md](docs/SECURITY.md) and
[docs/architecture](docs/architecture/README.md).

## Development

Tests and harnesses live outside production source trees:

- `apps/core/test/unit/**`
- `apps/core/test/integration/**`
- `apps/core/test/e2e/**`
- `apps/core/test/harness/**`
- `packages/contracts/test/unit/**`

Common checks:

```bash
npm run format:check
npm run lint
npm run typecheck
npm test
npm run build
npm run security:package
```

Postgres-backed integration tests require a disposable Postgres database via
`GANTRY_TEST_DATABASE_URL`; do not run them against a developer's persistent
runtime database.

### Postgres migrations

Change the Drizzle schema, then generate a timestamped migration and review its
SQL before committing:

```bash
npm run db:migrations:generate -- --name add_feature
```

For data migrations or SQL Drizzle cannot generate, use a custom migration:

```bash
npm run db:migrations:custom -- --name backfill_feature
```

Run `npm run db:migrations:check` locally. After rebasing overlapping schema
work, regenerate and resolve any Drizzle conflicts. CI also verifies that a
clean schema produces no uncommitted migration files. Runtime deployments
continue to apply migrations with `npm run db:migrate`.

## Contributing

Read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request. Keep
changes small, current-behavior focused, and backed by the smallest relevant
checks.

## License

MIT. See [LICENSE](LICENSE).

## Working in this repo — Forge

This repo runs on [Forge](https://github.com/knacklabs/symphony-forge) v1, which
takes each change from an approved plan to a merged pull request. Open an agent
session (Claude Code or Codex) in the repo root, then:

- **Run `forge next` whenever you are unsure.** It says where things stand and
  gives the exact next command.
- **Changes arrive as stories or fixes.** A story is one short doc that gets one
  cold read and one human approval, then runs task by task; a small change is a
  fix. `AGENTS.md` has the rules, `forge.toml` the settings.
- **Humans approve and merge.** Agents plan, build and review; approving a story
  and merging its pull requests stay with people.

The old copied-in Forge is history: see
[0002 Symphony Forge adoption](docs/decisions/0002-symphony-forge-adoption.md) and
[0093 client sign-off gate](docs/decisions/0093-client-signoff-is-a-pinned-project-gate.md),
both superseded.