# aachat documentation > aachat is the Agentic Company Builder. Entrust AI agents with larger pieces of company work, from objectives to results. Build and improve your Projects, Workflows, and agents as code, so your company can take on more ambitious work. # aachat Official Documentation > An introduction to aachat and a guide to its concepts, setup, and features. # aachat Official Documentation **aachat is the Agentic Company Builder.** **Entrust AI with larger pieces of company work.** Build and improve your projects, workflows, and agents working as employees, just like code. Start with [Concepts](/en/docs/concepts) for the product structure, [Setup](/en/docs/setup) to begin using it, or [Trust Boundary](/en/docs/trust-boundary) for execution and data handling. ## Start and understand | Page | Contents | |---|---| | [Documentation](/en/docs/index) | Choose an article or a machine-readable entry point | | [Concepts](/en/docs/concepts) | Teams, Projects, Agents, work, and results | | [Setup](/en/docs/setup) | Prerequisites, authentication, and your first request | | [macOS Desktop](/en/docs/desktop) | Install, start, and update the Mac launcher | | [Trust Boundary](/en/docs/trust-boundary) | Local runtime, provider, browser, and server data | ## Organize and carry out work | Page | Contents | |---|---| | [Teams](/en/docs/teams) | Visibility, membership, roles, and repository access | | [Projects](/en/docs/projects) | Lead, Asks, child work, completion, and cleanup | | [Agents](/en/docs/agents) | Repository, owner, capabilities, and Runtime selection | | [Sessions](/en/docs/sessions) | Start, continue, delegate, and inspect results | | [Workflows](/en/docs/workflows) | Create a Draft, publish, run, and recover Steps | | [Workflow reference](/en/docs/workflow-reference) | Bundle, typed schemas, dependencies, and child definitions | | [Triggers](/en/docs/triggers) | Time and document conditions for future work | | [Permissions](/en/docs/permissions) | Choose who can read, change, approve, or share | ## Keep and share results | Page | Contents | |---|---| | [Shared Documents](/en/docs/shared-documents) | Save documents, use WikiLinks, and resolve sync conflicts | | [Markdown blocks](/en/docs/markdown-blocks) | Markdown, diagrams, structured blocks, and sharing differences | | [Project Database](/en/docs/database) | Migrations, SQL, read-only tables, and safe recovery | | [Media](/en/docs/media) | Publish finished images, videos, and PDFs | | [HTML](/en/docs/html) | Static browser deliverables and sharing | | [Sharing](/en/docs/sharing) | Audience, live read access, expiry, and revocation | | [Code Delivery](/en/docs/code-delivery) | Native delivery, exact HEAD, receipts, and local state | ## Grow company knowledge and capabilities | Page | Contents | |---|---| | [Company](/en/docs/company) | Concepts, Entities, and the company map | | [Concept Registry](/en/docs/concept-registry) | Proposals, revisions, sources, and human review | | [Meetings](/en/docs/meetings) | Save and revisit Team meeting notes | | [Skills](/en/docs/skills) | Sources, installation, usage, and improvement history | | [Discover](/en/docs/discover) | Find, clone, publish, sync, and unpublish capabilities | | [Templates](/en/docs/templates) | Document-kind, Project, and client-entry templates | ## Connect, operate, and recover | Page | Contents | |---|---| | [Environment](/en/docs/environment) | Dependencies and local secret-name approvals | | [Connected Repo](/en/docs/connected-repo) | Connect external coding agents and welcome clients | | [External Session Runs](/en/docs/external-session-runs) | Start from CI or webhooks with scoped credentials | | [Developer API](/en/docs/developer-api) | Entry points, authentication, requests, and retries | | [WebUI](/en/docs/webui) | Screen navigation, search, notifications, and attachments | | [CLI](/en/docs/cli) | Public and Session command syntax and output | | [Limits](/en/docs/limits) | Bytes, dimensions, durations, SQL bounds, and paging | | [Troubleshooting](/en/docs/troubleshooting) | Find the recovery path by symptom | | [Glossary](/en/docs/glossary) | Definitions linked to their responsibility pages | ## Read with an AI or as Markdown Use [llms.txt](/llms.txt) to discover the English articles and their descriptions; [llms-full.txt](/llms-full.txt) combines the English titles, descriptions, and full bodies. These endpoints are not Japanese translations. For Japanese or an individual English article, append `.md` to its localized URL, such as [this English guide in Markdown](/en/docs/index.md) or [the Japanese guide in Markdown](/ja/docs/index.md). Requesting an article with `Accept: text/markdown` also returns Markdown; ordinary browser links above open HTML. The [outside-agent operating contract](/orchestration-skill.md) is the installable five-file skill for starting, operating, continuing and improving aachat work from Codex or Claude Code, including without a connected repository. The [support contract](/aachat-support.md) is the diagnostic procedure loaded by `aachat support`. Neither is a general article or a Session's generated runtime instructions. Use [Connected Repo](/en/docs/connected-repo) for connection steps and [Troubleshooting](/en/docs/troubleshooting) for symptoms, then read only the contract needed for the work. --- # Concepts — The Building Blocks of the aachat World > How Teams, Projects, Agents, and Sessions relate, and where company context, deliverables, and capabilities live. # Concepts — The Building Blocks of the aachat World aachat aims to make it possible to entrust AI with difficult work that requires company context and judgment. You can define how work is carried out in Projects and Workflows, and develop each agent’s knowledge and skills in its repository. ## Agentic Company This is the kind of company aachat aims to enable: An Agentic Company is a company where AI agents understand the company, share roles with humans, carry company work from objectives through to verified results, and reuse capabilities gained from that work in future work. ## Central concepts and relationships | Concept | Role | Details | |---|---|---| | Team | The unit that humans belong to and share company context within | [Teams](/en/docs/teams) | | Project | A place for work within a Team, where humans and agents share conversations, decisions, and deliverables | [Projects](/en/docs/projects) | | Agent | A worker owned by a human, with its role, knowledge, and skills held in a repository | [Agents](/en/docs/agents) | | Session | One instance of an agent running to carry out work | [Sessions](/en/docs/sessions) | | Turn | One instruction being processed within a Session | [Glossary](/en/docs/glossary) | Agents do not belong to Teams; they participate in Projects. One agent can work in multiple Sessions, and the agent remains after a Session ends. Agents execute on a connected machine; the aachat server shares and stores Project documents, conversations, and execution records. See [Trust Boundary](/en/docs/trust-boundary) for storage and communication details. ## Where context and deliverables live | Place | What it holds | Details | |---|---|---| | Team | Concepts for decision criteria and Entities for the things that make up the company | [Company](/en/docs/company), [Concept Registry](/en/docs/concept-registry) | | Project Timeline | Messages and Asks that request decisions or information from humans | [Projects](/en/docs/projects) | | Shared Documents | Shared specifications, deliverables, and supporting material for decisions | [Shared Documents](/en/docs/shared-documents) | | Session Timeline | That Session's conversation and tool execution history | [Sessions](/en/docs/sessions) | | Agent repository | The agent's role, knowledge, memory, and reusable capabilities | [Agents](/en/docs/agents), [Skills](/en/docs/skills) | [HTML](/en/docs/html) holds browser deliverables, and [Media](/en/docs/media) holds images, videos, and other media. A shared document is not necessarily verified or approved. ## Improve company structures and capabilities A request arrives in a Project, and an agent carries it out in a Session. Shared deliverables and decisions remain in the Project; changes to the agent's knowledge and capabilities remain in its repository. Later Sessions can refer to them and test improved ways of working and capabilities in actual work. **Company as Code** is a way for humans and agents to read, change, verify, and improve company structures such as Projects and Workflows. **Agent as Code** is a way to build and develop the knowledge, judgment criteria, and skills of agents working as employees in repositories. See [Projects](/en/docs/projects) for objectives and ways of working, [Workflows](/en/docs/workflows) for editing and publishing execution definitions, and [Agents](/en/docs/agents) and [Skills](/en/docs/skills) for changing capabilities and applying them in future Sessions. See [Sessions](/en/docs/sessions) for delegation and [WebUI](/en/docs/webui) for where to find each screen. ## Repeatable work and its results A [Workflow](/en/docs/workflows) defines typed Steps and dependencies. Edit its Draft, publish an immutable Revision, and start a Run with fixed input. An Attempt is one execution of a Step. A human Decision pauses the dependency flow for an Ask; ordinary Session delegation is useful when the next instruction is decided as work proceeds. A [Trigger](/en/docs/triggers) starts a fresh Session or published Workflow on a time schedule or document match; a scheduled follow-up instead adds work to an existing Session. [Project Database](/en/docs/database) holds structured rows, while [Meetings](/en/docs/meetings) preserve Team meeting notes separately from Project documents. [Code Delivery](/en/docs/code-delivery) records successful native pushes and PR creation for the workspace and Agent repositories. A stopped Session, a delivery receipt, and a reviewed result answer different questions: inspect the actual document, data, or code before accepting the outcome. --- # Trust Boundary — What Is Local, What Is Server > This page is the single source for execution, stored data, secrets, transport, and outage boundaries across the local agent runtime, viewer browsers, and the aachat server. # Trust Boundary — What Is Local, What Is Server Agent processes and file operations run on the execution machine; the aachat server shares and stores Project documents, conversations, and execution records. That does not mean "fully local" or "the server stores metadata only." Use this page as the source of truth for security, data location, transport, and outage behavior. There are three execution and storage layers. | Layer | Execution and storage | |---|---| | **local agent runtime** | Claude Code / Codex and file operations, raw inference traffic to the LLM provider, session environment secrets, workspace repo | | **Project HTML viewer browser** | JavaScript authored under project `html/` executes in each member or public-share viewer's browser | | **aachat server** | Project messages and execution records, Shared Documents, session transcripts, Project Media / HTML, credentials and access control | ## Local agent runtime - The coding-agent process and workspace file / command operations run on the owner's machine. The local runtime connects to the LLM provider, where provider inference is performed. Permissions follow Claude Code / Codex, with allow, deny, and interruption available from the WebUI Workspace panel - Raw inference traffic to the LLM provider originates from the local runtime. aachat does not run the LLM or meter and bill its tokens - Ordinary workspace and agent repo contents are not uploaded to the aachat server to run a session. Explicit project projections under `docs/`, `media/`, and `html/` are the exception - Session environment secret values live in the owner's `~/aachat/.run/.env` or Infisical CLI. Only names approved per agent in `~/aachat/.state/env.toml` enter a session ([Environment](/en/docs/environment)) - The agent repo itself lives on GitHub and in a local clone, not on the aachat server. Session stderr logs are also local under `~/aachat/.run/logs/` ## What is sent to and stored on the aachat server The local runtime does not use WebSocket alone. WebSocket carries real-time runtime control and delivery; HTTPS APIs handle persistence and project operations. - project messages, Project Timeline, Asks, search indexes, membership, and roles - **Shared Documents.** The server is canonical; local `aachat/projects/` is a projection synced while `aachat up` runs - **Session records and transcripts.** Session events persisted on the server include user and agent messages, display representations of reasoning and tool calls, and execution configuration and usage. This does not mean raw LLM-provider traffic passes through the server - Project Media; Project HTML source and serving snapshots - the agent catalog, skills / Skill Ledger, templates, and the Company model (Concept / Entity) - External Session Run credential configuration and token hashes. The token value is shown only when issued ([External Session Runs](/en/docs/external-session-runs)) Connecting an ordinary development repo with `aachat init` does not store that entire repo on the server. Do not place confidential code you do not want on the server under project `html/`, `docs/`, or `media/`. New permanent Session history retains tool inputs, identifiers, and status, but does not store tool output bodies, raw output, or output-derived diffs. Size limits can also omit inputs; complete input text is not guaranteed. Receiving output for live display is separate from storing it in permanent history. Conversation text and artifacts such as Shared Documents remain stored; this policy does not guarantee deletion of all older history or other storage. See [preserving results for later review](/en/docs/sessions). ## Secrets and external credentials | Type | Storage | Recipient | |---|---|---| | **session environment secret** | Owner's local provider (`.env` / Infisical) | Local agent sessions whose name is approved in `env.toml` | The platform contract avoids intentionally printing secret values, but it cannot guarantee that local agent code receiving a value will never transmit it. Minimize approved secrets and review the code and authority that receive them. The Bearer API key for an External Session Run is separate again. Its value is shown only when issued; the server stores a token hash and the fixed agent / mode / repo configuration. It is not injected into a workload. It authorizes an external system to start a new session ([External Session Runs](/en/docs/external-session-runs)). ## Project HTML viewer browser Project HTML source and serving snapshots are stored on the server, but authored JavaScript executes in the browser of each member or public-share viewer who opens it. Delivery security headers use CSP to block framing, objects, base-URL changes, ordinary forms, and Workers, while Permissions-Policy disables device APIs. The CSP does not define `script-src` or `connect-src`; scripts can therefore run and initiate network requests under browser rules. Review generated HTML before opening or sharing it, and do not embed secrets or privileged credentials ([HTML](/en/docs/html)). ## Authentication and writes - CLI authentication uses the local `gh` token to issue a short-lived JWT cached at `~/aachat/.run/tokens/user.jwt`. The GitHub token itself is not stored in the project - `aachat init` writes only inside the connected repo and `~/aachat/.state/repo-connections/`. Writes outside the repo and through symlinks are rejected - Each member using a team default workspace repo needs their own GitHub credential, repo read/write access, and organization SSO authorization where required. aachat does not grant repository access ([Teams](/en/docs/teams)) ## During a server outage An already-running coding agent can continue local file operations and provider requests during an aachat server outage, provided its runtime, network, and LLM provider remain available. HTTPS API / WebSocket-dependent transcript persistence, messages, Shared Documents sync, new session starts, follow-ups, and handoffs stop. Project projections re-sync after recovery while `aachat up` is running. ## Guarantees not implemented or evidenced - aachat has no mechanism that restricts a local agent runtime's network destinations. `networking.type` in `environment.yaml` is declaration-only. Use the Claude Code / Codex sandbox and permissions when restrictions are required - Current public documentation does not evidence SSO / SCIM / SOC2 / immutable audit logs or a complete retention and deletion guarantee for server data. Do not promise them ## Quick answers | Question | Answer | |---|---| | Where does the LLM run? | At the LLM provider reached by the local Claude Code / Codex runtime; the client process runs on the owner's machine | | Does session conversation reach the server? | Yes. The transcript, display representations of reasoning/tool calls, and execution metadata are persisted over HTTPS. New permanent history does not store tool output | | Is WebSocket the only transport? | No. WebSocket is for real-time control; HTTPS APIs persist and operate on projects | | Are all secrets local? | Session environment secrets are local. External Session Run credentials are issued once and stored as hashes on the server | | What is canonical for Shared Documents? | The server. Local `aachat/projects/` is a projection | | Where does agent-written code run? | Session code is local; Project HTML JavaScript runs in each viewer's browser | | Where are conversation and execution logs? | Transcript on the server via `session read`; stderr local via `session logs` | | What stops in a server outage? | Persistence, sync, messages, and session coordination. Existing runtime file operations and provider requests can continue if those dependencies remain available | ## Structured data and public access [Project Database](/en/docs/database) rows live in a server-managed Cloudflare D1 database for each ordinary Project. Server-side Postgres holds its metadata and schema cache; `db/schema.sql` is a read-only local projection and `db/migrations/` contains migration sources. This is another explicit Project data surface: local migration sync does not execute SQL, and editing workspace code does not automatically upload it into the database. A running covered Session uses role-checked server operations. The WebUI table browser is read-only. New database operations stop when the Project is no longer active. Accepted work can finish, and Project deletion waits for query leases, migration reconciliation, and physical database deletion. A deleted local file is neither a rollback nor proof of server erasure. [Public shares](/en/docs/sharing) deliberately cross the membership boundary. Anyone with a valid Markdown token can read its scope without logging in. A document token reads the current document and authorized media dependencies; an Admin-created context token can read Project records, documents, and Project session transcripts, including later content. These are live reads, not immutable exports. UI links last 7 days; authorized creators/Admins can revoke them as described in Sharing. Copies already downloaded cannot be recalled. Media `/m/` URLs still require membership unless access is delivered through an authorized share dependency. Share HTML exposes a built static surface and executes its JavaScript in the recipient's browser; it does not grant the author's server credentials or database access. Before publishing, inspect both content and dependencies and choose the smallest suitable sharing scope. --- # Setup — From Install to the First Request > The exact steps from prerequisites, CLI install and auth, obtaining an agent, starting `aachat up`, through the first request in a project. This page also covers headless / CI operating conditions and the roles of status / doctor / update. # Setup — From Install to the First Request Follow these steps from sign-in to the first request in a Project. Check the result at each stage so you can identify what needs attention if setup stops. For app-guided Mac startup, use [Desktop](/en/docs/desktop), then return here to obtain an Agent and create your first Project. ## Start from an external agent Paste this prompt into Codex or Claude Code to get help with setup through handing off your first task. ```text Read https://aachat.io/orchestration-skill.md, set up aachat, and help me hand off my first task. ``` Your agent follows the linked instructions to save the skill and install the CLI with the official installer. Use the same entry point if the CLI is already installed. You will be prompted for steps that need you, such as signing in. A connected repository is optional. To set up manually, follow the steps below. ## Prerequisites | Prerequisite | Condition | |---|---| | OS | One of macOS / Linux / WSL2 (Ubuntu) | | GitHub account | Used for sign-in and storing agent repos | | GitHub CLI (`gh`) | Installed and `gh auth login` completed | | Coding agent | For the Claude runtime, Claude Code (`claude`) is installed; for Codex, the Codex CLI is installed and signed in | | Node.js | 22 or later (`node` / `npm`). Used to start `aachat up` | If anything is not installed, complete it first via each official procedure. Even if Claude Code was installed via npm, confirm that `node --version` is 22 or later. ## Sign in Open aachat.io in a browser and sign in with GitHub. On completion, a personal team (slug `~`) is created automatically and Home opens. Check: the Home screen opens and the personal team appears in the team menu. ## Install the CLI ```bash curl -fsSL https://aachat.io/install | sh ``` The `aachat` binary and related binaries such as `chat` (used to run agents) are installed into `~/.cargo/bin`, and PATH is appended. ```bash aachat --version ``` If a version is printed, the install is complete. On `command not found`, open a new terminal. The installer appends PATH to your shell config file, so terminals that were already open may not pick it up. ## Authenticate ```bash aachat auth login ``` Issues a short-lived JWT from the local `gh` token and caches it at `~/aachat/.run/tokens/user.jwt`. If `gh` is already authenticated, no interaction occurs. Check: `✓ Cached aachat JWT for ` is displayed. ## Diagnose the environment ```bash aachat doctor ``` Diagnoses, in one pass, the GitHub CLI and its token permissions, Claude Code, connectivity to the aachat API, and login state (User JWT). For any `✗` line, resolve it with the steps shown directly below it (the command after `Run:`) and re-run. The coding-agent check in `aachat doctor` currently diagnoses Claude Code; it does not validate Codex sign-in. For a Codex runtime, confirm sign-in with the Codex CLI separately, then verify startup in the `aachat up` Launch Report and the first session. Check: resolve the failures relevant to your chosen runtime. A missing Claude check does not verify or disprove Codex readiness; check Codex separately as described above. ## Obtain an agent There are 3 paths. Whichever path you take, what gets created is the same — a single GitHub repo that is the agent's substance, and a registration on the team that references it (the agent repo structure is in [agents](/en/docs/agents)). | Path | Operation | |---|---| | Clone from Discover | In the WebUI, Discover → Agents, pick a public agent, and Clone. After GitHub authorization, the source repo's contents are copied as a private repo in your GitHub account, and an agent referencing that repo is automatically registered to the team | | Create via CLI | `aachat agent create ` | | Create via WebUI | Create from Agents in the sidebar | You may leave the GitHub repo field unspecified when creating an Agent. Its first `aachat up` then creates a private repo from the template. If you specify an existing repo, aachat uses that repo; it does not promise to scaffold an empty one. Check: your agent appears under Agents in the sidebar. ## Start the runtime — `aachat up` ```bash aachat up ``` Starts the runtimes of every agent you own, together in a single resident process. Real-time control uses WebSocket; transcript persistence and project operations use HTTPS APIs (the full boundary is in [trust-boundary](/en/docs/trust-boundary)). Agents can receive requests only while this process is running, so keep the terminal open. `Ctrl+C` stops all agents. `aachat up` checks for updates at startup, and if a new binary exists, it self-updates and re-execs with the updated binary. This is a startup check; it does not continuously replace a running process when a new release appears. Use `aachat update` for an explicit CLI update and plan runtime restarts around active work. Check: `● ready` appears in the terminal, and the agent shows as online in the WebUI's Agents. ### Runtime-specific prerequisites for Claude / Codex - **Claude**: `claude --version` works and Claude Code is authenticated. Hooks / MCP / plugins / commands / custom allow-deny settings from the team workspace repo are inherited into the session and merged with aachat's required permissions - **Codex**: install and sign in with the Codex CLI before switching the agent runtime to `codex-acp`. aachat prepares a pinned adapter; it does not create the user's Codex credentials ## Create a project and make a request Sign in to the team and check that an agent you own is online. For your first Project, start without a parent. 1. Open **Projects → New Project** in the WebUI. 2. Enter a **Name** of 2–30 lowercase letters, numbers, or hyphens. Do not use `stream`, `dm`, or `repo`. 3. Select an agent you own as **Lead**. In **Brief**, describe the goal, background, expected deliverables, and constraints. The optional description does not replace the Brief. 4. Submit **Create** once. “Project created; setup session accepted” means the Project and its setup Session were accepted. You do not need to repeat the setup request from the composer. 5. Open the Lead's Session from the new Project's Work Panel. The agent prepares PROJECT.md and REPORT.md and may ask for missing details. After the setup Session ends, review both documents and request the next work you want the Lead to perform. If Create is disabled, check Name, Lead, and Brief. If you cannot select a Lead or no response follows acceptance, use [Troubleshooting](/en/docs/troubleshooting) to check agent ownership, team, the ready line from `aachat up`, and runtime authentication. Choosing a human Lead instead gives “Project created; human Lead notified”: this notifies a human and does not run an agent. Continue to the [Project guide](/en/docs/projects) for start conditions, answering Asks, and accepting results before Done. See the [Session guide](/en/docs/sessions) for additional requests. ## Connect a development repo (optional) If you want external agents such as Cursor / Claude Code in your everyday development repo to participate in projects, run `aachat init` at that repo's root to connect it. Steps, placed files, and the write boundary are in [connected-repo](/en/docs/connected-repo). ## Operating in headless / CI environments aachat can run in headless environments (CI, always-on servers). Two implemented facts support this. - Authentication: if `gh` is authenticated, `aachat auth login` obtains a JWT non-interactively and caches it at `~/aachat/.run/tokens/user.jwt` - Residency: `aachat up` runs as a resident process that requires no interaction There is one more prerequisite. Agent execution happens on the coding agent (Claude Code / Codex) on that machine, so **the coding agent itself must be authenticated and runnable on the headless machine**. aachat's authentication (via `gh`) and the coding agent's authentication are separate; agents can work only when both are in place. ## Roles of the operational commands | Command | Role | |---|---| | `aachat status` | Returns the state of repo connections, auth, daemon, mirror, docs, and the Launch Report as JSON. Use for status checks from scripts and agents | | `aachat doctor` | Diagnoses environment health as human-readable text. Each `✗` item comes with resolution steps | | `aachat update` | Updates aachat itself to the latest version. `aachat up` self-updates at startup; an already-running process does not become the new version just because a release exists | ## Choose the startup path and check its version For an app-guided Mac setup, use [macOS Desktop](/en/docs/desktop). It checks prerequisites, signs in through the browser, installs its managed CLI, starts the local runtime, and opens the WebUI. The terminal procedure above remains the path for Linux, WSL2, and headless use. ```bash aachat --version chat --version aachat status ``` Record versions before diagnosing a missing feature. Desktop has its own app version and updater; updating it and updating the CLI are different operations. A repository change or a guide update does not itself upgrade the binaries on your machine. Use `aachat up --if-stopped` when you want to start only if no valid runtime is already running. It leaves an existing valid runtime alone and returns; if it starts a new one, that invocation stays resident. Plain `aachat up` can stop and replace an existing daemon, affecting active local work. Neither command promises an operating-system service or automatic restart after reboot. Keep the chosen runtime host running, and inspect status rather than repeatedly starting it. ## Keep the authentication paths separate | Path | What it authorizes | What to check when it fails | |---|---|---| | WebUI GitHub sign-in | Your browser access to teams and Projects | Browser sign-in and current team/Project membership | | CLI `aachat auth login` | aachat user access obtained from local `gh` authentication | `gh` login/permissions and `aachat doctor` | | Desktop GitHub sign-in | The app's browser callback flow and local aachat login | Complete the app's fresh sign-in attempt; coding-runtime login is still separate | | Claude / Codex login | Execution by the local coding runtime | Authenticate the selected runtime on the machine that runs the Agent | | External Session Run API key | A fixed external-start credential | Expiry, rotation/revocation, owner and Project membership; see [External Session Run](/en/docs/external-session-runs) | | Client entry | A temporary guest browser login for its dedicated Project | The originating browser and 7-day validity; see [Connected repo](/en/docs/connected-repo) | Task-specific environment secrets are another layer, configured in [Environment](/en/docs/environment). Browser sign-in is not approval to inject a secret. Treat each credential's expiry or revocation at its own surface; do not assume signing out of one client revokes external-start keys or provider credentials. ## Related pages - What is local and what is server, secret handling: [trust-boundary](/en/docs/trust-boundary) - Agent repo structure and when changes take effect: [agents](/en/docs/agents) - Session lifecycle and delegation: [Sessions](/en/docs/sessions) - Connecting a development repo and external agent participation: [connected-repo](/en/docs/connected-repo) - Diagnosis by symptom: [Troubleshooting](/en/docs/troubleshooting) --- # agent — the entity is a GitHub repo, grown with git > An agent's entity is a single GitHub repo. This page covers the repo layout (identity / memory / knowledge / skills / environment.yaml), when changes take effect, the relationship to the owner and the machine it runs on, and how agents are created and grown. # agent — the entity is a GitHub repo, grown with git The entity of an aachat agent is a single GitHub repo. 1 agent = 1 repo. Personality, memory, knowledge, and capabilities all exist as files in this repo and are managed as git versions. Agent names use the `{base}.{owner}` format (example: `researcher.kensaku`) — the owner's GitHub login is appended to the base name to form the full name. When asked who an agent is, what it remembers, and what it can do, every answer is inside this repo. There is no magical internal state. ## agent repo layout | Path | Role | |---|---| | `identity.md` | Personality, role, and behavioral guidelines. **Injected into the agent at session start** | | `memory/` | The agent's own accumulated experience and judgments. Appended through work | | `knowledge/` | Reference information needed for work (specs, style guides, etc.) | | `.agents/skills/` | The normal source for agent skills, laid out as `/SKILL.md`. `.claude/skills/` is also read for Claude compatibility or existing assets | | `environment.yaml` | Declares dependency packages and environment variable names. **Secret values cannot be written here** (details in [Environment](/en/docs/environment)) | When a session starts, this repo is checked out as a worktree inside the session's workspace (`~/aachat/.run/workspaces/--/aachat/agents/`). The local clone cache is at `~/aachat/.run/cache/`. The agent repo is canonical for the agent's own learning, not for the deliverables of an individual project. The next session combines identity / memory / knowledge / skills from the agent repo with project-side context. When a task needs that context, it reads `PROJECT.md` first as the stable Project Contract / Context Router, then follows the curated Context Map to the Shared Documents it needs. It reads dynamic handoffs from a session transcript, short project message, or normal Shared Document. Keep settled deliverables and project-specific decisions on the project side; keep capabilities and rules of thumb that travel across projects in the agent repo ([Concepts](/en/docs/concepts)). ## When changes take effect — the most important fact Changes to the agent repo are **made via git commit, and take effect from the next session after push**. This is a point where misunderstanding arises structurally, so convey it to users precisely. - Editing files locally is not enough for changes to take effect. You must commit and push - Even pushed changes **do not take effect in a running session**. They become effective from the next session that starts - The same rule applies to all of `identity.md`, `memory/`, `knowledge/`, `.agents/skills/` (including the compatible `.claude/skills/` source), and `environment.yaml` For the question "I changed the identity but the behavior didn't change," first have the user confirm two things: (1) did they push, and (2) did they start a new session after pushing. The flip side of this rule is that **the repo is the source of truth for agent behavior**. Because what gets injected into a session comes from the pushed repo, local-only configuration drift never changes agent behavior. Every behavioral change is traceable as commit history and is subject to review and revert. When a team wants to govern agent behavior, this history serves directly as the audit record of changes. ## owner and the machine agents run on - Only the **owner** can manage an agent (creation, repo changes, making it dormant). Team members other than the owner cannot manage the agent - An agent **runs on the owner's machine**. The `aachat up` run by the owner starts the agent's runtime. If the owner's `aachat up` is not running, that agent's session will not start even when other members send requests - The coding-agent process (such as Claude Code) and workspace file operations run on the owner's machine. That runtime connects to the LLM provider for inference; provider computation does not run on the owner's machine merely because the client does. **The server stores Project messages, Shared Documents, and session records; it does not run agent processes.** The full picture of this boundary is in [Trust Boundary](/en/docs/trust-boundary) ## Creating and acquiring an agent There are three acquisition paths. 1. **Clone from Discover**: duplicate a published agent as your own agent. Cloning also automatically creates a DM project with that agent (`dm:`) 2. **Create in the WebUI**: from Create Agent in the "Agents" sidebar. Names use alphanumerics, hyphens, and underscores. The GitHub repo field is optional (leaving it empty is the easy path). The runtime is `Claude` (default) or `Codex` 3. **CLI**: `aachat agent create` When an agent is created without specifying a repo, **the first `aachat up` automatically creates a private repo `/` from the template** and lays out the scaffold (`identity.md`, `memory/`, `knowledge/`, the normal `.agents/skills/` source, and the compatible `.claude/skills/` source) (this uses an already-configured `gh`; prerequisites are in [Setup](/en/docs/setup)). If `aachat up` is already running, the new agent is started automatically without a restart. If you specify an existing repository instead, use one whose default branch is `main`. Managed Sessions record Agent-repository delivery against `main`; a repository with another default branch can start from that branch but will not satisfy the delivery receipt contract. Change its default branch before registering it, or leave the repo field empty and let aachat create the repository. ### Excluding an agent from launch (dormant) Agents you will not use for the time being can be excluded from `aachat up` launch targets with the `dormant` flag. ```bash aachat agent update --dormant # exclude aachat agent update --no-dormant # restore (auto-starts if up is running) ``` Dormant agents are shown as `○ dormant` at launch and recorded as `[dormant]` in the Launch Report (`~/aachat/.run/logs/up.log`). ### Deleting an agent ```bash aachat agent delete --yes ``` Delete is irreversible and is not the same as dormant. It cancels active sessions and Session-scope Asks, deletes the owner's DM, removes every project membership, and tombstones the server agent. Local workspaces also become cleanup targets, so inspect uncommitted / unpushed work and any needed DM or session record first. Choose dormant instead when the agent may be used again. ## Agents grow Agent growth means commits accumulating in the repo. Through work, `memory/`, `knowledge/`, and the normal `.agents/skills/` source build up and remain as git versions. Therefore all of the following are possible. - **review**: check what was learned and when via commit history - **revert**: roll back undesirable changes with git - **clone**: duplicate a grown agent (and hand it to other users via Discover publication) Editing in practice is ordinary git operations. The easy way is to directly edit the worktree checked out inside a running session's workspace. ```bash # is the first 8 characters of a session ID, found with aachat session list --agent cd ~/aachat/.run/workspaces/--/aachat/agents/ # edit files git add git commit -m "" git push origin HEAD:main ``` Cloning normally into a separate directory, editing, and pushing yields the same result. You can also have the agent grow itself by asking it to "append this to memory and push." ### The skill improvement loop Create and update skills in the agent repo's normal source, `.agents/skills//SKILL.md`. `.claude/skills//SKILL.md` is also read for Claude compatibility or existing assets, but is not the normal authoring destination. If the same skill name exists in both, the `.agents/skills/` source takes precedence. The basic form of the improvement loop is to route it through the agent itself as a self-improvement request. 1. Ask the agent in a session to "turn this procedure into a skill so you can use it next time" 2. The agent writes the skill into its own repo (which the environment variable `AA_AGENT_DIR` points to inside a session), commits, and pushes 3. The skill is loaded **from the next session after the push** (there is no hot reload during a session) Besides the agent's own skills, a session also gets aachat's platform skills (`aachat-*`) and the skills git-managed in the workspace repo projected into it. To avoid name collisions, give skills agent-specific names and do not use `aachat-*` names. [skills](/en/docs/skills) is canonical for source precedence, Skill Ledger, and the feedback-to-improvement-session loop. Helper commands: - `aachat skills add ` — places a skill into the normal `.agents/skills/` source of the current directory (changeable with `--target`) (requires Node.js because it uses `npx skills add --agent universal` internally) - `aachat manage-agent` — an interactive entry point that walks through search, clone, identity editing, skill addition, and commit & push in one flow (requires the `claude` command) ## Default Runtime and per-Session selection — Claude Code / Codex Each new Session runs on either `Claude` (Claude Code; `claude-acp`) or `Codex` (`codex-acp`). An agent's setting is only the initial default for future launch drafts; the selected Runtime is fixed independently for each Session. The default is Claude. | Operation | Method | |---|---| | WebUI | Change the target agent's **Default runtime** on Home, or choose a Runtime in the Project composer | | CLI | `aachat agent update --runtime codex-acp` (revert with `claude-acp`) | - Changing the default affects only future launch drafts. It does not change running or existing Sessions and does not require restarting `aachat up` - Choose a Runtime per Session in the WebUI composer or with `session run --runtime claude-acp|codex-acp` - The selected Session Runtime determines workspace projections: Claude uses `.claude/` (`CLAUDE.md` and `.claude/skills/`), while Codex uses `AGENTS.md` and `.agents/skills/`. The agent repo's skills are loaded under either Runtime ## Relationship to Discover - **Acquire**: clone a published agent from the Discover catalog to make it your own agent - **Publish**: agents you have grown can be published to Discover. Use a reviewed public tree with `.aachat/public.yaml` and an explicit human-owner publication action; follow the procedure below ## Deliver an Agent change and verify it For an edit made inside a managed Session, the Agent worktree can be detached. Push explicitly to the Agent repo's required `main` default branch, then record the successful operation with the Session CLI: ```bash cd "$AA_AGENT_DIR" git status --short git add identity.md git commit -m "Clarify research responsibilities" git push origin HEAD:main ``` Stage the actual files you reviewed; `identity.md` is an example. The receipt records a successful push and does not perform one. A commit or a local edit alone is not delivery. Check the remote commit and begin a new Session to observe the change. If the receipt fails after a successful push, retry only the receipt from the same repository and HEAD; do not repeat the external operation just to obtain a receipt. For a start failure, distinguish an offline owner runtime from an unavailable Runtime or unsupported configuration. Use the Runtime and options actually offered in the launch form. Arbitrary model/configuration values are not accepted merely because a coding CLI supports them. Correct runtime authentication or the offered configuration and launch a new Session; changing the Agent default does not repair an existing Session's fixed Runtime. ## Publish or return an improvement [Discover](/en/docs/discover) gives the complete preparation, human publication, sync, and unpublish procedure. Publication needs `.aachat/public.yaml` and reviewed public files; making the working repository public or merely having `identity.md` is not a sufficient publication procedure. Private Agent development, public-copy updates, and catalog synchronization are separate steps. A cloned Agent can draft an upstream improvement proposal for its human owner to review and send as a **GitHub Issue**. The proposal does not automatically update the source or your clone. Discover's separate reviewed code-improvement flow may create a PR; confirm which action the card will execute before approving it. ## Related pages - The session lifecycle and workspace separation: [Sessions](/en/docs/sessions) - The `environment.yaml` contract and how secrets are passed: [Environment](/en/docs/environment) - What is local and what is server: [Trust Boundary](/en/docs/trust-boundary) - Prerequisites and setup for `aachat up` and `gh`: [Setup](/en/docs/setup) - Skill sources, precedence, and improvement history: [skills](/en/docs/skills) ## Choose an offered Runtime profile Before launch, inspect the Runtime controls in the human launch form. A Session agent can discover current profiles with `chat project members / --runtime-profiles`. Select a Runtime and config IDs/values actually offered for that Agent; do not infer availability from a model name in an old transcript. CLI overrides are typed: `--config =id:` for an ID choice and `--config =boolean:true` (or `false`) for a boolean. Repeat `--config` for separate options. `mode=id:plan` is only usable if the selected profile offers that exact option. Missing options use the profile defaults. For a direct launch, omitting both Runtime and config can reuse the target Agent owner's saved launch preferences for that Agent in this Project; without saved preferences it resolves the Agent default. This applies to interactive human launches and direct Agent delegation. Explicit Runtime or config overrides do not reuse that preference set; config alone resolves against the Agent default Runtime. Workflow automation and external launches use their own accepted launch settings. Existing Sessions retain their accepted settings. If launch rejects an unknown option, unsupported value, or unavailable profile, reread the offered profile and replace/remove only the invalid override. Check provider authentication and local Runtime availability when startup itself fails. Read the acceptance result and Session state before resending, so an accepted request is not duplicated. See [Sessions](/en/docs/sessions), [CLI](/en/docs/cli), and [Troubleshooting](/en/docs/troubleshooting). --- # Skills — Sources of Truth and Improvement History > This page explains where Agent, Team, and Platform skills come from, projection precedence, and how Skill Ledger turns usage and feedback into repo-backed improvements. # Skills — Sources of Truth and Improvement History A skill is a reusable capability or procedure for an agent. Its source of truth is `/SKILL.md` in a Git repository. This page is canonical for where skills live, which same-named skill is used, and how observed usage becomes an improvement. Read [agents](/en/docs/agents) first for the agent repo and the push-then-new-session rule. ## Three sources | Source | Source of truth | Purpose | |---|---|---| | **Team** | Git-managed `.agents/skills/` or `.claude/skills/` in the session's workspace repo | Procedures shared by every agent working in that repo | | **Agent** | The normal `.agents/skills/` source in the agent repo; `.claude/skills/` is also read for Claude compatibility or existing assets | Capabilities the agent carries across projects. `.agents/skills/` wins on duplicate names | | **Platform** | Skills supplied to the session by aachat | Contracts for correctly operating aachat projects, documents, Asks, git, and related surfaces | A top-level `skills/` directory is not loaded. Each skill needs a `SKILL.md`, stored as a normal UTF-8 file under git. Do not use symlinks or special files as skill sources. ## Projection and precedence At session start, all three sources are projected into the runtime's skill discovery path. When the workspace repo and agent repo contain the same skill name, the **workspace / Team skill shadows the Agent skill**. This lets the repo-specific contract win in that session. Platform skills are reserved contracts and cannot be overridden, but collision outcomes depend on the source. - A workspace / Team skill with the same name as a Platform skill is a setup error - An Agent skill with the same name is shadowed by the Platform skill; the session starts with the Platform version Invalid paths and missing `SKILL.md` remain setup errors. Recovery and the source-specific collision cases are in [troubleshooting](/en/docs/troubleshooting). The `aachat` skill that `aachat init` writes into a repo is not a Platform name, so it projects like any other workspace skill. Its own `SKILL.md` says it is not for use inside a session. Because the repo is canonical, commit and push a skill change, then start a new session. There is no hot reload into a running session. ## Skill Ledger **Skills** shows explicitly refreshed repository snapshots alongside observed usage and feedback. Starting a Session or opening the list does not rescan repositories. An Agent page shows Agent and Platform sources; Team and Project links select their own workspace repository and branch. - **Refresh** checks one source at one GitHub commit and saves its `SKILL.md` files and Agent identity atomically. Failure or cancellation preserves the previous snapshot. Never fetched and confirmed empty are different states. - Private sources require the signed-in person's GitHub authorization or the Team GitHub App installation matching that repository. - Usage loads independently for the last 30 days. These are saved tool observations, not a complete usage rate. Missing observations, unavailable observations, and observed zero are distinct. - Detail shows the saved source, branch, commit, and text. Files loads only the directory opened or file selected. Legacy Session content is labeled as historical; unknown size or hash is not filled with zero or an empty value. - Runtime usage and `chat skill feedback` work before a refresh. Humans can leave feedback from a saved source. - **Start improvement session** pins the repository, root, branch, and commit. Repeating the same request returns the original Session, even before the skill has a history ID. Choose a workspace skill's Agent from collaborators of the improvement Project. Platform skills are read-only. Send improvement feedback to aachat instead of editing them in the project or agent repo. ## Basic improvement loop 1. Read the observation coverage and feedback to select a skill to improve 2. Edit the workspace repo for a Team-specific skill, or the agent repo at `AA_AGENT_DIR` for an Agent-specific skill 3. Test, commit, and push 4. Use it in a new Session and inspect usage and feedback. Refresh the source to update the saved list Supporting commands are `aachat skills add `, which installs into the normal `.agents/skills/` source, and `chat skill feedback ...`; syntax is in [cli](/en/docs/cli). ## Install from Discover and record the installation Discover → Skills is the public catalog; the team's **Skills** sidebar is the Skill Ledger. Read the public Skill's source files and requirements first. In the catalog's install action, choose an Agent you own that has a repository and a connected runtime. Review the preparation conversation and explicitly approve the installation. See [Discover](/en/docs/discover) for target selection and fallback behavior. The installation work must copy or adapt the Skill and its supporting files into `.agents/skills//` in that Agent's repo, validate them, and commit and push. If a Skill with that name already exists, review the differences and choose how to adapt it before overwriting useful local behavior. New dependency declarations do not install packages or grant secrets; follow [Environment](/en/docs/environment). After a successful push, the catalog operation is: ```bash aachat skill install --agent ``` Use the actual catalog UUID and your target Agent name from the installation flow. This records an **installation receipt**. It does not download files, push commits, restart a Session, or verify usage. Repeating the registration for the same Agent reports that it is already recorded. Only the target Agent's owner can register it. | Operation | What it does | Completion check | |---|---|---| | `aachat skills add ` | Uses the external skills installer to place source files in the current directory's `.agents/skills/` (or `--target`) | Inspect files, validate, commit, and push to the intended repo | | `aachat skill install --agent ` | Records catalog installation for an owned Agent | Registration result; this is not runtime evidence | | Skill Ledger usage / feedback | Observes projected skills and records use or improvement feedback | Check the source commit and actual usage in a new Session | If registration fails after the file push, repair authentication, ownership, or the catalog ID and retry only registration. If the receipt exists but the Skill is absent in a Session, check the pushed commit, new-Session timing, and source precedence. A workspace Skill can shadow the installed Agent Skill. ## Publish a Skill on its own You can publish a Skill without publishing its Agent in Discover. The original Agent's GitHub repository can stay private. In the Agent detail page's Skills section, choose **Publish** for a Skill owned by that Agent. With a repository and connected runtime, the Agent prepares the selected Skill and supporting files in a separate publication repository. Review that content before publishing. Skills supplied by the Team or Platform do not have this publication action. A standalone Skill does not need an Agent publication profile or `.aachat/public.yaml`. Put `SKILL.md` and supporting files in `.agents/skills//` in the publication repository, with `aachat.discovery.listed` set to `"true"` in the metadata below. The CLI command in that prepared repository is `aachat skill publish .agents/skills/ --agent `. Follow [Discover](/en/docs/discover) for private preparation and the explicit change to public visibility. Manage each Skill's sync and listing in publication management. Stopping the source Agent's listing or changing its publication repository does not remove standalone Skills. Sync reads public repository changes into the catalog; it does not distribute updates to Agents that installed the Skill. ## Publishing with an Agent and shared metadata Agent publication and synchronization also read Skills from that Agent's reviewed public repository. Both standalone and bundled Skills use regular UTF-8 files and require all five localized/listing metadata keys below. The two headline and two description values must be nonempty. This is the complete content of an example `.agents/skills/source-review/SKILL.md`: ```yaml --- name: source-review description: Review public sources and record citations. metadata: aachat.headline.ja: 公開情報を出典付きで整理する aachat.headline.en: Review public sources with citations aachat.description.ja: 公開情報を比較し、事実と推定を分けて報告する手順。 aachat.description.en: Compare public sources and separate facts from estimates. aachat.discovery.listed: "true" --- # Source review Read the supplied public sources. Record each source URL, distinguish facts from estimates, and write a referenced summary. Do not contact third parties. ``` For a Skill bundled with an Agent, `aachat.discovery.listed: "false"` keeps the Skill out of standalone Discover listing, but its files are still public with the Agent repository. A standalone Skill publication requires `"true"`. The flag is a catalog choice, not an access control. The localized metadata describes the Skill in Discover; it does not translate its instructions automatically. Review the repository's license, private content, and all supporting files before the human owner publishes it. Follow [Discover](/en/docs/discover) for `.aachat/public.yaml`, explicit public visibility, sync, and stopping the Agent/Skill listing. Catalog lineage records a source relationship; it does not automatically install upstream updates into existing Agents. ## Related pages - Agent repo and when changes take effect: [agents](/en/docs/agents) - Session projection: [sessions](/en/docs/sessions) - Collision and setup failures: [troubleshooting](/en/docs/troubleshooting) - Command syntax: [cli](/en/docs/cli) --- # Session — the execution unit where agents work > The exact specification of session state transitions, starting and continuing sessions, reading transcripts versus logs, how workspaces are created and repo configuration, scheduled execution, and delegation between agents. # Session — the execution unit where agents work A session is the execution unit in which an agent actually works. When a user or another agent sends a request, a session starts, and the agent runs on top of the coding agent on the owner's machine ([Trust Boundary](/en/docs/trust-boundary)). This page covers the session lifecycle, operations, how to read the records, workspace separation, and delegation between agents. ## Lifecycle States transition as `starting → running → stopping → stopped`. Abnormal termination becomes `failed`. A runtime prompt execution failure is distinct from notification delivery failure. Read the transcript and owner-local logs, then check Resume eligibility; Workflow Steps use Workflow retry ([recovery](/en/docs/troubleshooting)). For an ordinary Session, the policy is for the agent to run `chat session finish` before ending the turn once the current request is fully handled and there is no specific continuation planned. If finishing is already underway, it should not repeat the command. After `chat wait` is accepted, the agent ends only the turn and waits for continuation without finishing the Session (see “Wait for results and continue the same Session” below). Application of this instruction depends on the owner-side runtime version; it does not guarantee that every running Session stops immediately when its work is done. Acceptance of finish also differs from actual termination. See the [CLI finish explanation](/en/docs/cli) for the subsequent asset wrap-up and other details. A Workflow Attempt follows its Step completion procedure; ordinary Session finish is not a substitute ([Workflows](/en/docs/workflows)). A Session ending does not by itself establish that the Project is Done, its deliverables are accepted, or code delivery succeeded. Use “Read results and the accepted turn” below to inspect the artifacts and validation. After 60 idle minutes, a session enters its finish path. When it has a completed turn, the runtime performs `finish` on its behalf and runs one asset wrap-up turn to check for unsaved deliverables before closing. If submitting the initial idle-finish request fails, the session stays alive so that request can be retried. If the wrap-up turn itself cannot start, complete, or persist, the session becomes `failed`, preserves its workspace, and instructs the user to resume it or start another session. Idle finish is disabled while a scheduled follow-up has a next run pending. Archiving a Project does not forcibly stop work already executing in ordinary Sessions. It does cancel that Project’s unexecuted reservations and block new execution and follow-up instructions. See [Projects](/en/docs/projects) for Workflow Session termination and reservations or recurring work that are not restored automatically. ## Starting a session ```bash aachat session run --project "request text" ``` The agent is resolved as a member of the specified project. A session can run only when all three of the following conditions are met. - The project's status is `active` - The agent is a member of that project - `aachat up` is running on the agent's owner side (the agent is online) In the WebUI, a session starts when you address an agent with the composer's **target chip** and send. **An @mention is not a session execution trigger.** The exact `@.` in a message body is a notification (a call-out) and does not start a session on its own. What makes an agent work is target chip addressing in the WebUI, and `session run` in the CLI. Reports of "I mentioned the agent but nothing ran" are caused by this specification. The WebUI composer also accepts an attachment-only request with no message text. The attachment is stored in Session history and is not automatically published to Project Media. ### `session run` options | Option | Meaning | |---|---| | `--repo ` | Override the workspace repository for this session | | `--runtime ` | Select this session's Runtime. Omission and saved interactive launch preferences follow [Agents](/en/docs/agents) | | `--config ` | Set one explicit Runtime option. Repeat for multiple options; for example, `--config mode=id:plan` | | `--attach ` | Attach images, videos, or PDFs. Attachments go to Session history and are not published to Project Media. An attachment-only start without text is valid | | `--stdin` | Read the request text from stdin (mutually exclusive with the message argument) | For runtime Permission, a temporary question, a Project Ask, or a Workflow Decision, use the [response comparison](/en/docs/permissions) to choose who answers and what continues. ## Continuing a session Send additional instructions to a running session with `session send`. When waiting for a registered Ask continuation, do not send the same answer again as a follow-up; see “Wait for results and continue the same Session” below. ```bash aachat session send --project "follow-up instruction" ``` | Option | Meaning | |---|---| | `--cancel-current-turn` | Cancel the running turn before executing this message | | `--attach ` | Same as `run`. Goes to Session history, not Project Media. An attachment-only send without text is valid | | `--stdin` | Read the message from stdin | In the WebUI, the workspace panel opened by selecting a Session in the Project Work Panel lets you monitor execution in real time, send follow-ups, respond to permissions, and cancel turns ([WebUI](/en/docs/webui)). List sessions with `aachat session list` (the connected team's Work Index; filter with `--agent` / `--project`); stop one with `aachat session stop `. ## Reading the records — transcript and logs as a pair There are two kinds of session records, differing in content and storage location. Use them as a pair. | Command | What it reads | Storage | |---|---|---| | `aachat session read --project ` | The conversation transcript (requests, responses, progress) | server | | `aachat session logs ` | The runtime's stderr log (startup and execution errors) | Local (`~/aachat/.run/logs/`) | Use `read` to check conversation content and results; use `logs` to investigate startup failures and execution errors. `read` supports paging with `--last` (default 50, max 100) and `--before`. `logs` can read from the beginning with `--from-start`. Turn completion text is stored in this server transcript but is **not automatically posted as a Project Timeline message**. A handoff remains in the transcript first. When the project needs a short notification or handoff, the agent explicitly runs `chat send ...`. Use a normal Shared Document only when the handoff is substantial and independently worth rereading. Do not put progress or handoffs in `PROJECT.md`. A transcript is the session record; a Timeline message is project-wide communication. ## Compacting a long session `chat session compact` compresses a long session's context so work can continue in that same session. It does not start new work. Outside agents use the public `aachat session compact` command instead of `chat`. ```bash chat session compact chat session compact --project aachat session compact --project ``` - With no target it compacts the current session; a target requires its project - The request runs after the current turn completes and before an ordinary follow-up. Do not pack more work into the turn that requests compaction; finish that turn - If the runtime does not support compaction, use `chat session finish` to preserve assets, then start a fresh session - CLI / server request identity makes retries idempotent; do not send a home-grown compression prompt - Compaction does not delete the original transcript. Keep important decisions and deliverables in canonical Shared Documents rather than relying on the summary alone ## Accepted work after a runtime restart With a supporting API/runtime version, pending or interrupted work accepted before a restart can recover in the same Session and workspace when its conditions are met. These include restoring saved runtime connection information, workspace and launch configuration with current Project coverage, meeting close/Archive constraints, and staying below the redelivery attempt limit. Automatic recovery of every job and exactly-once external operations are not guaranteed. A return to `starting` after restart alone does not mean a new request or failure. Before running or sending the work again, inspect the original Session, accepted turn, transcript, results, and delivery. Recovery of accepted work differs from manually resuming an ended ordinary Session. A terminal Workflow Attempt still follows Run retry/new Run rules, not generic Resume. See [Troubleshooting](/en/docs/troubleshooting) for the check order and what to do if progress stops. ## Workspace separation and how workspaces are created Each session gets an independent workspace created at `~/aachat/.run/workspaces/--` (sid8 is the first 8 characters of the session ID). At session start, the runtime prepares the following. - **workspace repo**: in a session whose repo is resolved, that repo is checked out at the workspace root. The branch is the aachat-managed `aachat-sessions///` (for a session spanning multiple projects, `` is `multi`). A session whose repo is not resolved (a DM, or a team with no repo configured) gets a repo-less empty workspace (scratch) - **agent repo**: the agent's own repo is checked out as a worktree at `aachat/agents//`. The session can locate it via the environment variable `AA_AGENT_DIR` - **Runtime context projection**: aachat's runtime context is generated into `.claude/CLAUDE.md` (Claude runtime) or `AGENTS.md` (Codex runtime), and skills are projected. If the repo already git-manages a file of the same name, the projection is diverted to `CLAUDE.local.md` / `AGENTS.override.md`. Projected files are added to git's local exclude, so they never show up as repo changes **Cleanup when a session ends** is decided automatically: if uncommitted changes, or local commits that do not exist on the remote, remain, the workspace is **kept**; if it is clean (no changes, or committed and pushed), it is **deleted**. This keep/delete decision **applies only to git workspaces**: a repo-less scratch workspace is deleted at session end regardless of its contents, so move anything worth keeping to a project surface (Shared Documents, media, etc.) before the session ends. The workspace of a resumable session is protected from deletion, and the same workspace is reused on resume. One session has one workspace repo. Work that spans multiple repos is split into one session per repo and coordinated at the project level. Even when multiple sessions run in parallel against the same repo, each works in its own independent workspace, so in-progress files never collide directly. Changes are integrated through the normal git / PR flow. ### Configuring the workspace repo The repo resolution order is **the session-level override > the project setting > the team default**. | Where it is set | How to set it | |---|---| | session (one-time override) | CLI `session run --repo `; in the WebUI, the composer's **Repo chip** | | project setting | Specify the repository (`owner/repo`) and working branch in the project settings | | team default | Specify at team creation (WebUI "Create Team" / `aachat team create --repo`) or in the team settings' repository | A session-level override must match either the project setting or the team default. An `owner/repo` that matches neither is rejected (this is not a mechanism for pointing at arbitrary repos). DM sessions are always scratch; no repo is used. Note that the WebUI sidebar's "Repository" tree (the GitHub App connection) is a separate system from this setting ([WebUI](/en/docs/webui)). The `aachat init` repo connection ([Connected Repo](/en/docs/connected-repo)) is also not a workspace repo setting. A team default repo does not grant repository access. Each member needs their own GitHub credential, read/write permission, and organization SSO authorization where required ([Teams](/en/docs/teams)). ## Delegation — an agent driving another agent's session An agent running inside a session can start, monitor, and continue another agent's session with the `chat` command. `chat` is exclusively for agents inside a session; outside a session (humans, external agents), use `aachat`. | Operation | Command | |---|---| | Start another agent's session | `chat session run --agent --project "request text"` | | Read progress and results | `chat session read --project ` | | Send additional instructions | `chat session send --project "follow-up instruction"` | | Resume an ended session and send instructions | `chat session send --project --resume "follow-up instruction"` | Before delegating, read `chat project members ` and use `members[].name`, `capability.commands`, and `live_sessions` to choose the target. Use `run` for fresh work; use `send` only when there is a clearly related session. To continue the same work in an ended session, explicitly add `--resume`. An advertised slash command is placed at the beginning of the request prompt; it is not a dedicated flag. `--resume` is an explicit agent-only operation. For a `stopped` or `failed` target, the resume and follow-up are accepted in the same database transaction. If a resume is already in progress, the follow-up is queued in that generation; if the target is `running`, it is accepted as an ordinary follow-up without restarting the session. A plain send never resumes an ended session implicitly. Archived sessions, Workflow Steps, and sessions whose workspace, configuration, or project coverage cannot be safely restored are rejected. Do not combine `--resume` with `--cancel-current-turn`. Delegation has two conditions: the delegate agent is online (`aachat up` running on its owner's side), and the delegate is a member of the same project. Agent mentions use the exact project-member name `@.`. An unknown target produces a warning, and a mention still does not start a session. The same loop humans run in the WebUI — request → execute → check → follow up — works between agents. Delegation requests and results remain in session transcripts; use a message for a short project-wide handoff, and a normal Shared Document for an independent deliverable ([Concepts](/en/docs/concepts), [Shared Documents](/en/docs/shared-documents)). A session started by delegation records its lineage to the session that started it (the source session). Because which request spawned which session can be traced afterwards, the history stays traceable even as work passes between agents. ### Orchestration patterns Use immediate Session delegation when the next request depends on the work you are inspecting. Use a [Workflow](/en/docs/workflows) when you want repeatable Steps with typed inputs, outputs, dependencies, and human Decisions. A Workflow pins its Revision for each Run; ordinary delegation keeps the next instruction flexible. - **run versus send**: `chat session run` starts new work as a new session. `chat session send` adds instructions in an existing session's context; add `--resume` only when continuing the same work in an ended session - **Waiting for completion**: register explicit targets with `chat wait` as described below in “Wait for results and continue the same Session.” After acceptance, end the turn without polling. Read the results when continuation arrives - There is no implementation limit on delegation depth or fan-out. Deep chains make the history hard to follow, so consolidate results in the project's Shared Documents When a human drives multiple agents from the WebUI, the composer's target chip addresses one agent per message. To reach multiple agents, split the request into separate sends or entrust the delegation to an orchestrator agent. ### Wait for results and continue the same Session When a Session agent needs to use results in a later turn, register explicit target IDs with `chat wait --all` from the current Project directory. Targets are Project Asks, direct child Sessions, or top-level Workflow Runs started by the source agent, all in that Project; they are never discovered automatically. ```bash cd aachat/projects// chat wait --all --ask # Inspect the wait ID returned at registration when needed chat wait show ``` After acceptance, end the turn. While waiting, do not use `chat session finish`, re-register, send a manual follow-up, or poll. Once every registered target settles, one continuation is accepted. Ask cancellation is also settled; it does not mean approval or success. The check runs on a 30-second cycle, not a promise of a response within 30 seconds. #### Find the wait and read its result The following displays require a Web/API version that supports wait details and result notifications. If they are absent, check the registration receipt in the transcript and use the [CLI read commands](/en/docs/cli); absence alone proves neither an unregistered wait nor success. A Session can be `running` while its list entry shows **Awaiting results**. Open that Session to find the wait panel above the composer. A single target is a row; expand a multiple-target group to see each Ask, Session, or Workflow name and state. Follow its link to the details. Deleted targets have a fallback name with a short ID and a disabled link. **Couldn't load wait details. → Retry** reloads these details; it does not resend an answer or continue the Session. After all targets settle and continuation acceptance succeeds, the transcript stores a collapsible **Wait completed** system notification. If every target is settled but the notification is still absent after a check cycle, inspect whether the source Session is `stopping` or archived and whether its agent still has Project collaborator access. Expand a saved notification to inspect the names and states captured at settlement and follow the target links. Later renames or answer revisions do not rewrite this snapshot. **Needs attention** means a target is `failed`, `attention_required`, or `cancelled`. A `stopped` Session also does not by itself prove a successful deliverable. Keep six checks separate: the answer was saved; every target settled; the target results succeeded; the system notification was saved; it was delivered to the agent; and the agent produced the next result using those inputs. **Delivery pending / failed / cancelled** describes notification delivery, separately from the target snapshot. Open a failed notification for its error and, when eligible, **Retry delivery**. It retries the same notification and turn; it does not rerun the targets. System notifications cannot be edited, removed, or sent with **Run now** like ordinary queued messages. The agent receives target results with `Read:` commands and reads only the sources needed for its decision. The Web notification presents results and links, not raw commands to copy. `chat wait show` remains an optional read-only check. For retry conditions and Session failure, follow [answer and continuation recovery](/en/docs/troubleshooting). See [Projects](/en/docs/projects) for saving answers and distinguishing registered from unregistered waits. `chat ask wait --timeout` bounds a wait within the current turn; it does not register this continuation ([CLI](/en/docs/cli)). ### Runtime built-in subagents A Task tool or similar subagent started by Claude Code / Codex is a **runtime feature for exploration or parallel work inside the same session**. It does not start a separate project-member agent session and does not gain independent project membership, transcript, or handoff ownership. Use `chat session run --agent ...` when work belongs to a worker with another agent repo, owner, and project role. Use a runtime built-in subagent for temporary division of work inside the same session. ## Scheduled execution Automatic execution uses Project Triggers and scheduled follow-ups. Triggers are managed in the WebUI or with `chat trigger` inside an aachat Session; scheduled follow-ups can also be created, listed, or cancelled with `aachat session schedule`. Cron expressions are not used. | Mechanism | Target | Recurrence | Where to configure | |---|---|---|---| | **Project Trigger** | Starts a published Workflow or fresh Session | Time conditions may recur; Document match is one-time | Project **Triggers** or `chat trigger` | | **scheduled follow-up** | Sends a follow-up turn to a running or waiting session | Yes (1-minute to 1-day intervals) | The **Schedule** button in the session thread composer | - A Project Trigger has exactly one When: Once, Daily / weekly, Interval, or Document match. Document match starts once when Shared Document frontmatter in the same Project equals the configured value. The composer When chip can carry the current agent, prompt, and launch settings into Trigger creation - A **scheduled follow-up** supports turn execution such as "run this check every morning." It is text-only; replies and attachments are not supported. While a next run is pending, the 60-minute idle auto-stop does not apply. Delete the follow-up or end the session to stop recurrence ## Read results and the accepted turn Open a Session from the Project Work Panel. Inspect its direct child Session tree to follow delegation, and read each child's final response and actual artifacts. Workflow result badges open the Workflow; Trigger result badges identify the Trigger but do not directly open its detail. Go to the Project's When/Triggers surface and locate that Trigger to inspect its state and occurrences. Open documents through the Project's Docs or the actual document links in the transcript. The results panel is not a complete attribution list for every document or Ask. A stopped Session is an execution state. Check both repositories in [Code Delivery](/en/docs/code-delivery), then read the submitted content and validation before accepting the outcome. **Pin session / Unpin session** in the header changes your personal pinned list; it does not keep execution running or guarantee workspace retention. From a human's terminal or an external coding agent, choose the read that answers your question: ```bash aachat session read --project --team --decision aachat session read --project --team --submission aachat session read --project --team --last 50 ``` `--decision` returns a bounded view of purpose, latest final text, pending submissions, and child context. Read `gaps` and follow `next_read`: truncated text or unavailable artifact attribution is not complete evidence. Use `--submission` to reconcile one accepted instruction; take the exact `turn_id` from `data.submission.turn_id` in the original run/send receipt. It follows that submission's phase, not simply the latest turn. Runtime acknowledgement is not an independently observed start timestamp or a successful result. Follow its suggested read for transcript evidence. Both flags are mutually exclusive and belong to public `aachat`, not Session-scoped dispatch or `chat`. For ordinary transcript history, use `next.before` with `--before`. ### Tool output and results you can read later Current aachat versions do not store tool output in newly saved permanent Session history. Tool inputs, identifiers, and status are retained, but size limits can also omit inputs, so full text is not guaranteed. Output or diffs visible live during execution may be absent when you reopen history. History reads and searches cannot recover output that was not saved. This policy alone does not establish that all older history or data in other storage has been deleted ([storage boundary](/en/docs/trust-boundary)). Missing output proves neither that the tool returned an empty result nor that execution succeeded or failed. Reconcile the saved status and final response with the actual artifacts, and leave results you cannot verify explicitly unconfirmed. Do not rerun an operation solely to fill in missing output. Put confirmed results, judgments, sources, and remaining uncertainties needed for later decisions into independently readable artifacts such as [Shared Documents](/en/docs/shared-documents), and point to them from the Session's final response. Select the necessary evidence and exclude secrets instead of copying raw output wholesale. Adding a document does not recover output that was never saved. ### Search saved transcripts A Session agent can search as follows with a chat/API version that supports it. If `chat session read --help` does not list `--match`, check the installed version. Public `aachat session read` does not have this flag. ```bash chat session read --project / --match 'cargo test' --last 20 ``` The scope is searchable text actually retained, such as saved conversation and tool inputs in **both the specified Session and the specified Project**. Unsaved or omitted output and image contents are not searchable. Matching trims surrounding whitespace and treats the remainder as one case-insensitive literal using Unicode case folding. It does not split whitespace-separated terms or use wildcards or regular expressions; an empty value after trimming is rejected. `--last` limits the number of excerpts (default 50, maximum 100). The newest matches are selected and returned in history order. One message may yield several excerpts, so the count is neither a message count nor a total match count. Each body excerpt is at most 600 Unicode scalars, with a separate tool identification header in some cases. Excerpts are not full text, and an ordinary read does not guarantee full tool output either. Pass an ordinary read's `next` to `--before` to search history older than that cursor. Match responses have no next-page cursor, and scanning stops at the limit; neither all history nor all matches are guaranteed. Narrow the search text if the result reaches the limit. An empty successful response means no match in saved searchable text for that Project and search window. Read failures such as 403, 404, or timeout are not a negative search result ([Troubleshooting](/en/docs/troubleshooting)). ## Related pages - The agent repo structure and when changes take effect (next session after push): [Agents](/en/docs/agents) - Project status and member management: [Projects](/en/docs/projects) - Starting from an external system with a credential: [External Session Runs](/en/docs/external-session-runs) - Triage when sessions will not start or responses stall: [Troubleshooting](/en/docs/troubleshooting) - The full command surface: [CLI](/en/docs/cli) --- # Start Sessions from an External System > The credential, HTTP request, idempotency, and rotate/revoke contract for safely starting a new session with a fixed agent, mode, and repo from GitHub Actions, CI, or a webhook. # Start Sessions from an External System External Session Run lets GitHub Actions, CI, a webhook adapter, or another system outside aachat send new work to a project agent. It is separate from interactive `session run` and from scheduled starts configured inside the WebUI, and has its own credential boundary. Before using it, confirm that the project is active, the target agent is an active Admin / Collaborator, and the owner's runtime can start sessions. ## Create a credential Open **Start from external app** on the project screen and choose an agent. Only the current human owner of that agent can manage its credentials, and that human must also be a project Admin / Collaborator. Creation fixes the following authority: - credential name - target agent - a launch mode advertised by that agent - workspace repo resolved from the project / team - optional expiry After creation, the screen shows `AACHAT_API_URL` and `AACHAT_API_KEY`. **The API key is shown only then and cannot be read back.** Store it in a secret store or untracked `.env`; never put it in a repo, log, or document. ## Send a request ```bash curl -fsS -X POST "$AACHAT_API_URL?wait=started" \ -H "Authorization: Bearer $AACHAT_API_KEY" \ --json '{ "text": "Run the external check and report the result.", "idempotency_key": "github-run-12345" }' ``` - `text` is the request delivered to the session - `idempotency_key` is a stable unique ID for the external event. Retrying the same request with the same key does not start a duplicate session - Reusing an `idempotency_key` with different text, metadata, or execution context is a conflict. Use a new key for new work - `?wait=started` waits for the runtime to acknowledge session start. Without it, the response returns when the request is accepted - An optional `metadata` object can correlate the invocation with the external event Use response `status`, `session_id`, and `web_url` to confirm the start. A request may be accepted and later fail to start at the runtime, so inspect the existing invocation before retrying the same work. ## Rotate, revoke, and expiry - **Rotate** issues a new token and invalidates the old one. Update the caller's secret immediately - **Revoke** stops new requests through that credential - An expired credential cannot accept new work. Issue a new credential and update the caller for a new invocation New work through an otherwise active credential is rejected when the project is not active, its creator is no longer a project Collaborator, the agent's owner changed, or the agent is no longer a project Collaborator. A credential never bypasses current membership. An exact retry can still return an already-accepted invocation after revocation, expiry, or a membership change, as long as the token is still recognized. These checks protect new work; they do not erase earlier acceptance. Rotation replaces the token while keeping the credential ID: the old token is no longer recognized, so retry with the new token and the same key/body. A revoked or expired credential cannot be rotated. A newly created credential has a different ID and a separate idempotency scope. ## Connect a CI event without duplicate work Give each intended piece of work a stable event key. For GitHub Actions, a repository, workflow run ID, and operation label identify one request. Do not include the retry attempt if rerunning a CI job should only recover the same invocation. Include an explicit new work identifier only when you intend to start another Session. The following shell step requires `curl` and `jq`. Configure `AACHAT_API_URL` and `AACHAT_API_KEY` using the credential screen's values, and inject them through the CI environment. It constructs JSON safely rather than interpolating event text into a JSON string. Keep the same body and credential for transport retries. ```bash # Supply AACHAT_API_URL and AACHAT_API_KEY through your CI secret settings. # GITHUB_REPOSITORY and GITHUB_RUN_ID are provided by GitHub Actions. set -eu request_file="$(mktemp)" trap 'rm -f "$request_file"' EXIT jq -n \ --arg event_key "github:${GITHUB_REPOSITORY}:${GITHUB_RUN_ID}:source-review" \ --arg repository "$GITHUB_REPOSITORY" \ --arg run_id "$GITHUB_RUN_ID" \ '{text: "Review the public sources and report findings in this Project.", idempotency_key: $event_key, metadata: {repository: $repository, run_id: $run_id}}' > "$request_file" curl --silent --show-error --fail-with-body \ --request POST "$AACHAT_API_URL?wait=started" \ --header "Authorization: Bearer $AACHAT_API_KEY" \ --header 'Content-Type: application/json' \ --data-binary "@$request_file" ``` Do not enable shell tracing (`set -x`) or print the credential environment. Keep metadata to non-sensitive correlation information: it is part of the request stored by the server. The idempotency key must be nonblank and at most **200 UTF-8 bytes**; metadata must be an object that serializes to at most **8192 bytes**. Shorten a key deliberately if the repository and label make it too long, preserving uniqueness. A key is scoped to its credential ID. The same key with the same normalized text, metadata, fixed launch specification, and workspace context returns the existing invocation. Metadata object key order alone does not make a different request. Changing any of those contents conflicts. A different credential is not a way to retry the same invocation safely. ## Read acceptance, start, and failure separately | Response state | Meaning | Next step | |---|---|---| | `accepted` | The server recorded the invocation; start is still pending | Preserve `invocation_id` and the exact request. An identical retry can retrieve the current result | | `started` | The runtime acknowledged Session start | Follow `session_id` / `web_url` and inspect the actual result in the Session | | `failed` | The invocation could not complete startup | Read `failure.code` and `failure.message`, correct the cause, and use a new key only for a deliberate new attempt | `wait=started` has a bounded wait and may still return `accepted`. It does not wait for task completion. HTTP success alone does not mean the work succeeded, and `web_url` can be absent until a Session is bound. Store the returned invocation ID and Session link as correlation evidence in your CI output, then check the Session's work and deliverables in aachat. On a network timeout or lost response, retry the **exact request with the same credential and key**, rather than generating a new timestamp key. This can recover the existing invocation. A failed invocation remains that invocation; repeating its key does not create a fresh attempt. A wrapper that needs to retry actual failed work must make that choice explicit and inspect the previous result first. ## Diagnose the failing layer - For an unauthorized, expired, or revoked credential, check the caller's secret and the credential screen. After rotation, replace the caller's old token. Never paste a key into a support message. - For an authority failure, check that the Project is active and that the human owner and Agent still satisfy the Project membership rules. A key cannot add membership. - For a validation error, check nonempty text, key length, metadata shape/size, and the `wait` value (`accepted` or `started`). - For an idempotency conflict, compare the original request and execution context. Do not silently turn it into a new key and duplicate work. - For startup failure, check the owner's runtime, fixed launch configuration, and access to the fixed workspace repo. Correct those prerequisites before deliberately starting again. If a different target or launch context is required, create an appropriate new credential. Rotation, revocation, and expiry control use of a credential; they are not Session cancellation or rollback of work already started. Use the [Session controls](/en/docs/sessions) to manage that work. This endpoint starts a Session and does not publish or run a Workflow from a webhook. ## Related pages - Interactive sessions and workspaces: [sessions](/en/docs/sessions) - Team / project roles: [teams](/en/docs/teams), [projects](/en/docs/projects) - Server storage boundary for credentials: [trust-boundary](/en/docs/trust-boundary) - Start failure diagnosis: [troubleshooting](/en/docs/troubleshooting) --- # Team — Visibility, Roles, and Member Lifecycle > This page covers public/private teams, Discover Teams, Owner/Admin/Member authority, invitation and removal lifecycle, deletion, and the credential boundary of the default workspace repo. # Team — Visibility, Roles, and Member Lifecycle A team groups humans, agents, projects, and company context. This page is canonical for the team's visibility and member management. Project Admin / Collaborator / Viewer are separate roles covered in [Projects](/en/docs/projects). ## Create a team From WebUI Home → Teams → **Create Team**, set a name, vision, visibility, and optional default workspace repo. The CLI is `aachat team create --repo `. - **public**: Discover Teams shows the name, vision, and member count without sign-in - **private**: the team is not exposed to non-members - A personal team (`~`) is created automatically at sign-in. It is a fixed personal surface and does not follow all ordinary team publication, deletion, and leave behavior Public visibility publishes the existence of the team. It does not expose private projects or member-only Timelines and Documents. ## Team roles | Role | Primary authority | |---|---| | **Owner** | Team settings, role changes, member removal, and team deletion | | **Admin** | Team settings and invite-link management. Cannot change/remove an Owner or perform owner-only operations | | **Member** | Uses projects and team surfaces to which they have access | A team must keep at least one Owner; the last Owner cannot be demoted or removed. Only Owners change roles and remove members. Owners / Admins issue invite links in Team Settings, and a human opening one joins immediately as a Member. Rotate a link if it may have leaked. ## Leave, removal, and deletion - When a human leaves or is removed, their project memberships in the team and the project assignments of agents they own are also removed - Leave Team is not shown to an Owner. Establish another Owner and change roles first - Team deletion is an irreversible Owner operation. Usable access to the team's projects, messages, and agent assignments is permanently lost, with no restore path. Confirm project assets and member migration first - A personal team cannot be left Use a team invite for an ongoing colleague, a project join link for a project-only collaborator, and client entry for a short-term client without a GitHub account ([Projects](/en/docs/projects), [Connected Repo](/en/docs/connected-repo)). ## Default workspace repo A team default workspace repo is used when no more specific repo is set on the project or session. [Sessions](/en/docs/sessions) is canonical for repo resolution order. This setting does not share or grant GitHub access. Every member running a session needs their own GitHub credential, repo read/write permission, and organization SSO authorization where required. The GitHub App used by the WebUI Repository tree and an `aachat init` connected repo are separate systems. ## Related pages - Project roles and join links: [Projects](/en/docs/projects) - Workspace repo resolution: [Sessions](/en/docs/sessions) - Screen locations including Discover: [WebUI](/en/docs/webui) - Client entry and connected repos: [Connected Repo](/en/docs/connected-repo) --- # project — where the context of work lives > Project kinds (project / stream / dm), status and executability, Project Timeline input and output, member management and invitations, and Asks. Answer questions about projects from this page. # project — where the context of work lives A project is the unit of work — the place where requests, history, decisions, and deliverables accumulate. In the two-layer context structure of [Concepts](/en/docs/concepts), a project is the "context of work" layer. It is the counterpart concept to an agent's own memory (the agent repo), so answer questions about which of the two something belongs in based on [Concepts](/en/docs/concepts). Project members are both humans and agents. Members of the same project can see all conversations and deliverables within that project. That is why handing work off between agents requires no re-sharing of information. ## project kinds There are three project kinds. | kind | Purpose | Participants | |---|---|---| | `project` | A regular project for getting work done | Chosen members (humans and agents) | | `stream` | Team-wide announcements and casual chat | All human members of the team | | `dm:` | One-on-one with an agent | You and that agent | A **stream** exists exactly once per team and is created automatically when the team is created. It is human-only: agents cannot join, requests cannot be issued there, and agents can neither view it nor be mentioned in it. It cannot be deleted, its name and settings cannot be changed, and members cannot be added or removed (it follows the team's membership as-is). An `@name` mention delivers a notification to that person's Feed. Use it for discussion before something becomes a project, cross-team announcements, and casual chat; write anything an agent should read in a project. Streams are excluded from search (`find`). A **dm** is created automatically in the owner's personal team when an agent is created (or cloned from Discover). Only the owner can see its contents. Sending with the agent selected as the target starts a session; sending without a target just leaves a regular message and does not start a session. It is suited to trial requests and agent tuning before bringing work into a project. Issue work requests in a regular project from the start. stream and dm are places for conversation before — or instead of — bringing something into a project. ## Status and executability A project has four statuses, and new projects start as `active`. **Starting a new Session or sending follow-up instructions requires an active Project with no Archive in progress.** | status | WebUI label | Intended state | |---|---|---| | `planning` | Planning | Not yet started | | `active` | In progress | In progress (default) | | `completed` | Done | Finished | | `archived` | Archived | Put away | In a non-active project, running sessions and sending follow-up instructions, sending messages, **viewing the timeline and Shared Documents**, adding or changing members, and editing join links all become unavailable. The project is also excluded from search, mention lists, and Inbox (unread). Archive preserves history. A Project can be archived from planning, active, or completed, but returning it to active does not restore cancelled work. Check the effects in the steps below before archiving. A Project Admin can choose Done from the status menu in the header. First review and accept the results using “Review results and complete the Project” below. Done (completed) records completion after reviewing results; Archive stops work and puts the Project away. A successful Archive does not establish that the outcome was achieved. ### Check the effects before archiving 1. **As a Project Admin, open Settings → Danger Zone → Archive.** The Archive action shown in the sidebar, or **Archived** in the header’s status menu, opens the same confirmation. Projects in planning, active, or completed can be archived. Opening the confirmation does not start the operation. 2. **Read the counts of Workflow Runs to cancel and Workflow Sessions to stop.** Work already executing in ordinary Sessions is not forcibly stopped. However, this Project’s unexecuted reservations are cancelled, future scheduled follow-ups are ended, and active Triggers are paused. Check that these effects are appropriate for the work. 3. **Resolve any blocking child Projects or Workflow Sessions first.** Review an active child’s results before marking it Done, move it to a parent that meets the requirements, or check its effects and archive the child. For a Workflow Session that also covers other Projects, finish its work and reopen the confirmation. See [Troubleshooting](/en/docs/troubleshooting) for reparenting requirements and the different rejection reasons. 4. If you accept the effects, choose **Archive**. The button reads **Stop and archive** when there are running or waiting_for_decision Runs, or Workflow Sessions to stop. A button labelled Archive can still cancel Runs such as those in attention_required, so read the counts. Before submitting, use Back to leave. **Once accepted, cancellation continues even if you close the dialog.** If Trigger configuration/version, reservations, or other work changes and the confirmation has changed, reopen it and check the updated effects. 5. **Archive in progress** means accepted, not completed. Check Remaining Runs and Sessions waiting to stop. The Project becomes Archived after the Workflow Runs reach a terminal state and Workflow Session termination is confirmed. During processing, even if the status still shows active, new execution and follow-up instructions are blocked, as are status changes and deletion. If an error and Retry appear, follow [the Archive recovery steps](/en/docs/troubleshooting). ### Review history or start work again After Archive completes, an Admin can choose **Unarchive** in Settings to return the Project to active (In progress). From the CLI, find it in the list of all statuses: ```bash aachat project list --status all aachat project update --status active ``` To return from Done, choose In progress in the header or use the same CLI command. If the Project has a parent, the parent must also be active with no Archive in progress. If this Project is still being archived, first confirm that Archive has completed. Restoring the Project does not automatically restart cancelled Workflow Runs or unexecuted reservations, ended scheduled follow-ups, or paused Triggers. Read the preserved history and results, request only the work still needed, and check each recurring task’s settings and state before configuring or resuming it individually. Permanent deletion is "Delete" in the "Dangerous Actions" card in Project settings (CLI: `aachat project delete --yes`) and cannot be undone. Only active projects can be deleted. When in doubt, choose archive. ## Starting a project Sign in to the team. If you choose an agent Lead, check that the agent you own has an authenticated, online runtime. See [Setup](/en/docs/setup) for first-time preparation. 1. Open **Projects → New Project**. Leave Parent project unset for your first independent piece of work. Creating a child Project requires an active parent where you are an Admin or the current Lead. 2. Choose a **Lead** responsible for the result. Choose an active human member of the team or an agent you own. For a child Project created through this human entry point, the chosen Lead is added to the parent at creation if needed; prior parent membership is not required. 3. Write the goal, background, expected deliverables, and constraints in **Brief**. Use a **Name** of 2–30 lowercase letters, numbers, or hyphens, excluding the reserved names `stream`, `dm`, and `repo`. The optional catalog note (description) does not replace the Brief. 4. Submit **Create** once. An agent Lead gives “Project created; setup session accepted” and receives a setup Session. A human Lead gives “Project created; human Lead notified” and receives a notification. 5. For an agent Lead, open the accepted Session from the Project's Work Panel and check the Brief, response, Asks, and directions to deliverables. For a human Lead, use the notification to review the Project and Brief, then begin the work as a human. Verify creation acceptance, work progress, and acceptance of results separately. The agent Lead prepares PROJECT.md and an initial REPORT.md from your Brief and relevant context, using Asks when information is missing. After incorporating the answers and completing both documents, it ends the setup Session. The Project and its Lead remain in place; you choose and request the next work. For an agent Lead, creation already accepts the setup request, so do not repeat it in the composer. See [Sessions](/en/docs/sessions) for a later request or additional instructions for the same work. If Create is disabled, the Lead is missing, or work does not progress after acceptance, use [Troubleshooting](/en/docs/troubleshooting). Required CLI arguments and Brief input are in [CLI](/en/docs/cli). ### Starting from a Project Template **Discover → Project Templates** starts from an existing work pattern and is a separate entry point from regular Project creation above. Choose a team and new project name on a public template's detail page. This creates a fresh project with the template's root document and generated Project HTML `index.html`. Advertised folder structures and document templates are not currently applied. Agents are not assigned by the template; assign the needed agents after creation. A Project Template is a catalog blueprint for a new, independent project; the project does not stay synchronized with it. It is distinct from a [Shared Document template](/en/docs/shared-documents) that installs kind definitions. ### `PROJECT.md` is the project's stable contract A project's `docs/PROJECT.md` is the Project Contract / Context Router that an agent reads first, on demand, when it needs context. Keep only Purpose, Outcome, Outputs, decision principles and boundaries, a curated Context Map, and a stable Approach. Do not put progress, assignments, handoffs, logs, or unresolved notes there. The Context Map is a reading route to important canonical sources, not a document inventory. Use generated `docs/index.md` to discover the full catalog. A handoff remains in the session transcript by default; use a message for a short project-wide share, or a normal Shared Document when it is independently worth rereading ([Shared Documents](/en/docs/shared-documents)). ## Project Timeline The Project Timeline is where a project's requests, history, and decisions remain in chronological order. The WebUI main timeline shows messages and Ask cards. Shared-document create/update is discovered in the Documents surface ([Shared Documents](/en/docs/shared-documents)); sessions are discovered in the Work Panel. The CLI `aachat project read` still mixes document and session lifecycle items into `items[]` for agents. The Timeline is not a notification that scrolls away; it is a record that stays. The source of truth for deliverables lives in Shared Documents, but the intent of requests, the course of decisions, and the exchanges remain on the Timeline, where the next session and humans can consult them. Results accumulate in three places: Shared Documents, the Timeline, and the agent repo (the flow of company assets in [Concepts](/en/docs/concepts)). When a human needs to notice a document update, write a short message with a WikiLink. Date and unread separators show your position; **Load older** reads history, and new arrivals can be followed at the latest edge. Session turn completion text is stored only in the session transcript and is not automatically posted as a Timeline message. Project-wide notification requires explicit `chat send` / `project send` ([Sessions](/en/docs/sessions)). ### Rendering Timeline messages are rendered richly as Markdown. | Syntax | Display | |---|---| | Headings, lists, tables, quotes, checklists | Rendered as normal Markdown | | Code blocks | Syntax highlighting via language tag. With a copy button | | Mermaid | ` ```mermaid ` blocks render as diagrams. Follows the light/dark theme | | mindmap / brainstorm | Structured blocks display as a collapsible tree and idea cards respectively (how to write them is in [Markdown blocks](/en/docs/markdown-blocks)) | | WikiLink | The `[[aachat/projects///docs/...]]` form becomes a clickable chip that opens that document | | @mention | Highlighted in color. **Mentions are notification-only, not a session execution trigger** (execution is in [Sessions](/en/docs/sessions)) | | External links | Become links that open in a new tab | Write a WikiLink in a request body and the agent can read the document at that path to build context. Attached images display on the timeline and enlarge on click. ### Input and output Timeline input and output are the CLI's `aachat project read` / `aachat project send` (agents use the equivalent `chat` commands inside a session). ```bash aachat project read aachat project send "message body" aachat project send "reply body" --reply-to ``` What you pass to `--reply-to` is not a message ID but `seq`, the sequential number within the project (included in the output of `aachat project read`). A message posted as a reply shows a quote of the message being replied to; clicking the quote jumps to the original message. In the WebUI, open the inline thread from a root or reply, then reply from the bottom composer. ### deep-link Opening a project URL with `?msg=` appended auto-scrolls to that message and highlights it temporarily. Messages inside a session (Workspace panel) use the form `?session=&msg=`. URLs opened from search results and Feed notifications use this form, and the parameters are removed from the URL automatically once display completes. ## The project's deliverable surfaces A project's deliverables go to a different surface per type. The directories under `aachat/projects///` in the workspace correspond to the surfaces. | Surface | Path | What goes there | Details | |---|---|---|---| | Shared Documents | `docs/` | Documents to read for decisions and handoffs (the source of truth) | [Shared Documents](/en/docs/shared-documents) | | Project Media | `media/` | Finished images, videos, and PDFs | [Media](/en/docs/media) | | Project HTML | `html/` | Browser-viewable prototypes and reports | [HTML](/en/docs/html) | ## Member management and invitations Both humans and agents become project members. **Humans** join via invite links. Only humans can use join links. - **Team invite link** (Team settings → Invite Links; Owner / Admin only): welcomes someone as a member of the team. Joiners are granted the Member role - **Project join link** (project settings → Join Link; manageable by project Admins only): joins that project only. The granted role can be chosen from Viewer / Collaborator / Admin. Because the team's other projects are not visible, this suits inviting outside collaborators per engagement With either link, whoever opens it joins immediately at the press of a button, with no approval wait. If a link may have leaked, invalidate the old one with Rotate (reissue). **Agents** are added from project settings (or the Add Agent button on the project screen). There are three project roles: Admin / Collaborator / Viewer. | Capability | Admin | Collaborator | Viewer | |---|---|---|---| | View messages and documents | ○ | ○ | ○ | | Send messages | ○ | ○ | − | | Add your own agents | ○ | ○ | − | | Project settings, member management, join link management | ○ | − | − | | Archive and delete the project | ○ | − | − | Agents can be given the Admin role, and an agent Admin can add another agent as Admin. However, a project must keep **at least one active human Admin**. Demoting or removing the last human Admin is rejected even when an agent Admin exists. Removing a human member from a project also removes the participating agents that person owns. ## Asks Asks are the mechanism by which a session agent hands decisions and information that only a human can provide over to humans as questions. **Session agents must always use Asks, not Shared Documents frontmatter.** Outside agents ask the human in their own conversation with the host ask. The question, background, answers, and change history are stored on the Ask itself, so a decision can be reached without creating a document. **An Ask is immutable, and answers remain as revisions.** Changing an answer adds a new revision, and the earlier decision also stays in the history (Change history). Answered and canceled Asks are never deleted; they remain as the project's decision log. - **Where they surface**: an Ask card on the project timeline, the Asks panel in the sidebar (with an unanswered-count badge), and Home Feed notifications. Session agents create and wait with `chat ask`. The outside CLI is `aachat ask list|show|cancel|answer` - **Input**: the assignee is an active human project member. Supply either no choices (free answer) or 2–5 choices. Even with choices, the human may submit a free answer outside them - **Conflicts**: if another screen saved an answer first, explicitly compare the server answer with your draft and choose to use the latest, overwrite with your answer, or discard the draft. The WebUI does not silently overwrite - **scope**: `Project` scope is a normal question that can wait for an answer across turns. `Session` scope is a question meaningful only in the current session's context; it gets a `Session` badge in the WebUI - **Cancellation**: an open Ask can be canceled with a reason by its creator, its assignee, or a project Admin. It is auto-canceled, with the reason kept in the history, in these cases — the Session-scope source session ended / the project is no longer active / the assignee is no longer a project member ### Save an answer and check continuation Check that the Project is active and you are the Ask's assignee or a Project Admin. Open **Asks** or its Timeline card and read the question, background, scope, and source Session. The panel groups Asks from the same source Session into one card. 1. Select an option into the draft, if provided, and edit a free answer as needed. **Selection alone does not save it**. Use **Save answer** or **Save only**, as shown on your screen. 2. Check the saved answer under **Answered**. Changes remain as revisions in **Change history**. If a conflict appears, compare the latest answer with your draft before using the latest or explicitly overwriting it. 3. If the source Session registered this Project Ask with `chat wait --all --ask `, save and wait for continuation. Find the accepted wait ID and target set in the Session transcript. When needed, a Session agent can inspect it with `chat wait show `. 4. **After every registered target settles**, one continuation turn is accepted for the source Session. If the wait also includes other Asks, Sessions, or Workflow Runs, those must settle too. Check continuation acceptance separately from the results the agent produces using your answer. For a registered wait, do not also use **Send & continue** or **Send N answers to session**. Continuation may be delayed until the next check, which runs on a 30-second cycle. This does not guarantee a finished response within 30 seconds. On a version with the corresponding API, database changes, and Web UI delivered, an answer covered by its source Session’s own wait shows **Answer saved. The session will continue when all wait conditions are met.** An answer whose automatic continuation has been accepted shows **Chat continuation accepted**. Answer saving, continuation acceptance, the agent reading the answer, and a successful result are separate: neither display proves reading or success. On versions without these displays, check the registration receipt and source Session above; absence alone does not mean no wait was registered. When the same card mixes automatic and manual continuation targets, **Send N answers to session** counts and sends only answers needing manual delivery, so its count can be smaller than the number saved. If all answers are automatic targets, no additional manual send is needed. A supported server also checks Ask answer sends from older screens: when all answers are automatic targets, a successful response creates no new turn or message. This does not guarantee deduplication of all ordinary follow-up instructions. For a normal Project Ask without a registered wait, saving alone does not start a new turn. If the same work needs to continue, check the source state; if running, use a manual send action once to deliver saved answers as a follow-up. For stopped work, see [Sessions](/en/docs/sessions). If registration is unclear, check its acceptance first instead of combining two continuation paths. Cancellation also counts as settled for a wait; it is not approval or a successful answer. A later answer revision does not fire the same wait again. If the next stage needs the change, deliver it as an additional instruction for the current work. Do not treat Session-scope Asks or Workflow decisions as ordinary Project Ask waits. If saving or continuation cannot be confirmed, use [answer and continuation recovery](/en/docs/troubleshooting). Automatic acceptance covers revisions up to the answer revision used for that acceptance. A revision changed after acceptance, an answer without a wait from its source Session, or an answer awaited only by another Session is not necessarily covered by the same automatic continuation. Read the revision in **Change history** separately from the current continuation display, check the source Session’s state, and choose any additional instruction needed. Do not assume changing an answer always restarts work automatically. For **Awaiting results**, **Wait completed**, and notification delivery after answering, see [Sessions](/en/docs/sessions). Use [recovery](/en/docs/troubleshooting) to choose read Retry, Retry delivery, Session Resume, or Workflow Step retry. ## Review results and complete the Project While the Project is active, the person accepting its results checks the following. Being Lead and holding the human Project Admin role are separate responsibilities. 1. Open `PROJECT.md` from **Docs** and compare the deliverables with its Outcome and Expected Outputs. 2. In the same Docs view, open `REPORT.md` by its title. Read the results, verified evidence, remaining gaps, and next steps; also inspect linked deliverables and Session transcripts. 3. If the REPORT is missing or out of date, ask the current Lead to create or update it. Its location is the Project's `docs/REPORT.md`, with the uppercase filename. See [Shared Documents](/en/docs/shared-documents) for ownership and sync. 4. After accepting the results, a **Project Admin selects Done from the header's status menu**. Check that the status becomes Done (`completed` in the CLI). An active Project with a Lead cannot complete without a REPORT. Its presence does not automatically establish quality or goal attainment. Review the content before completion instead of creating an empty REPORT just to pass the condition. If the menu is unavailable, ask an Admin. If “Create or update Current report, then retry completion.” appears, follow [REPORT recovery](/en/docs/troubleshooting). See “Status and executability” above for revisiting content and reactivation. ## Change the Lead and inspect delegated Projects A human Project Admin can open **Settings → General**, choose **Lead**, and save, or send a separate CLI update: ```bash aachat project update --lead @ --team aachat project delegations --team ``` Choose an active human Team member or an Agent you own. Membership checks also cover the active direct parent and children; if the required membership cannot be added under your authority, resolve that access first. Do not combine `--lead` with description or status changes. The new Lead owns future REPORT updates. Existing REPORT text and Session ownership are not rewritten, and changing Lead does not itself launch replacement work. Active time Triggers created by the previous Agent Lead to start itself in this Project are marked completed; inspect scheduled work and deliberately arrange the next request. `delegations` returns direct child Projects and their current REPORT summary/version, or marks a missing REPORT. Inside a Session, read `items` and the available access flags from `chat project delegations ` to inspect the child's actual results. A completed child or a summary is not a substitute for reviewing its deliverable. ## Move a child with a handover Brief Reparent when a child's work belongs under another parent. A human must be Admin of both old and new parents. They must be ordinary Projects in the same Team; the child must be planning or active, the destination active, and the relationship must not form a cycle. A root Project cannot be moved this way. Resolve Archive in progress before moving anything. ```bash cat > handover.md <<'BRIEF' Purpose: Move the customer-guide work under the documentation Project. Current result: The draft is saved in this child's Docs; review it before editing. Next outcome: Complete the bilingual guide and record validation in REPORT. Boundary: Preserve this child's artifacts. Do not publish without the required approval. BRIEF aachat project reparent --parent --team --stdin < handover.md aachat project delegations --team ``` Replace the names and Brief with the real work. stdin is plain Markdown text, not JSON. Read the returned old/new parent, disposition, and `lead_action`. An agent child Lead receives a handover Session; a human child Lead receives a signal. `completion_state: accepted` is handover acceptance, not completion of the child's work. The parent relationship and necessary Lead memberships change; existing Sessions do not automatically gain rewritten coverage. Inspect the new parent's direct children and the child's REPORT, then use [reparent recovery](/en/docs/troubleshooting) if the request was rejected. ## Confirm deletion has completed Delete is irreversible and requires removing or relocating **all** child Projects first, including inactive ones. After confirming the Project, `aachat project delete --team --yes` returns deletion acceptance and an operation ID. Keep that ID. Acceptance does not mean the data has already been erased. Return to the WebUI's **Deleting** state to read progress; **Deletion failed** exposes the error and **Retry**. An authorized Team administrator can retry the same operation after resolving the cause. Integrations can read `GET /v1/teams/{team}/project-deletions/{operation-id}` using the appropriate identity ([Developer API](/en/docs/developer-api)). Re-read the operation until its completed state; a missing view or an unsuccessful read is not proof of deletion. Cleanup processes Workflows, Database, HTML, Media and attachment resources before final Project-record removal. Accepted database operations and unresolved migrations can delay cleanup. Public assets and shares should not be assumed erased at request acceptance, nor should every ordinary Session process be assumed to stop instantly. Review in-flight work before choosing Delete; use Archive when you may need to restore the Project. See [Database](/en/docs/database), [Media](/en/docs/media), [HTML](/en/docs/html), and [deletion recovery](/en/docs/troubleshooting). ## Related pages - How project relates to the session and agent concepts, and the two-layer context structure — [Concepts](/en/docs/concepts) - Session start conditions and lifecycle, delegation between agents — [Sessions](/en/docs/sessions) - The Shared Documents contract (source of truth and projection, WikiLink, kind) — [Shared Documents](/en/docs/shared-documents) - WebUI screens and operations — [WebUI](/en/docs/webui) - Team roles and visibility — [Teams](/en/docs/teams) - CLI command details — [CLI](/en/docs/cli) --- # Company — Concepts, Entities > Share decision criteria through Concepts and map your company with Entities. Learn registration, proposals, permissions, hierarchy, and when to use Meetings. # Company — Concepts, Entities An aachat team holds shared context about the company itself, outside any individual piece of work (project). There are two layers. Concept's internal model (kind, semantic axes, revisions, reviews, links, similarity gate) is canonical in [concept-registry](/en/docs/concept-registry). Entity's internal model is canonical on this page. | Layer | Content | Where in the WebUI | Detail | |---|---|---|---| | **Concept** | The team's agreed Visions, Issues, and Policies. Every agent and human reads them as premises for judgment | Team sidebar "Concepts" | [concept-registry](/en/docs/concept-registry) | | **Entity** | A map of the persistent, concrete things that make up the company, decomposed to the level where building, improving, maintaining, or retiring each can be decided independently | Team sidebar "Entity" | Below on this page | ## Where to ask **No dedicated place is needed.** Ask an agent in any project session as with any other request, or ask an outside agent working in a connected repo. Session agents use session authority; outside agents read the same projected YAML and use `aachat registry`, which submits with the signed-in human's Team role. - **Read**: agents read published Concepts and current Entities and use them as premises for their judgment - **Proposing Concepts**: agents register new Concepts, revisions, and links as **proposals**. A proposal stays pending, and **a human reviews it on the Concepts screen in the WebUI** to accept or decline. Only accepted Concepts become the team's decision criteria (see [concept-registry](/en/docs/concept-registry)) - **Entities**: agents can register and update Entities (normal kinds only — see below) directly from a session. Unlike Concepts, these take effect immediately, without a proposal-and-review step In a connected repo, first require the Team projection in `aachat status` to be `healthy`, then read the two indexes, selected individual YAML, and matching Meeting bodies. Saving YAML is only a staged local edit; `aachat registry submit` is the explicit mutation boundary. The server applies the same authorization as a human WebUI action, so an Owner/Admin can submit sensitive Entity operations while a Member receives 403. ## Which layer to use - A desired state, durable problem, or reusable decision policy → **Concept proposal** - The concrete things that make up the company and where to focus improvement → **Entity** Company context is both an input and an output of agent work. An agent working in a project returns findings as Concept proposals; once a human accepts them, every later session works on top of those criteria. This is how the company itself grows as an asset (the company-level version of the company assets flow in [concepts](/en/docs/concepts)). ## Entity model — kind, sensitive boundary, hierarchy An Entity is an identifiable, persistent thing that concretely makes up the company. Entities form the Company map: they make it explicit what to build, improve, maintain, or retire, decomposed to a level where each improvement target can be selected independently. **Entity stores no properties, evaluations, goals, KPIs, owners, or progress.** Those belong to Concept (decision criteria), Project/Session (work in progress), and Message/Shared Document (evidence and detail). ### What should be an Entity Register something as an Entity when building, improving, maintaining, or retiring it can be decided independently. Create a child Entity only when separating it lets the company select that improvement target independently. Before registering a new Entity, check existing Entities and add one only when the existing Entity is too broad as an improvement target. Goals, work, abstract responsibility areas, feature classifications, and implementation parts such as UI, APIs, Workers, CLI commands, or database tables are not Entities unless they are themselves concrete parts of the company that are improved independently. ### kind — 9 types | kind | Note | |---|---| | `organization` | Normal | | `offering` | Normal. A product or service | | `media` | Normal. A channel or medium | | `community` | Normal | | `system` | Normal. An internal or external system | | `facility` | Normal | | `person` | **sensitive** | | `partner` | **sensitive** | | `agreement` | **sensitive** | ### The sensitive-kind boundary (important) The three kinds `person` / `partner` / `agreement` **cannot be registered or changed by an agent**. If an agent attempts to register one, rename it, change its status, move it, or link a Concept to it, the server rejects the request. The rejection message is returned in Japanese regardless of the agent's own language: > person / partner / agreement Entity の変更は human の操作が必要です。Project の human member に依頼してください。 > > ("Changing a person / partner / agreement Entity requires a human action. Ask a human member of the project.") Agents **can read** sensitive kinds — their name and structure are visible as part of the Company map. Writes are restricted to **human team Owners / Admins**; a regular human member is rejected as well. Don't infer an Entity's meaning or evaluation from what you read — only name, kind, status, and parent are stored. ### status — position in the company structure `planned` / `current` / `retired` describe only the Entity's position in the company structure, not the progress of a piece of work. - `planned`: planned as part of the company structure - `current`: currently part of the company structure - `retired`: no longer part of the company structure **Hierarchy constraint**: an active Entity (`planned` / `current`) cannot be placed under a retired parent. Before retiring an Entity, its active children must be moved or retired first. ### Hierarchy (parent/child) Entities form a tree. A parent is at most one Entity in the same team; self-reference, cycles, and cross-team parents are never allowed. Reparenting is done with a move operation. Don't represent more than one kind of structural relationship through parent (don't encode undefined relationships such as dependency, provision, or ownership into hierarchy or name). ### Concept link An Entity can link to a published Concept with `realizes`. This is the only relation type in v1. Don't link to an archived Concept or one with no published content. ### Change history Entity changes are recorded as append-only events: `registered`, `renamed`, `status_changed`, `moved`, `concept_link_added`, `concept_link_removed`. ## Register your first Entity Open Entity in the Team sidebar and inspect the Entity map and existing names. A customer help center operated over time is a candidate for `media`; the work to launch it belongs in a Project. This example uses a Session agent. Replace `acme` with your Team slug and `acme/help-center` with a Project where the Session has collaborator/admin membership and coverage. Do not overwrite an existing file with the same name. 1. Run `chat registry refresh --all`, then read `aachat/teams/acme/entities/_index.yaml`. Follow its `file` references to the individual records you need. 2. If the Entity does not exist, save this complete file as `aachat/teams/acme/entities/help-center.entity.yaml`. ```yaml format: aachat.team-entity/v1 id: null name: Help center kind: media status: planned parent: null realizes: [] ``` 3. From the workspace root, check syntax, inspect the operation, and submit it. ```sh chat registry check aachat/teams/acme/entities/help-center.entity.yaml chat registry plan aachat/teams/acme/entities/help-center.entity.yaml --project acme/help-center chat registry submit aachat/teams/acme/entities/help-center.entity.yaml --project acme/help-center chat registry refresh --all ``` `check` validates locally. Confirm that `plan` describes a single registration before running `submit`. After a successful write, you can read the current Entity with its server-assigned ID and see it in Entity. Use the file referenced by the index thereafter; preserve its assigned ID and path. Registering a `planned` Entity is not evidence that the service has launched. ### Change a parent or connect a Concept Refresh the existing `help-center.entity.yaml`, then change only `parent` to a relative reference to a real parent in the same directory, for example `parent: "./customer-services.entity.yaml"`. Repeat check → plan → submit → refresh, confirm the plan contains only a move, and inspect the new hierarchy in the UI. Use `parent: null` to return it to the root. Submit name or status changes separately from a move. To connect a Concept, first locate its published file, then add one reference such as `"../concepts/customer-self-service.concept.yaml"` to `realizes`. Submit this operation separately too. These filenames are examples: copy actual filenames from the index. An Entity's `kind` is not an editable field after registration. ## Actors and permissions | Operation | Session agent | Human Team Member | Human Owner / Admin | |---|---|---|---| | Register or change an ordinary Entity | With Project write permission and coverage | Allowed | Allowed | | Change a sensitive Entity | Not allowed | Not allowed | Allowed | | Propose a Concept, revision, or link | Proposal only | Proposal only | Propose and decide | | Publish / decline a Concept, decide on links | Not allowed | Not allowed | Allowed | When working as a human from a connected repo, first check that the Team projection is healthy in `aachat status`. Replace the commands in the Entity example with these. This CLI resolves the Team from the connection and file; it does not accept `--project`, `--team`, or `--via`. ```sh aachat registry check aachat/teams/acme/entities/help-center.entity.yaml aachat registry plan aachat/teams/acme/entities/help-center.entity.yaml aachat registry submit aachat/teams/acme/entities/help-center.entity.yaml aachat registry refresh --all ``` An outside agent using this CLI acts with the signed-in human's Team role. That is distinct from Session agent authority. A successful local plan does not guarantee server authorization. ## Where Registry and Meeting records live Registry has two indexes: `concepts/_index.yaml` and `entities/_index.yaml`. Concepts describe decision criteria; Entities describe the things that make up the company. A [Meeting](/en/docs/meetings) records discussion, decisions, and follow-ups in Markdown; it is not a third registry. Keep Project work products in [Shared Documents](/en/docs/shared-documents). A Session receives Meetings under `aachat/meetings/` as a read-only snapshot taken at startup. Registry YAML submission cannot create or correct them. Save Team-wide discussion as a Meeting; when part of it should become a reusable decision criterion, organize its evidence and propose a Concept. ## When a change does not apply - `mixed_edit` means that one file combines multiple operations. Preserve your draft and split it into changes such as name only or parent only. - For a sensitive-kind rejection, ask a human Project member to involve a Team Owner/Admin. Agent credentials cannot bypass this boundary. - For a retired-parent or active-child error, change the order of moves and retirements to satisfy the hierarchy rules above. - For stale state or an unknown result, follow [Registry recovery](/en/docs/concept-registry). Deleting YAML does not delete an Entity. Use `retired` to record that it is no longer part of the company. Do not commit generated `aachat/teams/` or `aachat/.state/` into the workspace repository. Saving a file alone does not write to the server. ## Related pages - Concept's types and lifecycle: [concept-registry](/en/docs/concept-registry) - Projects and work context: [projects](/en/docs/projects) - The WebUI as a whole: [webui](/en/docs/webui) - Terms: [glossary](/en/docs/glossary) --- # Concept Registry — types and lifecycle of decision criteria > Propose Concepts with evidence and adopt decision criteria through human review. Follow YAML examples, semantic fields, revisions, sources, links, and recovery. # Concept Registry — types and lifecycle of decision criteria Of the two registries in [Company](/en/docs/company), Concepts hold reusable team decision criteria. This guide explains how to propose a criterion with evidence, have a human review and publish it, and use it after adoption. Session agents read projected YAML under `aachat/teams//concepts/`, edit it, and propose changes with `chat registry`. ## kind — Vision, Issue, and Policy A Concept has one of three kinds. Choose it by the question the Concept answers. kind describes the content's role only; the semantic axes below (guidance_strength, etc.) are never derived automatically from kind. | kind | Question it answers | Use | |---|---|---| | `vision` | What state do we want to realize? | A future or state the company wants to realize | | `issue` | What currently prevents the Vision? | An important problem or gap the company must keep recognizing. Keep one-Project tasks and bugs in that Project | | `policy` | What do we prioritize when making this kind of decision? | A reusable decision or action policy for moving toward a Vision and addressing Issues | ## Semantic axes — 6 axes A Concept has 6 semantic axes independent of kind. YAML for a new Concept requires `scope` (domain + tags), `abstraction_level`, `time_horizon`, `guidance_strength`, and `maturity`. There is no automatic mapping such as `policy = governing`, and none is inferred from review counts either. | Axis | Values | Meaning | |---|---|---| | **guidance_strength** (how strongly it directs judgment) | `contextual` / `guiding` / `governing` | `governing` is used as a standard premise; deviating from it requires a reason. `guiding` should be followed in principle but can be overridden with a reason given stronger evidence or a conflicting governing Concept. `contextual` is used as input only when relevant | | **maturity** (how settled the revision is) | `exploratory` / `provisional` / `established` | `established` can be taken as a premise without re-examination. `provisional` should have its sources or latest reviews checked for high-impact decisions. `exploratory` may be included in published context but must not be restated as settled fact | | **abstraction_level** (scope of impact) | `foundational` / `directional` / `structural` / `tactical` / `operational` | Chosen by the scope of judgment it affects, never inferred from kind | | **time_horizon** (time frame) | `today` / `one_week` / `one_month` / `three_months` / `one_year` / `three_years` / `ten_years` / `enduring` | Every value except `enduring` requires an `expires_at`. After expiry, the Concept is excluded from current published context | | **domain** (area of applicability) | `company` / `organization` / `product` / `marketing` / `sales` | Choose the one broad area the Concept applies to. Team-internal classifications such as product, customer segment, or initiative go in `scope.tags` (up to 20) | | **applicability** (validity) | `active` / `expired` | A derived state based on `expires_at` | `governing + established` is a standard premise. `governing + provisional` must always be considered, checking sources or the latest review for high-impact decisions. `governing + exploratory` must always surface but must not be blindly followed. When governing Concepts conflict with each other, or an unresolved concern exists, don't pick a winner by score — read links, sources, and reviews and surface the unresolved conflict explicitly. ## Revision model A Concept is an immutable stack of revisions. The current revision is never rewritten directly; every change is recorded as a new proposed revision. - A revision's `status` is one of `pending` / `published` / `declined` - **A Concept can have at most one pending revision at a time.** A new proposal cannot be submitted while one is already pending - **Only humans (a team's Owner/Admin) can publish or decline.** Agents can only propose - **A decline requires a reason.** The next session should read that reason and calibrate its criteria before deciding whether to re-propose - Once created, a revision's content is immutable. Even changes to wording, sources, scope, or time horizon are recorded as a new revision Title is capped at 80 characters and description at 300 — they are an entry point, not a summary; the detailed evidence is read through sources (below). ## Reviews Both pending and published revisions can carry two kinds of review: `endorse` and `concern`. A `concern` requires a comment (an `endorse`'s comment is optional), and can be resolved with a resolution note. A published revision may still be read as a premise even with an open `concern`, but for decisions that depend heavily on that Concept, check the current revision's comments with `aachat_concept_reviews` and surface that the concern exists. Post a review with `aachat_concept_review`; projected `concepts/_index.yaml` carries only `open_concern_count`. ## Links between Concepts Concepts connect to each other through 8 directional relation types. | relation | Meaning | |---|---| | `realizes` | Realizes | | `constrains` | Constrains | | `addresses` | Addresses | | `measures` | Measures | | `supports` | Supports | | `contradicts` | Contradicts | | `refines` | Refines | | `depends_on` | Depends on | Links also have a lifecycle: `candidate` / `accepted` / `retired` / `rejected`. An agent can propose a link as a `candidate` by editing a Concept YAML link and running `chat registry submit`, but **it counts as a valid relationship for the Concept Map or for judgment only once accepted. Only humans (a team's Owner/Admin) can accept, reject, or retire a link.** When a published Concept would mislead future decisions, an agent can send an archive proposal to the Review queue with `aachat_concept_removal_propose`. For an accepted Link, remove it from the Concept YAML and run `chat registry submit --reason` to propose retirement. The Map does not change until a human accepts it, and history remains as an archived Concept or retired Link. ## Similarity gate on proposal `chat registry submit` for a new Concept automatically checks it against existing Concepts before registration. If a similar Concept is found, the proposal is not registered and `similar_found` is returned instead. - **A similar `published` Concept** — a decision criterion already exists. Withdraw, or switch to a link proposal or a review if there's a relationship. If the evidence reveals a durable gap, consider an `issue` + a `contradicts` link - **A similar `declined` Concept** — a human already rejected this. Read the decline reason (`status_reason`) and don't repeat the same proposal - **A similar `pending` Concept** — someone else's revision proposal is awaiting review. Don't submit a duplicate - A match against a `pending` or `declined` Concept the caller lacks permission to see returns no content or ID — only `hidden_match_count` - Only when the proposal is genuinely something different, resubmit with the returned `proceed_token` to register it anyway ## Sources A proposal is submitted with sources attached. There are 4 kinds. | kind | What it points to | |---|---| | `shared_document` | A Shared Document | | `session` | A session | | `external` | An external URL | | `human_decision` | A human decision (a note) | For a Session agent proposal, at least one source must belong to the Project selected by `--project`; other Project sources must also be in the same Team and Session coverage. A source's availability is shown as one of `accessible` / `restricted` / `unavailable`; don't guess at the content of a `restricted` source. `unavailable` means the source cannot currently be resolved; check for deletion or changes such as Session coverage. ## Archive / restore A Concept can be archived and restored. This is a WebUI/human-only operation and is not exposed as an agent-facing MCP tool. Don't create new links to an archived Concept or one with no published content. ## Free placement on the Concept Map The WebUI's Concepts screen has a map view. A card's position (`free_position`) can be moved by a human, or by an agent editing Concept YAML and running `chat registry submit`. Placement is shared soft context: proximity between Concepts can be a hint worth considering, but when it conflicts with sources, typed links, or semantic fields, those take precedence. Don't assert a relationship that appears only in placement as fact — if it looks important, treat it as a candidate for a link proposal instead. ## Propose a Concept with evidence Open Concepts in the Team sidebar and inspect existing Concepts and the Review queue. If the policy or a pending revision already exists, read it and its reviews before proposing a duplicate. Check the [Company permissions table](/en/docs/company) first. The following steps are for a Session agent with Project write permission and coverage. This example assumes that the `acme/help-center` Project has `docs/research/support-friction.md`, recording evidence that users could not find answers and explaining the proposed improvement. Replace the Team/Project, document kind, and document ID with real ones, read that evidence, and adapt the proposal. Do not submit a fictional source unchanged. Run `chat registry refresh --all` and read `concepts/_index.yaml`. Then save this complete new file as `aachat/teams/acme/concepts/customer-self-service.concept.yaml`. ```yaml format: aachat.team-concept/v1 id: null kind: policy title: Make answers easy to find description: Prefer clear, searchable help before adding support channels. scope: domain: product tags: - support abstraction_level: directional time_horizon: enduring expires_at: null guidance_strength: guiding maturity: provisional position: null sources: - kind: shared_document project: "acme/help-center" document_kind: research doc_id: support-friction restricted_source_count: 0 links: [] ``` `id: null` means a new registration. New Concepts require `position: null` and `links: []`; change position and links separately after publication. A time horizon other than `enduring` needs a future expiry as a quoted RFC3339 timestamp. Supply 1–20 sources; a new Concept has `restricted_source_count: 0`. From the workspace root, run these commands in order. ```sh chat registry check aachat/teams/acme/concepts/customer-self-service.concept.yaml chat registry plan aachat/teams/acme/concepts/customer-self-service.concept.yaml --project acme/help-center chat registry submit aachat/teams/acme/concepts/customer-self-service.concept.yaml --project acme/help-center chat registry refresh --all ``` `check` validates local YAML; it does not guarantee that a source exists or that the server will authorize the operation. Confirm that `plan` contains the intended single operation. After `submit` accepts the proposal, a Team Owner/Admin reads its evidence and changes in the Concepts Review queue, then publishes it or declines with a reason. Acceptance of a submission is not adoption of its content. Projected YAML represents published current content only. Do not resubmit because the file returns to its old content or a new pending proposal's text does not appear in the index. Check the receipt and Review queue. After human publication, refresh and confirm the current content matches the adopted revision. ### Separate revisions from position changes For an existing Concept, refresh the file referenced by the index's `file` field. To improve its description, edit `description`, preserve its existing ID and other required fields, and repeat check → plan → submit. Changes to meaning, sources, or scope create a new pending revision. If a revision is already pending, check its review outcome first. To change position only, replace `position: null` or the current position in the existing file with this block, leaving every other field unchanged. Do not save this fragment as the entire file. ```yaml position: x: 240.0 y: 120.0 ``` Repeat check → plan → submit → refresh. A position-only change applies directly; it does not approve the Concept's meaning. Coordinates must be finite, with each axis between -1000000 and 1000000. Editing meaning and position together produces `mixed_edit`, so submit them separately. ### Propose as a human from a connected repo Check that the Team projection is healthy in `aachat status`, then use these commands with the same YAML. ```sh aachat registry check aachat/teams/acme/concepts/customer-self-service.concept.yaml aachat registry plan aachat/teams/acme/concepts/customer-self-service.concept.yaml aachat registry submit aachat/teams/acme/concepts/customer-self-service.concept.yaml aachat registry refresh --all ``` This CLI has no `--project` or `--proceed-token`. The repo connection determines the Team; the server checks access to the Projects named in sources. Even an Owner/Admin's semantic submission is a proposal; publication is a separate decision. Clearing position to null is unsupported in the outside CLI. Removing an accepted Link also differs from an agent's retirement proposal: it is a human retirement operation requiring Owner/Admin and `--reason`. ## Follow sources and reviews Open Sources from a Concept Map card's menu to follow its evidence. Open the card's detail to inspect current content, reviews, and History. Distinguish pending content in the Review queue from the currently published content. For example, if the policy above is published but has an open concern that some languages remain hard to search, do not restate it as proof that all users can help themselves. `restricted` means you lack access to that source. Ask an authorized human to check the necessary evidence; do not infer its contents. For `unavailable`, the source cannot currently be resolved. Check for deletion or changed Session coverage and consider a revision with accessible evidence. The WebUI requires access to all sources before proposing a revision. In a Session agent YAML revision, preserve `restricted_source_count` and edit only visible sources. The server inherits restricted sources and checks the combined limit of 20. The index's `open_concern_count` does not explain concerns, so read the comments. Expiry excludes content from current decision context; it does not delete its adoption history. Both the Concept source model and Registry YAML `sources` accept four kinds: `shared_document`, `session`, `external`, and `human_decision`. It does not accept `project_message`. Inspect omitted sources in the WebUI instead of reconstructing them in the projection. For Session agent proposals, `external` or `human_decision` sources alone do not satisfy the Project-source requirement. ## YAML constraints and recovery Use UTF-8 and LF newlines, without unknown or duplicate keys, tabs, anchors, aliases, merge keys, or explicit tags. Preserve quoted UUIDs, timestamps, and file references. Use a meaningful lowercase ASCII slug and `id: null` for a new record; never rename an existing ID or assigned path. Do not edit generated `_index.yaml`. Each submit handles one file and one operation. Saving is not a server mutation, and deleting a file does not archive a Concept. | Situation | Next action | |---|---| | `mixed_edit` | Separate meaning, position, and individual links; plan one operation at a time | | `similar_found` | Read similar content and decline reasons. Only a Session agent that concludes this is a distinct proposal should add `--proceed-token` to the same submit | | Stale state / OCC conflict | Preserve the local draft, fetch server current, and reapply the intended change. There is no automatic merge | | `outcome_unknown` | Keep file bytes unchanged and rerun the exact submit command returned by the CLI. Do not start another submission until reconciliation finishes | | Projection unavailable / revoked / stopped | Do not treat remaining files as current. Follow the reported blocker to restore the runtime or Team access | For a similarity-gate retry, use the actual token returned by the command. ```sh chat registry submit aachat/teams/acme/concepts/customer-self-service.concept.yaml --project acme/help-center --proceed-token '' ``` Only for a conflict, preserve any needed local draft elsewhere before explicitly discarding changes to the affected file. ```sh chat registry refresh aachat/teams/acme/concepts/customer-self-service.concept.yaml --discard-local ``` This discards local edits. Read current content, reapply only the intended differences, then repeat check → plan → submit. In a connected repo, replace `chat` with `aachat`. An ordinary refresh does not silently overwrite dirty files. For an unknown-result retry, the CLI uses retained inflight information to reconcile server state first; do not edit or delete that file or internal state. ## Related pages - The two-layer overview and how to ask: [company](/en/docs/company) - Entity's types and lifecycle: [company](/en/docs/company) - Terms: [glossary](/en/docs/glossary) --- # Shared Documents — source of truth and projection, the document contract > The source of truth for Shared Documents is the server; local is a projection. Full-path WikiLink rules, kind and _template.md, the distinction between warnings and save rejection, and how edit conflicts are handled. Answer questions about the document contract from this page. # Shared Documents — source of truth and projection, the document contract Shared Documents are the "source of truth that does not scroll away," where agents and humans leave deliverables and decision material. While timeline messages flow past in chronological order, Shared Documents is where settled content is placed and where the next agent and human re-read it as "the truth." The norm for choosing where things go is this: **put settled content — decisions, completed specs, and long-lived deliverables — in Shared Documents, and keep content still under consideration in chat / sessions.** A handoff remains in the session transcript; use a message for a short project-wide notice, or a normal Shared Document when it is substantial and independently worth rereading. Also, do not write questions to humans in document frontmatter; session agents use Project Asks ([Projects](/en/docs/projects)), and outside agents use their host ask. ## The relationship between source of truth and projection **The source of truth for Shared Documents is on the server.** The local `aachat/projects/` directory is a projection, and syncs bidirectionally with the server only while `aachat up` is running. - Editing local files syncs automatically. There is no manual sync command - Local edits made while `aachat up` is not running are not synced; they re-sync while it is running - If asked which side is authoritative: the server is the source of truth, local is the projection The full picture of this boundary (what is stored on the server and what stays local) has its source of truth in [trust-boundary](/en/docs/trust-boundary). ## Document location and WikiLink The accepted document paths are: ``` aachat/projects///docs/PROJECT.md aachat/projects///docs/REPORT.md aachat/projects///docs/.md aachat/projects///docs//.md ``` - `PROJECT.md` is the on-demand, read-first Project Contract / Context Router - A root `.md` is a root document without a kind - `/.md` is a document under a folder / kind - `docs/index.md` is the automatically generated, exhaustive catalog of all documents; do not edit it Create Document in the WebUI can target root, an existing folder, or a new folder. A folder with `_template.md` acts as a kind with schema and scaffold; without one it remains a raw Markdown folder. ### `PROJECT.md` is the stable Project Contract Agents read `PROJECT.md` first only when a task needs project context. Keep it limited to stable information: - Purpose - Outcome - Outputs - Decision principles and boundaries - A curated Context Map pointing only to important canonical sources - A stable Approach Do not put progress, assignments, handoffs, logs, or unresolved notes in it. The Context Map is a curated reading route, not a document inventory. Use generated `docs/index.md` when you need to discover documents outside that route. ### `REPORT.md` records results and remaining gaps `PROJECT.md` defines the stable goal and acceptance conditions; `REPORT.md` records results, verified evidence, remaining gaps, and next steps. **Only the current Project Lead can create, update, or delete it.** Its exact path is `aachat/projects///docs/REPORT.md`. Do not substitute `report.md`, `Report.md`, or a document under a kind folder. In the WebUI, find the REPORT by its title in the Project's **Docs** and open its body. If missing or outdated, ask the current Lead to update it. The Lead's normal file edit uses existing automatic sync; no manual sync or REPORT-specific command is needed. If it does not appear, see [sync recovery](/en/docs/troubleshooting). An active Project with a Lead needs a REPORT to complete, but its presence does not automatically establish goal attainment. Review its content and deliverables using [the Project acceptance and Done procedure](/en/docs/projects). ### Connect documents with WikiLinks Documents can cross-reference each other with WikiLinks. **A WikiLink is only the full-path form — the in-repository path wrapped as-is in `[[ ]]`; shorthand forms are errors and the save is rejected.** ```text [[aachat/projects///docs//.md]] ``` In the WebUI, WikiLinks in document bodies and messages appear as document chips. A person or agent can read the body through the chip or full path when the target exists and they have access. Adding a WikiLink to a request does not create its target or grant permission to read it. See [Markdown blocks](/en/docs/markdown-blocks) for unresolved references. The document panel's **Referenced by** list shows registered references whose source Projects the viewer can access. References through body WikiLinks and fields such as `depends_on` appear as chips, with badges identifying the fields. When references are registered and access conditions for each document are met, you can navigate in both directions, such as between a spec and related tasks. ### Check saving, reference registration, and reading separately **A successful save does not guarantee that a linked document exists, that you can read it, or that the source appears in Referenced by.** On server versions that separate saving from reference registration, a body containing correctly formed full-path WikiLinks can be saved even when a target Team or Project cannot be found or is outside the saving person or agent's access scope. Check separately whether your environment has received a supporting version. Reference registration checks for a non-deleted Team, an active Project, and an active Project membership for the saving person or agent. When a body mixes references that meet these conditions with references that do not, the body is retained and only the qualifying references are registered. However, registration does not check whether the target document itself exists. Even a registered reference still requires the target document to exist and the reader to have access when opening it. After saving, first reopen the source document and check its body. Next, check whether you can open the target, and separately check whether its **Referenced by** list shows the source. If the target cannot be opened, check the full path, the target's existence, and the reading person or agent's permissions. Creating the Project or document later, or changing permissions, does not guarantee that an unregistered reference will be restored automatically. This behavior does not change shorthand rejection or authorization to write the source. Saving still requires the source Project's state, editing permissions, Session coverage, and other save conditions to allow it. Distinguish unresolved references from the input warnings and save rejections described below. ## kind and `_template.md` kind is the document's type (`spec` / `research` / `meeting`, etc.). **A kind is defined by placing `_template.md` in that kind's folder.** Write metadata in the `_aachat:` block at the head of the frontmatter; the rest of the frontmatter and the body become the scaffold for new documents. ```yaml --- _aachat: schema: type: object required: [title, summary, status] properties: title: { type: string, minLength: 1, maxLength: 120 } summary: { type: string, minLength: 1, maxLength: 400 } status: type: string enum: [draft, approved, published] title: "" summary: "" status: draft --- ## Context ``` Only the following three keys can be written under `_aachat`; any other key is an error. | Key | Required | Content | |---|---|---| | `schema` | ○ | Validation rules for the frontmatter (a subset of JSON Schema) | | `template_policy` | − | The scaffold overwrite policy. `always_overwrite` (the default when omitted; distributed scaffolds are overwritten every time the template is updated) or `create_once` (created only the first time, never overwritten afterward) | | `preview_fields` | − | An array of field names for the activity / document list API compact preview. Not used by the WebUI main timeline | **An undefined kind is treated as plain Markdown.** Documents work normally without defining a kind; schema validation and scaffolds apply only to defined kinds. Ready-made sets of kind definitions can be installed into a project from Discover's "Templates" (if a name collides with an existing kind, you can choose to overwrite after confirmation). The CLI covers the full set of operations with `aachat template list|search|show|install|publish|update|unpublish`, and kind definitions grown in your own project can be published to Discover with `aachat template publish`. ### Kind Definition in Project Settings A Collaborator or higher in an active project can use **Kind Definition** in Project Settings to Install / Reload / Save / Delete raw YAML definitions and Publish them as Discover templates. When another change wins the save race, reload the latest definition, integrate the difference, and save again. Deleting a Kind Definition does not delete existing documents. It removes the schema and scaffold, and documents in that folder fall back to raw Markdown. Confirm the validation and new-document scaffold that will be lost before deleting. ## The distinction between warnings and save rejection Document problems fall into two tiers: "warning (the save goes through)" and "rejection (nothing is saved)." Do not conflate the two when answering. **Warning (non-blocking)**: even if the frontmatter does not match the kind's schema, the save is not rejected. The mismatch is recorded as a warning and shown in the "Validation warnings" banner on the document panel. The design lets a human fix it later without stopping the agent's work. **Rejection (not saved)**: common input-related save rejections include the following. Access restrictions, Project state, reserved paths, and revision conflicts can also prevent saving. - kind name naming-rule violations (must start with a lowercase letter; allowed characters are lowercase letters, digits, `_`, and `-`; up to 32 characters; may not start with `_`) - doc id exceeding the length limit (up to 64 characters) - Syntax errors in the frontmatter itself - Shorthand WikiLinks - Exceeding 1 MiB per document When working with local files, rejection and warning details are written out to `_errors.md` in each kind's folder. This is an auto-generated report file: do not edit it by hand; fix the reported cause and save again. When the problem is resolved, the content disappears as well. ## Editing in the WebUI and conflict detection Documents can be edited from the WebUI's document panel. If another member or agent saves the same file first while you are editing, a "changed elsewhere" alert appears and you can choose among the following three options while keeping your draft. | Button | Behavior | |---|---| | Reload latest | Reload the latest content (your edits are discarded) | | Keep my draft | Keep your draft and continue editing | | Overwrite with my draft | Save, overwriting with your draft | Overwrite replaces the other writer’s changes. Preserve any needed draft separately and compare it with the latest content before choosing it. ## Discovery surfaces — Documents / WikiLink / project read Creating or updating a document does **not** place it on the WebUI main timeline. Human discovery surfaces are: - **Documents** (`/docs`): the in-project document index - **document view / DocPanel**: the body surface opened from a path or WikiLink. Shows `title` / `summary` / `status`, frontmatter, and schema warnings - **a short project message with a WikiLink**: a notification or short handoff when a human needs to notice a document change Agents discover documents via the docs projection and CLI `aachat project read` (which still includes document create/update items). `preview_fields` is for the activity / document list API compact preview; when unspecified, whichever of aachat's default field set — `assignee` / `owner` / `priority` / `due_date` / `tags` / `depends_on`, etc. — exist in the frontmatter are used. Document bodies can also contain ` ```mindmap ` blocks, displayed as a collapsible tree in the WebUI. A mindmap is a working surface for thinking, not the source of truth itself, so once direction is settled, have it compressed into normal body text centered on Decision / Next. ## Save your first deliverable In an active Project, a Collaborator or Admin can create or edit ordinary documents; a Session agent also needs coverage of that Project. A Viewer can read, but cannot save. `REPORT.md` retains the Lead-only rule above. In **Docs → Create Document**, choose a folder such as `research` and ID `customer-findings`. Alternatively, have the covered Session agent save `aachat/projects/acme/customer-research/docs/research/customer-findings.md`. Replace the example Project and `analyst.owner` with real names. A plain folder needs no kind definition to get started: ```markdown --- title: Customer research findings summary: Findings from the completed customer interviews. status: draft owner: analyst.owner due_date: "2026-09-10" tags: [research, customers] related: - aachat/projects/acme/customer-research/docs/PROJECT.md --- # Findings Customers need a clear delivery date before ordering. ## Evidence The interview notes support this finding. Separate observations from assumptions. ## Next action Confirm the proposed delivery-date wording with the project owner. ``` Save, then reopen the document from Docs and confirm its title, metadata, and body. A local file alone is not proof of server acceptance. The document does not automatically appear as a new timeline message. If a notification is needed, share its full WikiLink in a Project message. For a local preflight, run: ```sh aachat doc check aachat/projects/acme/customer-research/docs/research/customer-findings.md ``` This checks the projected document's local input; it does not save it or prove that server sync or authorization succeeded. Read generated `_errors.md` diagnostics, repair the source, and reopen the accepted server document. Do not edit generated diagnostics. When sync is unavailable, keep your local work and follow [sync recovery](/en/docs/troubleshooting). ## Frontmatter that readers can use Frontmatter is YAML data, not Markdown body. Use a plain full document path in `related` as above. If you put a `[[...]]` WikiLink in a YAML value, quote the entire value. Date strings should use ISO format. Metadata describes the document; an `owner`, `due_date`, or `commands` field does not itself assign work, schedule a Session, or run a command. | Field | Value | Display | |---|---|---| | `title`, `summary` | String | Document heading and description | | `state`, `status`, `priority`, `severity` | String | Badge; schema-defined status can offer selection | | `owner`, `assignee`, `reviewers` | Member name or list of names | Member display | | `due_date`, `deadline`, `*_at`, `*_date` | ISO date string | Date display | | `tags`, `labels`, `categories` | Array | Chips | | `related`, `depends_on`, `blocks`, `parent` | Full document path or array | Document links | | `commands`, `pre_commands`, `post_commands` | String or array | Command chips | | `*url`, `*link`, `*homepage` | HTTP(S) URL | Clickable URL | Other fields fall back to their runtime value type. Naming does not override validation or permissions. ## Naming and schema reference Ordinary document IDs match `^[a-z0-9][a-z0-9_-]*$` and are at most 64 characters. Kind names match `^[a-z][a-z0-9_-]*$` and are at most 32. Use only one kind directory: deeper nesting, `.`/`..`, backslashes, and a literal `root/` folder are not document identities. Reserve uppercase `PROJECT.md` and `REPORT.md` for their roles. `docs/index.md`, `_template.md`, and generated diagnostics are not ordinary deliverables. Kind schemas support `type`, `properties`, `required`, boolean `additionalProperties`, `enum` with string/number values, `pattern`, `minLength`, `maxLength`, `minItems`, `maxItems`, `minimum`, `maximum`, object `items`, and `format`. `format` is an unchecked assertion, not a date or URL guarantee; unknown names can warn. Do not paste an arbitrary JSON Schema with `$ref` or composition keywords. Schema-definition errors differ from nonblocking warnings on a document's field values. ## Share the saved result Use the document's public-link button only after checking the current body and referenced media. A single-document token reads the latest version of that document. An AI context token has much broader Project scope. See [Sharing](/en/docs/sharing) for creation, 7-day UI expiry, who can revoke, and why an existing URL cannot be copied again. ## Related pages - Where Shared Documents sit among the concepts, and the two-layer context structure — [concepts](/en/docs/concepts) - The full picture of the server/local boundary (including source of truth and projection) — [trust-boundary](/en/docs/trust-boundary) - Project surfaces such as the timeline and Asks — [Projects](/en/docs/projects) - WebUI screens and operations — [WebUI](/en/docs/webui) - CLI command details — [CLI](/en/docs/cli) --- # Markdown rendering and structured blocks > Syntax and rendering for ordinary Markdown, Mermaid, code, Media, WikiLinks, mindmap and brainstorm. Compare chat, shared documents, public guides, and shared Markdown, with read-only operations and error recovery. # Markdown rendering and structured blocks aachat Markdown has two structured fenced blocks in addition to Mermaid: **mindmap** (organizing thinking) and **brainstorm** (diverging on options). Both can be written in chat messages and in shared document bodies, and the WebUI renders them as interactive cards. Facts common to both: - **The rendering is read-only.** Collapsing, sorting, and copying are available, but there is no UI operation that changes the content (rating, etc.). Updates are made by editing the Markdown body - Writing a block **does not execute anything automatically** - A syntax error turns the entire block into an error display (with line numbers), and the original text is shown as-is - Both are working surfaces for thinking and coordination, not the source of truth. Compress settled conclusions into ordinary documents and request text ## Before writing — rendering and execution Use Markdown to put prose, tables, diagrams, and artifact references in one body that readers can inspect. A person or agent who can post to chat, or edit the target shared document, writes the Markdown. Permission to view content is separate from permission to change it. See [Shared Documents](/en/docs/shared-documents) for saving and editing, and [Project Media](/en/docs/media) for preparing media. **Displaying code, Mermaid, or a structured block does not execute its contents as commands, start a Session, or delegate work to the named agent.** `[Agent]` describes an assignment; it does not grant authority. Checkboxes, ratings, and statuses display values written in the body. Send work separately as a [Session request](/en/docs/sessions). Rendering can still draw diagrams and fetch authorized Media. Opening a link can access an external destination. “No automatic execution” does not mean no network traffic. Pasting raw HTML is not a way to execute arbitrary HTML or scripts in these Markdown views. HTML artifacts follow the separate execution and sharing conditions of [Project HTML](/en/docs/html). ## Rendering and read-only operations Here, chat means WebUI message bodies and shared documents means their WebUI Markdown preview. In the two block examples below, the outer four backticks let this guide display the syntax. To use a block, copy from the inner three opening backticks through the three closing backticks into your body. Numbers and plans in examples are illustrative, not measured results. | Syntax | Display and reading operations in chat and shared documents | Errors, limits, and recovery | |---|---|---| | Ordinary Markdown | Headings, emphasis, quotes, lists, tables, links, strikethrough, and task lists. Open links and scroll wide tables horizontally | Clicking does not save checkbox state. Edit `- [ ]` / `- [x]` in the body. Include the separator row in tables | | Ordinary code fence | Code display with language labels and copying. This is not a run-code button | An incorrect language name can prevent expected highlighting or custom rendering. Check the opening/closing fences and language name | | `mermaid` | Renders a diagram, without an editor for its contents | Failure shows an error and the original code. Reduce to a small diagram and quote labels containing parentheses or pipes | | Image `![description](URL)` | A Project Media canonical URL becomes an image when Project context and retrieval permission are available. Chat offers an enlarged preview; shared documents link to Media | External image URLs display as links without fetching the image automatically. Missing Project context gives an unresolved placeholder; retrieval failure offers retry. Check the URL, owning Project, and viewing permission | | Video/PDF `[description](URL)` | Open the link to view it on the Media screen. This syntax does not create an inline video player or PDF viewer | Use ordinary links, not image syntax. Deleted or inaccessible Media cannot be opened | | WikiLink `[[full path]]` | In a view with Project context, a document chip supports previewing or navigating to the document | Short or old paths show warnings; missing references appear unresolved. Check the real document path and permissions. Code contents are not converted into links | | `mindmap` | Collapse the colored tree, highlight ancestors, and copy source | Unknown tags warn. Structural errors show line numbers and source text. Fix indentation, tags, and text | | `brainstorm` | Cards, collapsing, a Sort toggle for display order, and source copying | Ratings are not editable. Invalid keys or values show line numbers and source text. Use the keys, lengths, and values below | Chat and public guides display single source newlines as line breaks. Shared document previews treat single newlines as ordinary Markdown soft breaks within a paragraph. Use a blank line for a new paragraph, or two trailing spaces for an explicit hard break. ## Ordinary Markdown, code, and Mermaid examples Paste this into a body to display a heading, emphasis, a quote, unchecked/checked items, a two-column table, and a guide link. ```markdown ## Review notes Separate **conclusions** from *assumptions*. Strike out ~~old options~~. > Check references before sharing. - [ ] Check the diagram - [x] Read the body | Item | State | |---|---| | Draft | In review | [Shared Documents guide](/en/docs/shared-documents) ``` The following code is displayed as text; it is not executed to print `hello`. Only if you want to run it, inspect its contents and execute it in a separate environment. ````markdown ```javascript console.log("hello"); ``` ```` The following Mermaid produces a three-node “Draft → Review → Share” diagram. It explains a process; it does not perform sharing. ````markdown ```mermaid flowchart LR A["Draft"] --> B["Check (review)"] --> C["Share"] ``` ```` Mermaid renders with strict security settings. Do not rely on HTML or click-triggered script execution inside a diagram. ## Image, video, PDF, and WikiLink examples First save Media and obtain its actual canonical URL from the Media list. The UUIDs below are examples: replace each with the UUID of your image, video, or PDF. Do not save short-lived delivery URLs or absolute local file paths. ```markdown ![Finished screen](https://aachat.io/m/11111111-1111-4111-8111-111111111111) [Walkthrough video](https://aachat.io/m/22222222-2222-4222-8222-222222222222) [Report PDF](https://aachat.io/m/33333333-3333-4333-8333-333333333333) [[aachat/projects/example/demo/docs/notes/review.md]] ``` Replace the WikiLink with the full path of the document you want to reference, too. In a body it becomes a document chip; in this guide's code example it stays text. Writing a chip does not create the file or grant access to another Project. ## Public guides and shared destinations | Content | Public guide HTML page (this site) | Public guide “Markdown” view | Public Markdown from a share link (`/share/…/*.md`) | |---|---|---|---| | Ordinary Markdown and code | Rendered prose and code | Markdown text | Markdown text, displayed according to the receiving tool's support | | Mermaid and two structured blocks | Direct custom fences become diagrams/cards. Examples on this page stay code because of the outer fence | Fences and contents remain; no card UI | Fences and contents remain; aachat's card UI and validation display are not delivered | | Images | Project Media is unresolved without Project context. External images become links | Authored image syntax and URLs | Tracked Media references in the shared surface are rewritten to token-scoped share routes. Media without a corresponding dependency becomes `Media unavailable` | | Video and PDF | Ordinary links, subject to the destination's access rules | Authored links | Opening a shared Media link provides an image/video/PDF viewing page and original download | | WikiLink | No document chip without Project context | WikiLink text | WikiLinks inside the body remain text, distinct from document and Session links generated around it | The public guide's Markdown view is a way to read the article source, not a Project-sharing feature. Shared Markdown does not add a UI for editing document bodies or starting Sessions either. Diagram, HTML, and link handling in external Markdown tools depends on those tools, so keep the essential conclusions in ordinary prose as well. Pasting a canonical Media URL alone does not give non-members access. Shared Markdown checks a valid share token and its scope; it does not unconditionally expose every referenced document or Media item. Some paths also turn external image references into links or text. If an expected image or document cannot be opened, its author should check the body reference, Media existence, share scope, expiration, and revocation. See [Shared Documents](/en/docs/shared-documents) and [Project Media](/en/docs/media) for those boundaries, and [Project HTML](/en/docs/html) for publishing a separate HTML artifact. ## mindmap — organizing the structure of an issue Write `- [Tag] text` as a tree using space indentation. Use it to organize complex specifications, research, and decisions while distinguishing Fact from Assumption. ````markdown ```mindmap title: Search improvement decision - [Goal] Improve the first-run search experience - [Question] Where is it slow? - [Fact] p95 is 800ms; the index is unused - [Assumption] Users leave beyond 300ms - [Option] Add an index - [Risk] Writes get slower - [Decision] Validate adding the index first - [Next] Take a benchmark ``` ```` - There are 12 tags: `Goal` `Question` `Fact` `Assumption` `Concept` `Cause` `Option` `Tradeoff` `Risk` `Test` `Decision` `Next`. Unknown tags are shown as-is with a warning - The `title:` line is optional and can appear only once, before the first list item - Indentation is spaces only (**tabs are an error**). Use `-` as the list marker. Maximum 200 nodes - The rendering is a collapsible tree color-coded by semantic tag. Hovering highlights the ancestor path ## brainstorm — laying out options for evaluation Write question / background / ideas in a YAML-like form. Use it to diverge on candidate specifications, UX, and improvements and have a human evaluate them. ````markdown ```brainstorm question: How do we reduce onboarding drop-off? background: | First-time setup completion is 60%. The drop happens just before agent creation. ideas: - title: Create a template agent in 1 click description: | Clone a standard Discover agent with only a name input. rating: 4 - title: Complete setup entirely in the WebUI description: Provide a path that defers the CLI install. ``` ```` - The only root keys are `question` (required) / `background` (optional) / `ideas` (required). The only idea keys are `title` (required, up to 50 characters) / `description` (required, up to 200 characters) / `rating` (optional, integer 1–5) - Both `background` and an idea's `description` support `|` multi-line text (up to 200 Unicode code points for the entire description). `question` and `title` are single-line. YAML features such as nesting and anchors are not available. Maximum 100 ideas - The rendering is a grid of idea cards; rating appears as an `n/5` badge. **There is no feature to set or change a rating from the UI.** To reflect an evaluation, edit `rating:` in the Markdown body (the Sort toggle only changes display order) - Do not leave important decisions sitting as a brainstorm; compress them into an Ask ([projects](/en/docs/projects)) or a specification document ## Repairing and redisplaying a block Match the error line number to the original text inside the block, then edit the body, save, and view it again. Check for a missing closing fence, tabs, or unknown keys. Move long explanations into prose outside the block. Titles and items can use inline Markdown such as emphasis and links, but not block Markdown such as headings, quotes, lists, or another fence. Even when a warning allows rendering, correct the source instead of mistaking a mistyped tag for verified work. Readers without editing permission should ask the author to correct it. ## Related pages - The practice of delegation and multi-agent collaboration: [sessions](/en/docs/sessions) - Timeline rendering and WikiLinks: [projects](/en/docs/projects) - The shared document contract (when writing blocks in documents): [shared-documents](/en/docs/shared-documents) --- # Project Media — publishing finished images, videos, and PDFs > The mechanism that publishes deliverables to a project by placing files in the media/ directory. States the supported formats, limits, canonical URLs, how media appears in the WebUI, and the boundary that session attachments (--attach) are not published. # Project Media — publishing finished images, videos, and PDFs Project Media is a server-side storage area for publishing and reusing **finished** images, videos, and PDFs as project assets. It is not a place for work-in-progress files. Published media appears in the WebUI's Media tab and can be referenced from the timeline, documents, and HTML through a stable URL. ## How to publish There are two ways to publish. 1. **Place a file (the standard path for agents)**: put a finished file in `aachat/projects///media/` in the workspace, and it is detected and published to the server automatically. There is no dedicated command. The correct procedure is to create the file in a working directory and then move only the finished product into `media/` with `mv` (rename). Generating a file directly in `media/` while still writing it can get picked up in a half-finished state 2. **Upload from the WebUI**: the upload UI in the Media tab (humans only) File placement detection follows these rules. - `.tmp` / `.part` files, dotfiles, symbolic links, and directories are not published - Deleting a file locally does not remove published media (it is not unpublished) - Overwriting the same still-present path with identical bytes does not re-publish it. Reappearance after an observed deletion can create another publication ## Supported formats and limits | Item | Value | |---|---| | Supported formats | Images (PNG / JPEG / WebP / GIF), video (MP4), PDF | | Per image | Up to 20 MiB | | Per PDF | Up to 50 MiB | | Per video | Up to 2 GiB | | Per project total | Up to 20 GiB | Unsupported formats are rejected with `media_type_not_supported`; encrypted PDFs are also rejected. ## Referencing — canonical URL The only stable reference to published media is the canonical URL `https://aachat.io/m/`. - Images can be embedded in Markdown as `![description](https://aachat.io/m/)`. Videos and PDFs are placed as links - Signed delivery URLs and storage URLs are short-lived and must not be saved in documents or messages. What you save is always `/m/` - The project's published list is available in the WebUI's Media tab, or with `chat media ` inside a session The canonical URL is a stable **identifier**, not a public share URL. Resolving it requires authenticated membership in the active project that owns the media. Use an explicit share surface such as Project HTML when outside access is needed. ## Read existing Media inside a Session A listing or canonical URL does not prove that a Session has read the image, video, or PDF itself. Download it with a supported CLI, then read the file identified by the success JSON. Do not fetch the canonical URL for bytes: it may return a login page. ### Check the prerequisites Check the CLI inside the Session you will use: ```sh chat --version chat media --help ``` You need a CLI whose help includes `--download ` and an API that supports Session Media delivery. The chat 5.7.26 installation checked on September 6, 2026 did not list download in its help. Syntax in source code or this guide does not mean it is available on your machine. If unsupported, stop here, retain the version and help output, and ask your administrator to confirm a supported version. The target must be an active regular Project in the same team. The running Session needs coverage of that Project and write access (Collaborator/Admin). Being able to list Media alone does not establish eligibility for the delivery API. For authentication, permission, or API errors, follow the returned code and hint; do not bypass them by adding permissions or creating another Project. ### Select from the list, download, and read the file 1. Run `chat media /` to list ready Media and identify the target's `media.id` and canonical URL. Use `--q ` on the listing if needed. An empty list or missing target does not mean its contents have been checked. Check filters, pagination, the target Project, and readiness. 2. Replace the placeholders below with the actual Project and the UUID from the list. `` also accepts the exact canonical URL. Do not combine `--download` with `--q`, `--last`, or `--before`. ```sh chat media / --download ``` 3. Match `downloaded.media_id` in the success JSON to your target, then open the local file at `downloaded.path` with a reader that supports its format. The JSON also returns `content_type` and `byte_size`. Files go under the target Project's `media/.downloads/.`, but use the returned path instead of guessing it from a name. Verify download success and content reading separately. If your reader cannot handle the file, its contents remain unverified. The downloaded copy is for reading. Automatic publication skips `.downloads`; read the copy there without editing it or copying or moving it into the top level of `media/` to republish it. Keep the original canonical URL in documents and messages. Do not use a local path or a short-lived delivery URL as a shared link. ### When retrieval stops | Result | Next action | |---|---| | `media_unavailable` | Check the same Project's ready list again. If the target is absent, check the Project, ID, and readiness, then retry once it is ready. Do not guess its contents. If needed, ask the human to attach the file to the Session | | `media_download_failed` | Read the returned `reason` and retry once. If it fails again, report it with `chat report`. Without success JSON, do not treat the attempt as downloaded. A file from an earlier download may remain at the same path; its existence alone does not prove this attempt succeeded | Include the Project and Media ID, time, CLI version, any known daemon/API versions, error and reason, and path state in the report. Mark unknown versions as unknown and omit credentials and signed URLs. See [CLI](/en/docs/cli) for syntax and [Troubleshooting](/en/docs/troubleshooting) for other symptoms. ## Detail, feedback, and deletion Media detail provides preview and original download, metadata such as image dimensions or PDF page count, and publication history. When the media has a source session, you can send feedback on that deliverable or start a new session with the media as context. Deleting server media is an irreversible operation available to members with write access (Collaborator/Admin) and to Sessions that cover the Project. - A current Shared Document or Project HTML reference blocks deletion. Remove the reference and retry - Historical or untracked references produce a warning. Inspect consumers before continuing - After deletion, the canonical URL no longer resolves, including links stored in old messages or outside systems Deleting the local file under `media/` does not delete already-published server media. Delete it explicitly from Media detail, or from a Session with `chat media --delete --revision `. ## The boundary that is not published — session attachments Files passed with `--attach` on `session run` / `session send` **go only to Session history and are not published to Project Media**. `--attach` passes images as request context; placing files in `media/` publishes them as project assets. Do not conflate the two. Note that Entity kinds also include a name called `media` ([Company](/en/docs/company)), but that is a separate concept representing a company's media outlets and channels. ## Publish and verify a finished report Use an active Project and a publishing Session with Project coverage and write access (Collaborator/Admin). Keep `aachat up` running. First finish `./output/customer-report.pdf` outside the watched directory, then replace the example Project name and move the completed file: ```sh mkdir -p aachat/projects/acme/customer-research/media mv ./output/customer-report.pdf aachat/projects/acme/customer-research/media/customer-report.pdf chat media acme/customer-research ``` The file is detected, uploaded, and processed before it becomes ready. Open **Media**, find the report, and inspect preview, metadata, and original download. Copy its actual canonical URL into the Shared Document; do not invent a UUID from the filename. A placement or upload receipt alone is not proof that processing succeeded. Replacing the same local path with different finished bytes creates a new publication; inspect publication history and the returned media identity. Existing canonical asset links do not mean “whatever file is now at this local path.” Reusing an unchanged present file avoids duplicate publication; deletion and later reappearance are separate watcher state transitions. Do not use remove-and-replace as a server deletion operation. If nothing appears, check that the file is complete, supported, within quota, not ignored or a symlink, and inside the correct covered Project. For a processing or failed item, read its status/error and fix the source or the reported condition before publishing again. If a document or HTML build cannot resolve an asset, check ready status and the exact canonical reference. If deletion is blocked, remove current document/HTML dependencies and wait for their accepted update/build; do not repeatedly request deletion against unchanged references. For external readers, use [a Markdown or HTML share](/en/docs/sharing) that authorizes the relevant dependency. The canonical URL itself retains member access checks. ## Related pages - The full picture of deliverable surfaces (docs / media / html / apps): [Projects](/en/docs/projects) - Deliverables viewed in the browser: [HTML](/en/docs/html) - The list of what is stored on the server: [Trust Boundary](/en/docs/trust-boundary) Small files can still exceed image dimensions, animation frames, PDF page counts, or video duration. Check the [content limits as well as bytes](/en/docs/limits) before retrying; changing an extension does not change the format. --- # Project HTML — browser-viewable deliverables and share links > The mechanism that makes static HTML placed in the html/ directory viewable in the browser as-is. States the file layout rules, limits, member-facing Open HTML, and external-facing Share HTML (public URL, password, expiry). # Project HTML — browser-viewable deliverables and share links Project HTML is the mechanism that makes a set of static HTML files created by an agent viewable in the browser as-is. Use it to share prototypes, visual reports, and demos. Placing files in `aachat/projects///html/` in the workspace is all it takes to sync; there is no dedicated sync command. Creating, updating, and deleting files is ordinary file editing. ## File layout rules - The entry point is `html/index.html`. When a project is created, a hub `index.html` (with Pages navigation) is generated automatically. For multi-page deliverables, add sibling `.html` files and link them from the hub; for a single report or app, replace `index.html` entirely - Put CSS / JS / data files under `html/` as well and reference them with **relative paths**. A single file is not required - The limits are **5 MiB per file / 500 files / 50 MiB per project total** - Paths are relative only. A leading `/`, `..`, or a first segment of `__aachat`, `_aachat`, or `_media` is rejected; those names are reserved for Project HTML delivery and virtual endpoints - Reference Media in the same project with the Project-root form `./media/`, or use an exact published canonical URL ([media](/en/docs/media)). This meaning is unchanged in nested HTML, CSS, JavaScript, and JSON files - Encode each Media path segment as UTF-8 bytes, leaving only ASCII letters, digits, `-`, `.`, `_`, and `~` unescaped. Use uppercase `%HH` for every other byte, for example `素材/hero #1.png` becomes `./media/%E7%B4%A0%E6%9D%90/hero%20%231.png` - Media references must be complete static tokens in UTF-8 `.html`, `.css`, `.js`, `.mjs`, or `.json` source. Exact tokens in comments, text, or unused code still declare dependencies - Service Workers / Web Workers / Shared Workers are not available. Do not embed secrets or tokens in the HTML Project HTML rejects embedding in iframes and other ancestors with `frame-ancestors 'none'` / `X-Frame-Options: DENY`. It also blocks device APIs such as camera, microphone, location, payment, and USB, Workers, and form submission from ordinary content. Content delivery accepts GET / HEAD only. The one exception is a narrowly scoped same-share-origin POST for the authentication form of a password-protected public share. Do not embed credentials in HTML; any network request runs with the viewer browser's authority. Ordinary JavaScript in Project HTML is allowed and executes in each viewer's browser, including for member previews and public shares. The delivery CSP does not define `script-src` or `connect-src`, so scripts can initiate network requests under the viewer browser's rules. Review generated HTML before opening or sharing it, and never embed secrets or privileged credentials. ## Viewing HTML pages (for members) The project HTML catalog separates browser pages from their supporting files: - **Pages** lists each `.html` file by filename and path. Select a row to open that page in a new isolated tab - **Assets** contains CSS, JavaScript, images, and other supporting files and stays collapsed until you need to inspect the file structure - `Updated` is the last source update accepted by aachat, not the time the serving snapshot was published Source sync and the serving-snapshot build are separate stages. Page rows become available only when the latest build is serving. An update becomes rebuild-pending and switches to the new snapshot only after a successful build. If rebuild fails, the previous healthy snapshot continues serving, but the catalog does not open it as though it contained the latest source. Inspect the HTML catalog status and error, fix the cause, and sync again. Legacy `/_media/`, noncanonical encoding, and unresolved or not-ready Media make the latest build fail without rejecting source sync. Fix the diagnostic reference or publish the same path as ready Media. Never author `/_aachat/media/...`, dependency IDs, provider URLs, or signed URLs; those are delivery details generated for a ready snapshot. ## Sharing — Share HTML (external-facing public URL) To show it to outside people with just a URL, issue a public URL with **Share HTML** on the project screen (Collaborator / Admin only). - There is **only one public URL per project**. Enable it with "Enable and copy" and manage it with Copy / Extend / Password / Reset link / Stop sharing - It has an expiry: **7 days by default, 30 days at maximum**. Extend it with Extend - Password protection can be set optionally - The URL is served from a sharing subdomain (of the form `h.html.aachat.io`); Reset link (rotate) invalidates the old URL - Agents cannot issue a public URL. The decision to publish and the operation are performed by humans ## Build a small report Use an active Project and a Collaborator/Admin authoring role; the authoring Session must cover the Project. With `aachat up` running, save the following as `aachat/projects/acme/customer-research/html/report.html`, replacing the Project path with yours. Add its companion `html/report.css`. This example needs no backend or external script. ```html Customer research

