# The docent in Microsoft 365 Copilot

This page is for anyone who adds the docent to a Microsoft 365 Copilot agent. **ktl-docent-m365** is the docent as a custom skill for a Copilot declarative agent, not a skill of its own.

Copilot runs skills with no repository, shell or network. So the skill carries a **snapshot** of the bundle, and the docent answers from it.

## 1. Get the zip

**Download it from a release.** There is nothing to install.

1. Open the repository's Releases page on GitHub.
2. Under the release's Assets, download `ktl-docent-m365-<tag>-<repository>.zip`, where `<repository>` is the repository's name or the name its `KNOWLEDGE_RELEASE_NAME` variable sets.

The release workflow attaches it beside the bundle zip whenever the bundle changed. A release lacks it when the bundle did not change, or when the repository has no `.lokf/m365/`. When the bundle did not change, take the zip from the last release that carries one.

**Or build it yourself.** A repository on another forge, or on none, runs the same builder the release workflow runs, on its bundle folder. It needs bash and `zip`.

```bash
.lokf/m365/knowledge-m365.sh --repo-url https://github.com/me/my-repo --ref v1.2.0 .lokf/knowledge ./dist
```

It creates `dist/ktl-docent-m365/`, with `SKILL.md`, `SNAPSHOT.md` (repository, revision, build date) and `knowledge/`, and `dist/ktl-docent-m365.zip`. In a git clone only tracked files are copied, and hidden files such as `.obsidian/` are left out. With `SOURCE_DATE_EPOCH` set, one input gives one zip. The build writes nothing and exits 1 if a skill breaks one of Copilot's limits. [If something goes wrong](https://noelmcloughlin.github.io/knowledge-trust-ladder/docs/m365/#if-something-goes-wrong) lists them.

## 2. Add it to an agent

