Ardent is a desktop AI agent for professional teams. It adapts to your business, rather than making your business adapt to it. One way it does that is by turning work it learns to do into reusable tools we call abilities. When one teammate teaches Ardent how to solve a recurring problem, the result can become a tool the rest of the team installs instead of rebuilding the workflow from scratch.
Say someone on your team asks Ardent to pull the open Linear issues into a weekly summary: which projects moved, what stalled, what needs a decision this week. Ardent works out the workflow once, in conversation, and turns it into an ability: a small tool that queries Linear and writes the report. The next Monday it takes one sentence to run, and a teammate who installs it gets the same report without ever explaining the workflow.
That raises an uncomfortable question: if a model writes code that may run again next week, on a teammate’s computer, why should anyone trust it?
Our answer is that trust should not depend on the model grading its own work. Before a generated ability joins the agent’s toolbox, Ardent parses its declared access and checks its source without executing it. The user reviews any new access it requests. Only after approval does Ardent load the ability with the same Deno permission boundary it will use later, verify that the loaded package still requests the approved permissions, and activate it.
An ability is code with a boundary
An ability is a directory: a manifest, a README, a tools/ folder of TypeScript files, and an optional prompts/ folder. The manifest declares its baseline authority: filesystem paths, network hosts, system information, secrets by provider, and connected services. The manifest also declares versioned npm dependencies. Dependency code runs inside the same Deno permission boundary as the ability and receives no additional authority of its own.
Here is what the weekly summary’s manifest might look like, if the report also pulls deploy status from an internal endpoint:
{
"id": "abl_k7x04nd8w1q6zj3vb5c9f2",
"name": "weekly-linear-summary",
"description": "Summarizes open Linear issues into a weekly report.",
"npm": ["date-fns@^4.1.0"],
"permissions": {
"connectors": {
"linear": { "label": "Linear" }
},
"net": ["status.acme.dev"],
"read": ["./reports"],
"secrets": {
"acme-status": { "label": "Acme status API key" }
},
"write": ["./reports"]
}
}
Everything the ability can touch is on this page: the Linear connector, one internal host, one named secret, and a folder it can write reports into.
Every tool call runs in its own fresh Deno subprocess; nothing survives between invocations or is shared across abilities. Its permission flags begin with that manifest, so code cannot simply roam across the computer or internet. If a tool later needs access outside the manifest, Ardent stops and asks the user; an approved runtime grant is stored and applied to the retry.
Abilities run on your Mac inside a permission boundary. That boundary limits what the code can access; it does not guarantee that the code will use that access safely. For example, a tool allowed to read a customer export and call a company API could still misuse the data or the API. The manifest makes those limits explicit, and Ardent enforces them.
The authoring loop
When someone makes that weekly-summary request, the conversation switches into an authoring flow. The model first proposes a plan: a name, description, permissions, dependencies, and the tools and prompts it intends to create. Then it generates the files and asks to save them.
Save is not a direct write into the live toolbox. Ardent assembles the candidate in a staging directory and validates it first.
- Parse the package again. The manifest is loaded from disk rather than trusted from the model’s tool call, and its metadata must validate.
- Check the source. An AST-based policy rejects patterns abilities should not use, including subprocess APIs and direct environment-variable access. This is useful feedback, not the security boundary: source rules can miss things, while the subprocess permissions are enforced at runtime.
- Audit identifiable access. Ardent compares the network destinations, secret requests, and connector imports it can identify statically against the manifest. If the generated Linear tool imports the Linear connector without declaring it, the save fails with a structured manifest repair.
- Review the requested access. Before any ability module is imported, Ardent shows the user the authority the candidate would add. A new ability that requests any access shows its complete requested scope; an edit shows only permissions added since the active version. Declining discards the staged candidate and leaves the current ability unchanged.
- Load the ability for real. After approval, Ardent launches a Deno subprocess and imports the tool modules. This checks that the modules load and expose the tools and prompts in the authoring plan. It does not prove that those tools behave correctly.

Importing a module executes its top-level code, which is why approval comes first. The discovery subprocess gets its permission flags from the approved snapshot, not from another reading of the manifest. After discovery, Ardent derives the permissions from the staged package again and compares them with the permission identity the user approved. If they differ, activation stops. A module cannot change its manifest between inspection and import and inherit an approval for a different boundary.
Validation failures return structured repair guidance. Declining approval stops the authoring flow instead of asking again.
It is still just a directory
The generated files are ordinary TypeScript on disk. You can open them in an editor, inspect them, and change them. Ardent treats this directory as developer-controlled source, so changing its manifest is considered a deliberate action rather than triggering another approval dialog. The watcher still enforces the declared Deno permissions, but it does not have an authoring plan to compare against or rerun checks intended for model-generated saves.
Publishing and installing
Publishing packages an ability into a versioned release and sends it to the registry. Tool discovery runs again before the archive is uploaded so the release describes what the package actually exports.
Workspace abilities become available to teammates, but availability is not installation. The agent can suggest an existing ability during a task; a person still confirms any install that requests access. In the weekly Linear summary example, a teammate sees that the ability requests access to Linear before installing it:

Once installed, their agent can produce the same report without reconstructing the workflow.
What happens when permissions change
Code changes. The important question during an update is whether the new code asks for more authority than the installed version already had.
Release metadata includes a hash of the normalized permissions. When Ardent installs or switches versions, it unpacks the downloaded release and derives the permissions again from that package. If the package disagrees with what the catalog advertised, the earlier approval no longer matches and Ardent asks again using the package’s actual permissions.
When a user switches versions, equal hashes mean the requested authority is unchanged. If the hashes differ, Ardent compares the two permission sets. Newly added paths, hosts, system access, secrets, connectors, connector capabilities, or OAuth scopes appear in a confirmation dialog before activation. If v3 of the weekly summary starts pulling review status from api.github.com, that host — and only that host — is what your teammate is asked to approve. Permission removals do not prompt because they reduce authority.
The permission hash is not a signature or a hash of the code. It identifies the normalized authority requested by a version. Equal permissions do not mean equal behavior; a new version can use existing access differently. The guarantee is narrower and useful: a version cannot acquire new declared authority without another decision from the user.
What this does and does not solve
The system is designed to make generated code constrained, inspectable, and interruptible. Nothing in the chain asks a second model to grade the first one’s work: the checks are static, the boundary is enforced by the runtime, and the approval belongs to a person. It does not make generated code correct, replace judgment about sensitive access, or turn a permission dialog into a code review.
This is why we describe abilities as user-directed, not autonomous self-modification. The agent does not wake up and decide to expand itself. A person asks it to build, reviews the authority it requests, chooses whether to publish, and chooses whether to install an ability someone else shared.
What “adapts to your business” means
A solved problem becomes a directory. The directory becomes a validated, permissioned tool. The tool can become a workspace release, and the next person’s agent can start from there instead of from a blank prompt.
None of the individual pieces is exotic: a manifest, static checks, a subprocess, an archive, a permission diff. Together they create a learning loop in which one person’s solved problem can become a reusable capability for the team, without asking anyone to take the model’s word for what it built.
Ardent is available in public beta for Apple silicon Macs. Download Ardent.