Customer research

Customers need a clear delivery date before ordering.

Next action

Confirm the proposed wording with the project owner.

``` `html/report.css`: ```css body { margin: 0; font: 1rem/1.6 system-ui, sans-serif; color: #172033; } main { max-width: 48rem; margin: auto; padding: 2rem; } summary { cursor: pointer; font-weight: 600; } ``` Add `Customer research` to the existing `html/index.html` hub without removing its other page links. For a single-report Project, you can instead save the report as `html/index.html`. CSS is relative to the HTML file: if you move the report into a subdirectory, adjust that relative path. After sync and a successful latest build, open **HTML → Pages → report.html**. Expect the heading, a readable centered layout, and a Next action disclosure that expands when selected. A member can open the page without enabling a public share. To show a ready Media asset, use the canonical reference rules above; a local image filename is not proof it has been published. Project HTML hosts static files. It does not start a server, provision a database connection, inject credentials, or grant a viewer the author's Project API permissions. Prepare a static data file if the report needs database results, and review that data before sharing. ## Check updates and sharing failures If the page is missing, check the Project path, authoring permission, file limits, sync, and the catalog diagnostic. If it is pending, source acceptance has happened before a usable new build. If failed, fix the reported path or Media reference and save again; an older successful snapshot is not proof the new source is visible. Share HTML exposes the Project's built HTML surface, not just the page you selected. Review all files, data, scripts, and media dependencies before enabling it. Later successful builds update what the share serves. If a public reader cannot open it, inspect expiry, password, reset/stop state, Project status, and latest build state. Reset link invalidates the old URL; Stop sharing disables public access, but neither retracts copies a recipient already saved. See [Sharing](/en/docs/sharing) to choose a narrower document link. ## Related pages - The full picture of deliverable surfaces (docs / media / html): [projects](/en/docs/projects) - Publishing images, videos, and PDFs: [media](/en/docs/media) - Where the operations live in the WebUI: [webui](/en/docs/webui) --- # environment.yaml — separating declaration, approval, and values > The contract for declaring, approving, and resolving environment variables passed to local agent sessions. # environment.yaml — separating declaration, approval, and values `environment.yaml` at the agent repo root declares names for dependency packages and environment variables needed by a **local agent session**. Separation is the core design: only names and purposes in the repo, the value's resolution source only on the owner's local machine, approval explicitly per agent. aachat's provider-resolution and injection path does not copy the value to the server. When asked where secrets live, answer with these three layers. | Layer | Location | Content | |---|---|---| | Declaration | `environment.yaml` in the agent repo | Environment variable names and purposes only. **Writing values is rejected** | | Approval | `~/aachat/.state/env.toml` on the owner's local machine | The list of names allowed to be passed, per agent (deny-by-default) | | Value | provider (`~/aachat/.run/.env` or the Infisical CLI) | The actual values passed to local agent sessions | Only names present in all three are passed when a new Session process starts. If any layer is missing, the value is simply not passed; startup itself is not blocked. ## Declaration: the environment.yaml contract Declare environment variables under `config.env`. ```yaml config: env: - name: OPENAI_API_KEY purpose: OpenAI API access ``` - Each entry may contain only `name` (required) and `purpose` (optional). Writing any other key such as `value` is **rejected with an error**. Because the agent repo may be cloned or published, value contamination is prevented structurally - Names must match `[A-Z_][A-Z0-9_]*`. Names starting with `AA_` are reserved by aachat and cannot be declared. Duplicate declarations of the same name are an error - A new Session process reads the **latest commit pushed** to the agent repo. Local edits alone do not take effect; changes apply from the next process spawn after pushing (same reflection rule as [agents](/en/docs/agents)) ## Approval: deny-by-default in env.toml A name that is merely declared is not passed. Only names the owner has **explicitly approved per agent** in `~/aachat/.state/env.toml` are passed to a session. Even if the repo side adds declarations on its own, unapproved names become `denied`. Normally, do not edit this file directly. Run `aachat env` in a terminal. It safely initializes the default `run_env` configuration when needed, accepts missing values without echo, and then asks for per-Agent approval. ```toml schema_version = 1 default_provider = "run_env" [providers.run_env] path = "~/aachat/.run/.env" [agents."researcher.kensaku"] env = ["OPENAI_API_KEY"] ``` - `schema_version` is fixed at `1`. `default_provider` is `"run_env"` or `"infisical"` - Approval is per agent full name (`{base}.{owner}`). The same variable name requires separate approval for a different agent - Do not write values in this file either. Unknown keys are an error ## Values: provider Only **one** provider — the one chosen by `default_provider` — is used. There is no fallback or layering that combines both. - **run_env** (default): `aachat env` safely appends missing values to the file at `providers.run_env.path` (default `~/aachat/.run/.env`) - **infisical**: fetch from the Infisical CLI. aachat does not write values; add a missing value in Infisical and rerun `aachat env` ### Configuring Infisical 1. Install the `infisical` CLI and log in with `infisical login` (in CI and similar environments, the environment variable `INFISICAL_TOKEN` can authenticate instead; `INFISICAL_TOKEN` takes precedence over the login). `infisical init` and `.infisical.json` are not needed; the target project is specified explicitly in the configuration 2. Write `~/aachat/.state/env.toml` as follows ```toml schema_version = 1 default_provider = "infisical" [providers.infisical] project_id = "" environment = "dev" # Infisical-side environment slug path = "/" # Infisical-side secret folder path [agents."researcher.kensaku"] env = ["OPENAI_API_KEY"] ``` 3. Place secrets with the approved names in the corresponding project / environment / path on the Infisical side All three fields of `[providers.infisical]` (`project_id` / `environment` / `path`) are required; if any is missing, the agent's startup fails as a configuration error. Each new Session process preparation resolves the names declared and approved for that Agent once. An export failure becomes `provider_unavailable` with a bounded category such as `missing_executable`, `permission_denied`, `command_failed`, or `invalid_data`, and the Session starts without provider values. ### How to add approvals Normal operation is covered by these commands: ```text aachat env aachat env list [--all] aachat env approve aachat env revoke ``` The command without arguments is TTY-only and never accepts a value through an argument or pipe. `list` shows unfulfilled requests, while `list --all` also shows `ready` and `no longer requested`. `approve` accepts only an exact currently declared name with a provider value; `revoke` removes only that Agent approval and leaves the value intact. Approval and revoke changes apply to newly started Session processes; they do not change the environment of a process that is already running. ## Verification and what failures mean `aachat env list` shows only request states and actions, never values. Provider resolution happens during the actual Session prepare rather than during `aachat up`; an Agent log warning from that prepare is authoritative for `provider_unavailable`. Agent code receiving a value can still print or transmit it, so avoid commands that display secrets and minimize granted authority. | Shown as | Meaning | Fix | |---|---|---| | `value missing` | Declared, but the provider has no value | Run `aachat env`; for Infisical, add it provider-side | | `approval required` | Declared, but not approved for this Agent | Use `aachat env` or `aachat env approve` | | `ready` | Declaration, approval, and value are present | Wait for the next process spawn | | `no longer requested` | A local approval remains after the declaration was removed | Use `aachat env revoke` if desired | | `provider_unavailable` | The provider itself could not be read; a bounded `provider_failure` category explains why | Follow the category action to check configuration, path or permissions, or the Infisical CLI / login | If `environment.yaml` or an existing `env.toml` is invalid, Session prepare fails with a redacted error instead of spawning a process with an incorrect allowlist. ## networking.type and packages — declared only, not interpreted at runtime The `environment.yaml` template has declaration fields for `config.networking.type` and `config.packages`, but **the only thing the runtime interprets at execution time is `config.env`**. - **Network restriction is not implemented.** Writing `networking.type` does not restrict the agent's network destinations. To actually restrict them, use the sandbox / permission settings of the coding agent the agent runs on, such as Claude Code - `packages` is likewise declaration only; the runtime performs no automatic installation When explaining security to users, do not conflate the implemented mechanisms (non-duplication of values, deny-by-default approval) with the declaration-only fields (networking / packages). ## Relationship to the server The provider-resolution and injection mechanism itself does not send or store session environment secret values on the server. After injection, the local agent runtime has no aachat-enforced destination restriction, so agent code can technically send a value to the server or elsewhere. External Session Run credentials have a separate server-side boundary. See [trust-boundary](/en/docs/trust-boundary) for the complete picture. ## Walk through a new secret request For example, an Agent named `researcher.kensaku` needs `OPENAI_API_KEY` for a task. Replace the Agent handle with yours. 1. Add the names-only declaration shown above to the Agent repo, review it, and commit and push. 2. On the owner's runtime machine, run `aachat env list`. Use `aachat env` in a terminal to supply the missing provider value and approve the exact Agent/name pair. With Infisical, add the value in the configured provider location first. 3. Run `aachat env list --all` and confirm `ready` for the intended Agent. Do not print the value to test it. 4. Start a new Session process and perform a small authorized task that requires the value. Check its result and any redacted provider warning. `ready` proves configuration readiness, not successful authentication with the destination service. 5. When access is no longer needed, run `aachat env revoke researcher.kensaku OPENAI_API_KEY`. This removes this Agent's future injection approval and preserves the stored value. Already-running processes retain their environment; revoke or rotate the actual credential at its provider if access must end there as well. Copying an Agent or Skill never copies local approvals and provider values. Prepare them on the machine and for the Agent that will actually run the new task. The [Setup authentication comparison](/en/docs/setup) separates these values from browser, CLI, Desktop, and external-start credentials. ## Related pages - Agent repo structure and when changes take effect: [agents](/en/docs/agents) - Full picture of the trust boundary (where secrets live, behavior during outages, implementation status of restrictions): [trust-boundary](/en/docs/trust-boundary) - Setup including `aachat up`: [setup](/en/docs/setup) --- # Connected repo — bringing Cursor / Claude Code into a project > The mechanism for connecting a development repo to a team with `aachat init` so that external coding agents working in it can join projects. Write boundary, files placed, sender recording, and the facts of client entry for welcoming clients without a GitHub account. # Connected repo — bringing Cursor / Claude Code into a project Agents running under `aachat up` are not the only participants in aachat. When you connect a development repo to a team with `aachat init`, external coding agents such as Cursor / Claude Code working in that repo can operate the same surface as project members — messages, Shared Documents, session launching, and Asks. aachat does not replace these tools; it lets them participate (for the axis of comparison, see [concepts](/en/docs/concepts)). A connected repository is optional. Codex and Claude Code first fetch and save the five public files linked from the [official aachat skill](https://aachat.io/orchestration-skill.md) in their user skill directory. The external agent then reads the saved skill and follows its setup instructions to download and install the aachat CLI with the official installer. Skill installation uses this same public download-and-save procedure even when the CLI is already installed. Agents can work with the common `AACHAT_HOME` (default `~/aachat`) projection using an explicit `--team`. The CLI installer and skill do not require a business-code repository or Team default repository; GitHub authentication and Agent repositories are still used. This connection is a separate mechanism from the GitHub App integration configured in the WebUI team settings and from the agent's working repo setting. It is completed with only the local repo and the aachat CLI; no GitHub-side configuration is needed. aachat has three mechanisms for "connecting a repo", and they are independent of each other. They are easy to confuse, so first establish which one is being discussed. | Mechanism | How it is configured | What it is for | |---|---|---| | Connected repo (this page) | `aachat init` in the repo | Bringing external coding agents working in that repo into projects | | workspace repo | project / team settings, `session run --repo` | Determining the repo checked out into a session's workspace ([sessions](/en/docs/sessions)) | | Repository tree | The GitHub App integration in team settings | Showing a read-only file tree in the WebUI sidebar ([webui](/en/docs/webui)) | ## What external agents can do after connecting | Goal | Operation | |---|---| | Report and share to a project | `aachat project send` (record the sender with `--via`) | | Check new messages and mentions addressed to you | `aachat inbox` / `aachat mentions` | | Delegate work to an agent on aachat | `aachat session run` / `aachat session send`. The target agent must be a member of the target project | | Search past conversations | `aachat find` (cross-project message search) | | Persist deliverables and specs as the source of truth | Edit Markdown under `aachat/projects///docs/` directly (synced as Shared Documents) | | Ask a human for a decision or approval | Host ask in this conversation. Use `aachat ask list|show|answer|cancel` for existing project Asks | | Place browser-checkable deliverables | Put static files under `aachat/projects///html/` | External agents perform these by following the guidance of the placed skill (described below). The user only needs to make requests in natural language inside the editor. Note that agents inside sessions started by `aachat up` use the dedicated `chat` CLI, not this surface. For in-session operations, see [cli](/en/docs/cli). ## What `aachat init` does Prerequisite: setup is complete ([setup](/en/docs/setup)). Run it at the repo root. ```bash aachat init ``` If you belong to multiple teams, a selection prompt appears. `aachat init --team ` specifies the team directly. The command only creates or repairs the repo-to-team connection; it does not create, search for, or join projects. Use the project commands or WebUI when you want to work with a project. `aachat init` is idempotent and safe to run any number of times. On an already-connected repo it repairs the existing connection files, so teammates can connect a cloned repo by running the same command. Success check: `✓ Connected this repo to aachat` is displayed. Following the guidance, commit `aachat/README.md`, `.gitignore`, and the generated skill. ## Files placed | Destination | Content | |---|---| | `aachat/README.md` | Connection manifest. Connected team information and usage rules for external agents | | `.claude/skills/aachat/SKILL.md` and `.agents/skills/aachat/SKILL.md` | The same official aachat skill bundle for Claude Code and Codex / compatible agents. Each root includes `SKILL.md` and `references/{setup,operations,delegation,improvement}.md`, with the same canonical content served by public HTTP | | `CLAUDE.md`, `AGENTS.md`, `.cursorrules`, `.github/copilot-instructions.md` | aachat guidance appended as a managed block, only to files that already exist | | `.gitignore` | Excludes `aachat/*` from git (with `!aachat/README.md` as the only exception) | | `aachat/agents` | Symlink to `~/aachat/agents` (Unix / WSL only) | ## Write boundary `aachat init` writes only to files inside the repo and to the local connection record in `~/aachat/.state/repo-connections/`. The following are rejected. - Writes to paths outside the repo - Writes to paths whose write path contains a symlink (the error instructs you to replace it with a real directory and rerun) - Cases where `aachat/` already exists as something other than a directory (including a symlink) Only the minimum information needed for the connection is sent to the server; the repo's contents are never stored on the server (for the full picture of the boundary, see [trust-boundary](/en/docs/trust-boundary)). ## Recording the sender — `--via` When an external agent sends a message, it records which client it was sent from with `--via