First, check that your tenant has custom skills. They are in preview, only for organizations in Microsoft's Frontier program, and not in tenants that use Information Barriers. Ask an admin if you are not sure. Without the preview, both routes below fail, and neither error says why: the toolkit's `provision` refuses the `agent_skills` entry, and Agent Builder sends you to Copilot Studio. [If something goes wrong](https://noelmcloughlin.github.io/knowledge-trust-ladder/docs/m365/#if-something-goes-wrong) quotes both errors.

Two routes take the same zip. Pick Agent Builder unless you already develop agents with the toolkit.

**With Agent Builder, nothing installed.**

1. In Microsoft 365 Copilot, open Agent Builder. Create an agent, or open one you own.
2. Add the zip as a skill. Agent Builder takes the skill as one zip. Microsoft's page on [custom skills in declarative agents](https://learn.microsoft.com/en-us/microsoft-365/copilot/extensibility/declarative-agent-skills) shows where.

**With the Agents Toolkit, for developers.** This needs [Node.js](https://nodejs.org/) and a Microsoft 365 account that may add agents.

1. Install the [Agents Toolkit CLI](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/microsoft-365-agents-toolkit-cli): `npm install -g @microsoft/m365agentstoolkit-cli`, then `atk auth login m365`.
2. Create an agent, then change into the folder `atk new` made for it. Run every later `atk` command there. To use an agent you have, change into its folder instead.

   ```bash
   atk new -c declarative-agent -n my-docent -i false
   cd my-docent
   ```

3. Turn skills on for this shell, then add the zip from wherever you saved it. The toolkit turns skills on only when a variable is set, and the variable's name depends on the version: `TEAMSFX_AGENT_SKILLS` in the 1.1.17 release, `ATK_FRONTIER` from the 1.1.18 betas on. Export both, and the steps work with either:

   ```bash
   export TEAMSFX_AGENT_SKILLS=true ATK_FRONTIER=true
   atk add skill --from ../ktl-docent-m365-v1.2.0-my-repo.zip -i false
   ```

4. In the same shell, run `atk provision --env dev`, then `atk preview --env dev`. The variable must still be set: without it, the toolkit packs the agent without the skill's files but keeps its entry. Skip `atk validate` for now, because it rejects the `agent_skills` entry that step 3 wrote, as [If something goes wrong](https://noelmcloughlin.github.io/knowledge-trust-ladder/docs/m365/#if-something-goes-wrong) explains.

Whichever route you take, an agent cannot have skills and embedded files together yet.

## 3. Ask it something

Ask the agent a question the bundle answers, such as what a service does or who owns it. The answer names the snapshot, its version and build date, and each concept it rests on with a trust label, such as *confirmed by a person* or *draft*. An answer with no snapshot in it did not come from the skill.

When the docent cannot answer, or two concepts disagree, it ends with one line for you to paste into the repository's `.lokf/feedback.md`, and `SNAPSHOT.md` says where to send it. It never records the gap itself. File the line in the repository, and the repository's librarian turns it into a concept or a question for the curator.

## Keep it current

The snapshot does not update itself. After each release that changes the bundle, take the new zip and add it again. The workflow packs the skill only when the bundle changed, so a release that brings new instructions and the same bundle carries no new zip. Run the workflow by hand with `force` for that tag.

## If something goes wrong

- **The release has no `ktl-docent-m365-…` asset.** [Get the zip](https://noelmcloughlin.github.io/knowledge-trust-ladder/docs/m365/#1-get-the-zip) gives the two reasons, and where to take the zip from.
- **The build exits 1.** The skill breaks one of Copilot's limits, and the output names which: `SKILL.md` over 20,000 characters, folders more than 3 deep, file types Copilot does not accept, more than 350 files, more than 10 MB, or symbolic links. Nothing is written.
- **The build says `zip not found`.** The folder is built but not zipped. Install `zip`, or zip the folder yourself before adding it.
- **`atk add skill` is not a command** (`UnknownCommandError`). Export both `TEAMSFX_AGENT_SKILLS=true` and `ATK_FRONTIER=true`, as [Add it to an agent](https://noelmcloughlin.github.io/knowledge-trust-ladder/docs/m365/#2-add-it-to-an-agent) does. Which one your toolkit reads depends on the version `atk --version` prints.
- **`atk add skill` says `InvalidProjectError`: `m365agents.yml` not found.** The command ran outside the agent's project. Change into the folder `atk new` created (`cd my-docent`), or add `--folder ./my-docent` to the command.
- **`atk validate` says `property name must be valid` for `agent_skills`.** Toolkit 1.1.17 and the 1.1.18 betas check the agent against the v1.8 manifest schema, the newest published, which has no `agent_skills` yet. The toolkit's own `add skill` wrote the entry, so the zip is not at fault. Skip `validate`, and let `provision` decide.
- **`atk provision` fails at `teamsApp/validateAppPackage` with `Unrecognized member 'agent_skills'`.** Microsoft's service refused the entry, not just the local schema. Check that the tenant has custom skills, as [Add it to an agent](https://noelmcloughlin.github.io/knowledge-trust-ladder/docs/m365/#2-add-it-to-an-agent) says. By then `teamsApp/create` has registered an app, whose ID `provision` prints as `TEAMS_APP_ID`. If you give up on this agent, delete that app in the [Teams Developer Portal](https://dev.teams.microsoft.com/apps).
- **Agent Builder says skill attachments require the full Copilot Studio experience.** Copy the agent to Copilot Studio from the top-right menu, and add the zip there. Copilot Studio needs its own licence or trial. If it says sign-up is disabled by your admin, the tenant has no licence for you, and only an admin can give you one.
- **Agent Builder or the toolkit refuses the skill for another reason.** Check whether the agent already has embedded files. That is a preview limit, not a fault in the zip.

## How it is put together

**One pattern for every read-only role.** A KTL Copilot skill is an instructions file plus the snapshot. `.lokf/m365/` holds one instructions file per role, named after the skill it becomes, and the builder packs each into its own zip. The docent is `ktl-docent-m365.md`. An auditor, the third line in [three-lines.md](https://noelmcloughlin.github.io/knowledge-trust-ladder/docs/three-lines/), would be `ktl-auditor-m365.md` beside it, with no change to the builder, the workflow or the checks.

**Why not the curator yet.** The librarian and the sidecar need a repository and a shell. The curator could follow once an action lets the agent write to SharePoint and there is a way to record who confirmed what without a forge login. The curator's [domain-schemas.md](https://github.com/noelmcloughlin/knowledge-trust-ladder/blob/a70038260880b7d9f47cd7e8ac796b2a2213168e/skills/ktl-curator/references/domain-schemas.md) holds the shape of that record.

**Change the instructions.** Edit [ktl-docent-m365.md](https://github.com/noelmcloughlin/knowledge-trust-ladder/blob/a70038260880b7d9f47cd7e8ac796b2a2213168e/skills/ktl-sidecar/templates/m365/ktl-docent-m365.md), which the build packs as the skill's `SKILL.md`. It is named after the skill, not `SKILL.md`, so installers don't list it as one. Its trust labels must match ktl-docent's, and the repository checks enforce that. A host's releases pack its own copy under `.lokf/m365/`, so a host that edits it changes what its readers' Copilot follows.

## Where the rest is written

- **What Copilot allows, what the toolkit checks, and how the curator's needs map to Microsoft 365** are in the sidecar's [references/m365.md](https://github.com/noelmcloughlin/knowledge-trust-ladder/blob/a70038260880b7d9f47cd7e8ac796b2a2213168e/skills/ktl-sidecar/references/m365.md).
- **Building on a host without git** is in the sidecar's [portability.md](https://github.com/noelmcloughlin/knowledge-trust-ladder/blob/a70038260880b7d9f47cd7e8ac796b2a2213168e/skills/ktl-sidecar/references/portability.md).
- **The release step** that attaches the zip, and when it runs, is the `knowledge-release.yaml` row in [ktl-sidecar's SKILL.md](https://github.com/noelmcloughlin/knowledge-trust-ladder/blob/a70038260880b7d9f47cd7e8ac796b2a2213168e/skills/ktl-sidecar/SKILL.md). [releasing.md](https://noelmcloughlin.github.io/knowledge-trust-ladder/docs/releasing/) says how a release comes about.
- **What the docent does with a question**, step by step, is the instructions file itself, [ktl-docent-m365.md](https://github.com/noelmcloughlin/knowledge-trust-ladder/blob/a70038260880b7d9f47cd7e8ac796b2a2213168e/skills/ktl-sidecar/templates/m365/ktl-docent-m365.md).
