Skip to content

Agents and Apps

Hadron has two layers: an Agent and an App. They are different things, but they fit together cleanly. Read this once and the rest of the platform will make sense.

The PWA analogy

The clearest way to hold the relationship in your head is the Progressive Web App pattern. A web manifest plus some service-worker code is the app you install. Once installed, the running thing on someone's phone is also called an app — same word, but the install moved it from "code on a server" to "a thing in someone's pocket."

Hadron works the same way:

  • Agent is what you build. The conversation design, the system prompt, the AI config, the declared memory provisioning, the installation policy. One row, owned by one organization. This is what the marketplace lists.
  • App is what an Agent becomes once installed. An organization picks an Agent and installs it, and the running deployment in that org is an App: it has its own credentials, members, and surfaces.

If you want a one-line pitch:

Build an Agent. Use it or sell it.

You build the Agent once. Different organizations install it. Each install is a separate App — separate credentials, separate members, separate operational data — but they all reference the same Agent definition. When you publish a new version of the Agent, every install gets it (modulo the conversation-pinning rules for in-flight chats, which keep current sessions on the version they started with).

Why two layers

The class-instance split is not bureaucracy — it earns its keep:

  1. Reuse without copy-paste. "I want my own copy of Mealplan in my family's org" doesn't mean you re-author the entire conversation design. You install Mealplan; the install gets your credentials and members; the design stays at the Agent.
  2. Marketplace shape. The Agent is the listing. The App is the purchase. Without the split, every install would be a fork of the Agent and updates wouldn't propagate.
  3. Privacy isolation across installs. Two installs of the same Agent (Mike on MicroMentor and Mike on Company-X) have fully isolated app and personal memory. The addressing scheme keys those memories on (app_id, …) — the Agent's identity is not enough.
  4. Per-org policies. AI overrides, member counts, surface choice (chat / Slack / MCP / web) are deployment decisions, not author decisions. They live on the App, where they can vary across installs without touching the Agent definition.

Three concrete walkthroughs

Mealplan @ Acme Corp

Bea owns Bea's Bakery and authors Mealplan — an Agent with memoryProvisioning: { appMemory: 'shared' } and installationPolicy: { maxMembers: 'unlimited', memberRoles: ['owner', 'cook', 'eater'] }. Acme Corp installs Mealplan: their installation is Mealplan @ Acme, an App in Acme's org. Acme's owner Bob and Acme's chef Alice are AppMembers (bob/owner, alice/cook). All sessions through that App read Mealplan's design (the Agent stays read-only from any App context); their family meal-planning data accumulates in Acme's shared app-class memory, keyed on (mealplanAppId, mealplanAgentId).

Juno installed twice — Mike's multi-install

Mike mentors at MicroMentor and runs his own consultancy via Company-X. He uses Juno (memoryProvisioning: { appMemory: 'user' }, installationPolicy: { maxMembers: '2', memberRoles: ['principal', 'guide'] }) in both. There are now two Apps — Juno @ MicroMentor and Juno @ Company-X — both deploying the same Juno Agent. Mike is an AppMember of both. His mentee chat history at MicroMentor lives at (microMentorAppId, mike.id); his Company-X data lives at (companyXAppId, mike.id). Same Mike, same Juno, but every byte of operational data is keyed by the install. One side has zero visibility into the other.

Productivity Suite bundles Calendar and Notes

Bea publishes Productivity Suite, a parent Agent that imports Calendar (required) and Notes (optional) as deps. When Org-X installs Suite, Hadron cascade-installs Calendar automatically (it's required); Notes installs only if Org-X explicitly opts in via installOptional: [notesId]. If Org-X already had a standalone Calendar install, the cascade reuses it — there's only ever one App per (org, Agent) pair, no per-bundle namespacing. Bea's right to bundle Calendar comes from her org's AgentOrgGrant for Calendar; if the grant is missing or revoked, she can't publish the import.

What lives where

A short reference card. If you're trying to decide where a piece of data belongs, this is the cheat sheet.

Data Lives on Why
Conversation design (system memory) Agent One per Agent; what the marketplace sells
Default AI provider/model/key Agent Author's recommendation
AI override (provider/model/key) App Deployer's choice; supersedes the Agent default for sessions through this App
memoryProvisioning, installationPolicy Agent Declared by the author; the platform enforces
Credentials (hdr_app_… keys) App Per-install authentication
Members + roles App Per-install membership; role string validated against the Agent's installationPolicy.memberRoles
surfaces (chat / slack / mcp / web) App Per-install routing; the portal's chat-tab shows iff surfaces.includes('chat')
system-class memory Agent (Agent.systemMemoryId) Read-only from any App; edits happen in the Agent ownership surface
app-class memory App ((app_id, agent_id) or (app_id, agent_id, user_id)) Operational data, scoped to one install
knowledge-class memory Agent (via AgentMemoryItem) Reference content the Agent reads from; per-Agent, not per-install
personal-class memory App ((app_id, user_id)) Per-user data, scoped to one install — privacy-isolated across installs
AgentSubscription User ↔ Agent The user's grant to use this Agent (gates personal-memory access)
AgentOrgGrant Org ↔ Agent The org's grant to install or bundle this Agent
AgentImport Agent ↔ Agent A dependency edge; carries position + required + a Builder grant

How installation works in the portal

Every App is created by installing an Agent. The Install affordance lives on the Agent — both on the org's Agents list (one button per row) and on the Agent detail page. The org's Apps page is list-only: it shows your installed Apps but offers no in-page "create" button. To produce a new App, find the Agent you want to install and click Install on its row.

The install form is short by design — name, URN, and App type. AI configuration (provider/model/key) is intentionally not asked at install time; the new App inherits the Agent's defaults. If you need a per-App AI override, set it from the App manage page after the install completes.

You can install the same Agent into the same org more than once — useful when you want two Apps with different keys, surfaces, or memberships. The portal pre-fills a disambiguating App name ((2), (3), …) and URN suffix (-2, -3, …) so the second install doesn't collide with the first. (Cascade-imports of dependency Agents are different: the resolver reuses an existing dep App rather than creating a parallel one.)

In v1, you can install Agents your organization owns. Cross-org install — installing an Agent owned by a different org you're a member of — is hidden from the portal until the marketplace ships. (The server still auto-provisions an AgentOrgGrant on first install so 008's invariants hold; the portal is the user-visible boundary for now.)

What hasn't changed (you can stop worrying about these)

  • appKey is still appKey. The wire token still starts with hdr_app_. Your .hadron/config.json works as-is.
  • The HADRON_CLIENT_KEY env var is unchanged.
  • The app-class memory label survives even though it now describes "operational data of an installed Agent" rather than "data attached to an App in the old sense." Don't read too much into the label; the data shape is what matters.
  • Existing chatbot deployments authenticate without modification. The spec migration is structurally additive — your tokens still authenticate; your sessions still resolve to the right App.

Where to go next

  • Architecture — the entity hierarchy in full, including memory subscriptions and cross-org chains.
  • Subscriptions — when AgentSubscription matters vs AgentOrgGrant vs MemorySubscription.
  • Memory access — the four-gate cross-org evaluation chain and how the per-App isolation enforces privacy.