> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tesslate.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Projects

> A project is a working directory, a set of containers, a persistent volume, permissions, and a .tesslate/config.json graph. Everything you build on OpenSail lives inside one.

<img src="https://mintcdn.com/tesslate/VT6tbZolrCfpx26M/images/opensail-banner.png?fit=max&auto=format&n=VT6tbZolrCfpx26M&q=85&s=66579c47537b3464fb65b229cc9ab0fd" alt="Tesslate OpenSail" width="4712" height="1612" data-path="images/opensail-banner.png" />

## What a project is

A project on OpenSail is a self-contained working environment. It holds your source code, the containers that run it, a persistent volume that survives restarts, per-project permissions, and a typed graph of how everything connects.

Every project carries:

* A **slug** like `my-app-k3x8n2` that identifies it in URLs, logs, and the file system
* A **runtime** (`local`, `docker`, or `k8s`) picked per project, not per workspace
* A **visibility** flag (`team` or `private`) that governs who can open it
* A **volume** that persists files across compute shutdowns
* A **`.tesslate/config.json`** graph describing apps, infrastructure, connections, previews, and deploy targets
* A **chat history** with every agent step ever run against it

<CardGroup cols={2}>
  <Card title="Source code" icon="code">
    Your files, tracked and editable from Monaco, agents, and the terminal simultaneously.
  </Card>

  <Card title="Containers" icon="cube">
    One or more services (frontend, backend, database) wired together in a shared network.
  </Card>

  <Card title="Persistent volume" icon="database">
    btrfs-backed storage on Kubernetes, filesystem on Docker, host folder on desktop local.
  </Card>

  <Card title="Graph config" icon="diagram-project">
    `.tesslate/config.json` is the source of truth for the Architecture Panel.
  </Card>
</CardGroup>

## Anatomy of a project

A project has four pieces. All four are agent-readable and agent-writable.

<AccordionGroup>
  <Accordion icon="folder" title="Working directory">
    On Docker: `/projects/{user-id}/{project-id}`. On Kubernetes: the mounted btrfs subvolume in `proj-{uuid}`. On desktop: `$OPENSAIL_HOME/projects/{slug}-{uuid}` or a symlinked folder you adopted. The agent, the terminal, and the editor all see exactly this tree.
  </Accordion>

  <Accordion icon="cube" title="Containers">
    Every container is a row in the `Container` table and a node on the Architecture Panel. Each has a name, image, port, env vars, a startup command, and a role (base, service, external, hybrid). Containers in the same project share a network and can reach each other by DNS.
  </Accordion>

  <Accordion icon="lock" title="Permissions">
    A project-scoped permission policy gates tool calls. Shell, network, git push, file writes, and process spawning each have an `allow`, `deny`, or `ask` policy. On desktop these live in `.tesslate/permissions.json`. On the cloud they combine with team RBAC (admin, editor, viewer) and project memberships.
  </Accordion>

  <Accordion icon="file-code" title=".tesslate/config.json">
    The canonical graph. Apps, infrastructure, connections, deployment targets, previews, and canvas positions all live here. The Librarian agent writes this during setup. Humans edit it on the Architecture Panel. Agents edit it with the `apply_setup_config` tool. Never edit this file through `write_file`. Always round-trip through the schema so Container records stay in sync.
  </Accordion>
</AccordionGroup>

## Runtime per project

Every project picks its own runtime. The same desktop app can run one project locally with no containers while another runs in your production Kubernetes cluster.

<Tabs>
  <Tab title="Local">
    Subprocesses on the host machine. No Docker, no cluster, fastest cold start. Good for single-service prototypes and scripts. Uses `services/orchestration/local.py`.
  </Tab>

  <Tab title="Docker">
    Docker Compose on your machine. Full container isolation, Traefik routing at `{container}.localhost`, shared volumes between services. Good for multi-service apps you still want to run locally.
  </Tab>

  <Tab title="Kubernetes">
    Full cloud runtime. Per-project namespace (`proj-{uuid}`), btrfs CSI volume, NGINX Ingress, VolumeSnapshot timeline, three-tier compute with hibernation. Good for anything you want to share, scale, or leave running while your laptop is closed.
  </Tab>
</Tabs>

<Info>
  The runtime is a column on the `Project` model. `get_orchestrator(project=project)` dispatches to the right backend. You can switch runtimes, but it requires a restart and may involve a file sync.
</Info>

## Three-tier compute

Kubernetes projects live on a tiered model so idle workspaces cost almost nothing.

| Tier       | What runs here                                                        | Cost profile                     |
| ---------- | --------------------------------------------------------------------- | -------------------------------- |
| **Tier 0** | File reads, web fetches, agent reasoning, most tool calls             | Near zero, no compute pod        |
| **Tier 1** | Shell commands via a warm ephemeral pool                              | Instant execute, returns to pool |
| **Tier 2** | Full project namespace with live preview and long-running dev servers | On-demand, hibernates when idle  |

About 99 percent of agent operations stay in tiers 0 and 1. Tier 2 starts when you click Start or open a preview, and it hibernates (volume-level) after a configurable idle window.

## Visibility and access

Projects are either `team` (inherits team RBAC) or `private` (owner-only). A team admin sees every team-visible project. A team editor can edit them. A team viewer can open them. Project-level overrides (`ProjectMembership`) let you grant or tighten access per user.

Every significant action writes to an append-only audit log keyed by team and project.

## Lifecycle

<Steps>
  <Step title="Create">
    `POST /api/projects` creates the row, allocates a slug, and runs `_perform_project_setup` in the background. Setup clones the template or git repo, writes files to the volume, and syncs `.tesslate/config.json`.
  </Step>

  <Step title="Configure">
    The Librarian agent inspects the tree and writes `.tesslate/config.json`. You can also hand-edit on the Architecture Panel or during the setup wizard.
  </Step>

  <Step title="Start">
    `POST /api/projects/{slug}/start` boots containers. On Kubernetes, it ensures the namespace, PVC, and file-manager pod, then creates Deployments, Services, and Ingress rules.
  </Step>

  <Step title="Build">
    Agents and humans edit files, run commands, and iterate. The preview hot-reloads. Steps persist progressively.
  </Step>

  <Step title="Hibernate">
    After the idle window, the whole volume is snapshotted and compute torn down. Files are intact.
  </Step>

  <Step title="Restore">
    Open the project and compute resumes from the snapshot. Same files, same containers.
  </Step>
</Steps>

## How agents see a project

The agent receives a structured context on every run: project info, git status, the current `.tesslate/config.json`, open chat history, attached skills, and a live file tree. It writes through the same file API you use, so its edits and yours converge on the same checkout. When it changes infrastructure, it calls `apply_setup_config`, which validates startup commands, upserts Container rows, replaces connections, and writes the config file in one transaction.

<Info>
  See the source at [orchestrator/app/routers/projects.py](https://github.com/TesslateAI/opensail/blob/main/orchestrator/app/routers/projects.py) for the full lifecycle API.
</Info>

## Related

<CardGroup cols={2}>
  <Card title="Workspaces" icon="layer-group" href="/guides/workspaces">
    Fork, snapshot, and share a project's full environment.
  </Card>

  <Card title="Architecture Panel" icon="diagram-project" href="/guides/architecture-panel">
    Visual editor for `.tesslate/config.json`.
  </Card>

  <Card title="Creating Projects" icon="plus" href="/guides/creating-projects">
    Template, import, describe.
  </Card>

  <Card title="Agents" icon="robot" href="/guides/agents">
    How the agent runner drives projects.
  </Card>
</CardGroup>
