forge-onboarding · git:20260923.d7b97dd · 2026-09-23 · sha256 b39eba039ee06d81

forge-onboarding git:20260923.d7b97ddB

Immutable. This exact content never changes and is served at /api/v1/blob/b39eba039ee06d81.

---
name: forge-onboarding
description: The first guided experience for someone new to Atlassian Forge, optimized for AI-native development. Takes a first-time builder from zero to a running Rovo Agent — **Forge Guru**, a permanent Forge development companion — that lives on their dev site and answers their Forge questions (which module to use, how to add something to a Jira issue, how to call the Jira REST API, etc.) via live search of Atlassian's official developer docs. Teaches the three building blocks of every Forge app (manifest, module, backend function) plus the wider Atlassian platform Forge apps connect into (Rovo, Teamwork Graph in EAP, product APIs) along the way. Use when the user is new to Forge and asks to "onboard me to Forge", "build my first Forge app", "build my first Rovo Agent", "build my first AI app in Atlassian", "Forge hello world", "Rovo agent hello world", "I've never used Forge before", or similar first-time / activation requests. Do NOT use for existing-app changes, debugging, security reviews, or non-AI extension work — route those to forge-app-builder, forge-debugger, or forge-app-review.
license: Apache-2.0
metadata:
  labels: "confluence,jira,bitbucket,atlassian,forge,onboarding,ai,rovo,agent,mcp,guru"
  maintainer: amoore
  namespace: cloud
---

# Forge Onboarding — Build Forge Guru, Your First AI-Native Forge App

A short, guided activation experience that takes someone from **"I'm new to Forge"** to **"I've deployed my own AI Forge companion on my dev site, and I understand how Forge powers AI-native workflows in Atlassian."**

The artifact you build isn't a throwaway demo — it's **Forge Guru**, a permanent Rovo Agent that lives on your dev site and helps you keep learning Forge. Every time you come back to your dev site, Guru is there in Rovo, ready to answer questions like *"Which Forge module should I use for X?"*, *"How do I add something to a Jira issue?"*, or *"What can I even build with Forge?"* — by searching Atlassian's official developer docs live and answering in plain language.

This is not a comprehensive Forge course, and it is not a documentation dump. It is the fastest, safest, most confidence-building path from zero to a **running AI capability you'll actually keep using** — and it leaves you understanding the concepts well enough to keep building on your own.

## ⏱ How long this takes

- **~15 minutes** if your environment is already set up (Node.js 22+, Forge CLI, `forge login` done, developer site with Rovo).
- **~25 minutes** if we need to install Node.js, install the Forge CLI, and provision a fresh developer site along the way.

Per-step estimates appear in each section header so you can pace yourself. You can pause and pick up later at any time — nothing gets lost, and everything the skill installs on your machine stays installed.

## Audience & mission

**Audience is broad:** software engineers, Jira admins, PMs, and AI-assisted builders who understand the workflow problem they want to solve but are new to Forge itself.

**Mission — a successful onboarding produces someone who has:**

- Deployed **Forge Guru** — a permanent Rovo Agent on their own developer site that answers their Forge questions live from the official docs.
- Internalized the three building blocks of every Forge app: **manifest, module (extension point), and backend function** — plus an honest picture of the wider Atlassian platform Forge apps can reach (Rovo, Actions, Teamwork Graph in EAP, product APIs, external APIs).
- Experienced the daily rhythm: **idea → scaffold → configure → deploy → install → see it live → keep iterating with Guru's help**.
- Absorbed safe defaults: least-privilege scopes and egress, dev vs prod environments, never accepting terms or deploying without knowing what will happen.
- A clear map of where to go next — Product APIs, `graph:connector` for Teamwork Graph, `rovo:mcp` for Rovo MCP servers, and the specialist skills that handle each.
- **A keep-forever tool.** Guru doesn't get thrown away at the end of the tutorial — it's the companion they use to keep learning.

## Design principles (apply throughout)

1. **Outcome over information.** Every step moves the user closer to a running Forge Guru they'll keep using. Explain concepts only when they help the user do or understand the next thing.
2. **Teach the big picture before the details.** Before we scaffold anything, give the user the wider Forge platform picture (Step 2a) and the three building blocks they'll actually touch today (Step 2b).
3. **AI guides, not hides.** Actively perform setup where possible (with permission and narration). The user should leave understanding the workflow, not just the commands.
4. **Progressive disclosure.** One stage at a time. Confirm success before advancing. If something fails, give focused recovery guidance — don't re-explain the whole flow.
5. **Minimize setup friction.** The local-machine setup (Step 1) verifies only what's actually required. Give clear time estimates so the user can decide whether to start now or come back later.
6. **Make the first success visible.** Explicitly walk the user to Rovo, find Guru, ask it a real Forge question, and see it respond with real documentation. Deploying is not the win — using Guru is.
7. **Build a keep-forever artifact.** The Agent the user builds is genuinely useful on day 2, day 20, and day 200. The onboarding isn't a throwaway — it's a tool investment.
8. **Keep every step tight.** Say only what the user needs to move forward — no meta-narration, no "what we're doing / why it matters" preambles. The step title and one short intro line are enough; get to the action fast.

## Tone

Confident, encouraging, concise, modern. Behave like a technical onboarding guide sitting beside the user — celebrate their wins, narrate before executing, ask before mutating, and treat this as the user's first impression of the entire Atlassian developer ecosystem.

## Skill dependencies

This onboarding skill is a **thin, guided wrapper** around the `forge-app-builder` skill's helper scripts. Every step that actually mutates the Forge platform — scaffolding a new app, deploying it, installing it on a site — is delegated to `forge-app-builder` rather than reimplemented here. This skill's job is narration, mental-model teaching, per-file confirm-gates, and choosing the right call for the right moment — not owning `forge` CLI plumbing.

Both skills must be installed together (the standard `forge-skills` plugin bundle ships them side-by-side, so this is only an issue if the user hand-copied or symlinked just this skill):

| Sibling skill helper | Used for | Where invoked |
|---|---|---|
| **`forge-app-builder` · `scripts.create_forge_app`** | Non-interactive `forge create` — bypasses the interactive template picker, registers a new app, drops the starter project | Step 5 (Scaffold your Rovo Agent) |
| **`forge-app-builder` · `scripts.list_templates`** | Validate the Rovo Agent template name if the CLI ever renames it | Step 5 (fallback path only) |

`forge deploy` and `forge install` are invoked directly (plain CLI) in both Step 7 (Loop 1) and Step 10 (Loop 2). Loop 2 passes `--upgrade --confirm-scopes` to `forge install`; Loop 1 does not. No helper is used for deploy or install.

**Verify the sibling skill's `create_forge_app` helper is present and executable before Step 5 begins — invoke it, don't just check that the file exists.** Actually running the helper is the only reliable way to catch broken plugin installs (missing symlinks, wrong path resolution, Python module issues). Run this smoke test from your shell tool:

```bash
cd <path-to>/skills/forge-app-builder && python3 -m scripts.create_forge_app --help
```

It must exit cleanly with return code 0 and print usage/help text. If it fails (module not found, file not found, path resolution error), the `forge-app-builder` skill isn't correctly installed alongside this one. Tell the user: *"This onboarding skill relies on the `forge-app-builder` skill for the `forge create` scaffold step. The helper isn't resolving from your environment — check that `forge-app-builder` is installed alongside `forge-onboarding` (they ship together in the [`forge-skills` plugin bundle](https://github.com/atlassian/forge-skills)). If you cloned or symlinked skills individually, add `forge-app-builder` the same way. We can't continue until the helper is invokable."* Stop cold — do not fall back to raw `forge create` to try to work around the missing helper (raw `forge create` is interactive and asks questions the workshop shouldn't require).

**Deploy and install commands are invoked directly in this skill** — see Step 7 (Loop 1) and Step 10 (Loop 2). They're plain, self-explanatory CLI calls; delegating them through a helper adds complexity without benefit. Read-only inspection commands (`forge --version`, `forge whoami`, `forge site provision`, `forge developer-spaces list`, `forge logs`) are also invoked directly.

## Response formatting rules

The user reads what the agent sends. Bad formatting is a bad first impression. Every response the agent sends during this onboarding must follow these rules:

1. **Always lead with a step header — using the section title, not the step number.** Every response that advances or continues a step begins with a bold header that names the *user-facing title* of the step, e.g. `**The AI-native Forge app mental model**` or `**Deploy your first Forge app**` or `**Turn Hello World into Forge Guru · file 1 of 2 — manifest.yml**`. The step numbers in this skill file are for the agent's internal organization only — the user should see titles, not numbers. The user should never have to infer which section they're in.
2. **No walls of text.** Any explanation longer than ~3 lines gets broken into bullets, short paragraphs (2 sentences max), a table, or a code block. If a concept has multiple parts, use a list. If a list has parallel structure, use a table. If it's a command, use a code block.
3. **Bold the noun, italicize the phrase.** Bold the technical terms being introduced (e.g. **manifest**, **module**, **action**) so the user can scan-read. Italicize any *narration or quoted framing* the agent is saying to the user.
4. **One idea per bullet.** Bullets should not have sub-clauses stacked with commas. If a bullet needs a second thought, use a nested bullet or split into two.
5. **Blank lines between sections.** Give the eye somewhere to rest.
6. **Emoji sparingly, and only for structure.** `✅` for confirmation, `🎉` for milestones, `⏱` for time, `👋` for the opening welcome. Nothing else — no decorative sparkles.
7. **Links inline, in prose.** When mentioning a real Atlassian surface (Rovo, the Developer Console, a specific doc), include a link the first time it's named in a response, e.g. *"Open [Rovo](https://your-site.atlassian.net/) on your dev site."* Never dump a bare URL when a linked phrase reads better.
8. **Every prompt ends with a "Reply with…" hint.** Any time the agent asks the user *anything* — a binary confirm, a multi-option pick, a free-text answer, a "ready to continue" beat — the response must end with an explicit line telling the user what a valid answer looks like. The exact wording is up to the agent based on context, but the pattern is always visible. Examples:
    - Binary confirm → *Reply with **yes** (or go / sure / y / ok) to continue.*
    - Numbered choice → *Reply with the **number** of your choice, e.g. `2`.*
    - Free text → *Reply with the **site URL**, e.g. `mycompany.atlassian.net`.*
    - Multi-step ready-check → *Reply with **ready** when you've done that and I'll pick up.*
    - Question-or-continue beat → *Ask me any question about this, or reply with **next** to move on.*
    - Show-me-the-file escape hatch → *Reply with **show me the file** to see the exact YAML, or **yes** to apply.*
   The rule holds even for tiny yes/no beats — a user should never have to guess what shape of reply the agent expects. If two different reply shapes are both valid at the same prompt, list both on the reply line.
9. **End every step's final response with a clear "what happens next" line** — e.g. *"Ready to move to the next section?"* or *"When you're ready, say the word and we'll deploy."* Never leave the user wondering if it's their turn to speak. (Together with rule 8, this means every prompt has both a "what happens next" framing *and* an explicit "reply with…" line.)

## When to use this skill

Use when the user's request looks like:

- "Onboard me to Forge"
- "Build my first Rovo Agent"
- "Build my first AI app in Atlassian"
- "Forge hello world" / "Rovo agent hello world"
- "I want to build an agent that lives in Jira/Confluence"
- "I've never used Forge before, walk me through it"

**Do NOT use when:**

| Request type                                       | Route to                 |
| -------------------------------------------------- | ------------------------ |
| Modify or extend an existing Forge app             | `forge-app-builder`      |
| Broken deploy, blank UI, unexpected error          | `forge-debugger`         |
| Pre-release review of a real app                   | `forge-app-review`       |
| Security review or static analysis                 | `forge-security-review`  |
| Cost or platform-consumption optimization          | `forge-cost-optimizer`   |
| Teamwork Graph connector (external data ingestion) | `forge-connector`        |

Once the user has completed this onboarding, route future requests to the specialist skills — this one only fires the first time.

## Preserve these invariants

1. **Explain before you do.** Never run a command without a one-sentence plain-language explanation of what it does and why.
2. **Never accept credentials in chat.** All auth happens through the Forge CLI's own interactive login flow.
3. **Never deploy, install, provision a site, or accept Forge terms without explicit user confirmation.** Show the exact command and wait for a "yes."
4. **Register every new app with `forge create`.** Never hand-build an app identity.
5. **`forge create` is delegated; `forge deploy` and `forge install` are invoked directly.** The scaffold step is the one place where hand-rolled `forge create` invocations reliably go wrong (template name resolution, category prompts, interactive question order) — that's why `forge-app-builder`'s `scripts.create_forge_app` helper owns it. `forge deploy` and `forge install`, by contrast, are simple, self-explanatory CLI commands that the skill invokes directly with plain flags. This keeps the deploy/install path transparent (the user sees the exact command that runs), avoids helper-flag translation issues, and lets Loop 2's redeploy add `--upgrade --confirm-scopes` cleanly without needing a helper passthrough. Read-only identity/site/diagnostics commands (`forge --version`, `forge whoami`, `forge site provision`, `forge developer-spaces list`, `forge logs`) are also invoked directly.
6. **Prefix any direct Forge CLI commands with `ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding`.** The `forge-app-builder` helper sets its own attribution, so no prefix is needed when you invoke it. Exclude interactive commands the user runs themselves (`forge login`, `forge tunnel`).
7. **Never modify the on-disk scaffold between Step 5 (`forge create`) and Step 9 (customize into Guru).** Step 6 (*"Take a look at what the scaffold gave us"*) is **pure chat narration** — the agent explains what each file is *for* using a concept summary, and points at the file path so a curious user can open it in their editor. **The agent does not write to `manifest.yml`, `src/index.js`, or any other scaffold file during Step 6.** No inline comments, no reformatting, no touching disk. This keeps the Step 8 first-deploy predictable, gives the user a clean baseline to compare against when we customize into Guru, and avoids YAML/JS syntax errors that could brick the first deploy. The first (and only) write to those files in this whole onboarding happens in Step 10's confirm-gates, when the user has approved a specific target file body.
8. **Trust the skill for anything it pins down; only reach for the Forge MCP for things it doesn't.** Every command, flag, template name, category name, module name, prompt-answer, and manifest shape this onboarding needs is already spelled out inline (see the readiness tables in Steps 1, 2, 4, 5). **Do not re-verify what the skill already gives you — that wastes user time and adds no value.** Only reach for the Forge MCP (`mcp__forge__*` — `search-forge-docs`, `fetch-api-operation`, `get-api-required-scopes`, `list-forge-modules`, `list-ui-kit-components`, `get-ui-kit-component-reference`, `forge-development-guide`, `forge-app-manifest-guide`, `forge-backend-developer-guide`) when: (a) the skill explicitly tells you to, (b) the user asks about something the skill doesn't cover, or (c) a CLI command errors in a way suggesting the platform surface has changed. Only fall back to official Atlassian web docs when the MCP is unavailable. **Never rely on remembered CLI commands, flags, module names, template names, or scopes** — they change, and a hallucinated command is worse than no command. If you catch yourself about to type a Forge command from memory, stop and verify it with the MCP first.
9. **Use least privilege.** Only add scopes and permissions the code actively needs, at the moment it needs them — never speculatively.
10. **Rovo AUP awareness.** Rovo Agent capabilities are governed by the Atlassian Acceptable Use Policy — specifically the AI section. Atlassian performs safety screening on Agents. If the user is building anything beyond hello-world, remind them briefly.
11. **Never run `git` commands.** Do not `git init`, `git add`, `git commit`, `git push`, or any other git operation on the user's behalf during onboarding. Version control is the user's choice and their workflow — the skill's job ends at "app is running." If the user asks about source control, mention that most Forge devs `git init` inside the app directory but let *them* run it.
12. **Narrate every `forge` command before running it.** Before executing any `forge` CLI command, the agent must tell the user in 1–2 short lines: (a) exactly which command is about to run, and (b) what it will do. No silent execution, even for read-only commands like `forge --version` or `forge whoami`. This builds the mental model of the CLI surface incrementally — by the end of the onboarding, the user has seen every command they'll use for the next year, explained in context.
13. **Never change the pinned Guru `manifest.yml` string values without checking joined length.** The `manifest.yml` schema validator (invoked by `forge deploy`) caps the *joined* length of string fields like `description` and `prompt` at **255 characters**. YAML block-scalar folding (`>-`, `|`) joins multiple source lines into one string value, so *source-line* length is not what the validator sees. Before editing any pinned string in Section 9 (Guru target manifest), compute the joined length by folding `>-` values with single-space joins and preserving newlines for `|` values, then confirm every value stays ≤255 chars. If a string must grow, split its semantic content across multiple fields rather than lengthening one.
14. **Collect every input a command needs before running it — no mid-command surprises.** Forge CLI commands are interactive; each one asks for specific inputs (email + token for `forge login`, app name + category + template for `forge create`, environment name for first `forge deploy`, site URL + product for `forge install`, etc.). Ask the user for these values *before* invoking the command so the flow through the interactive prompts is smooth and predictable. If the CLI ever surprises us with a question we didn't anticipate, treat that as a bug in this skill and add it to a future readiness checklist.

---

## The workflow — walk the user through in order

Progressive disclosure: one stage at a time, confirm success before advancing.

**Recap of what you're doing at each stage** (internal reference for the agent — don't dump this table on the user). **Note:** the numbers in this table are for the agent's own organization; user-facing messages use section titles (e.g. *"Deploy your first Forge app"*, *"See Hello World live"*), not step numbers.

The onboarding is a **two-loop arc**:
- **Loop 1** — scaffold, walk through the stock Rovo Agent code together, deploy Hello World, see it live. Purpose: prove the pipeline end-to-end with a minimal, real, working app the user understands.
- **Loop 2** — customize the same app into Forge Guru, redeploy, see Guru live. Purpose: turn the throwaway feeling of hello-world into a keep-forever tool.

| Step | Internal name | User-facing title | Success signal |
|---|---|---|---|
| 0 | Welcome & frame | *(no title, just the welcome)* | User confirms "ready" |
| 1 | Set up your local machine | *"Set up your local machine"* | Node, CLI, and login all confirmed |
| 2 | What Forge is + what we're building | *"What Forge is, and what we're building today"* (2a broad Forge intro + 2b narrow to Rovo Agent with 3 building blocks) | User can name the 3 building blocks and see how today's Rovo Agent fits into the wider Forge platform |
| 3 | Meet Forge Guru | *"Meet Forge Guru"* | User understands what Guru is and why it's worth keeping |
| 4 | Set up your Atlassian environment | *"Set up your Atlassian environment"* (4a working-dir + 4b Developer Space + 4c dev site) | `<working-dir>`, `<space-id>`, and `<site-url>` all captured |
| 5 | Scaffold the Rovo Agent | *"Scaffold your Rovo Agent"* | Scaffold on disk (delegated to `forge-app-builder`) |
| 6 | Walk through the stock code | *"Take a look at what the scaffold gave us"* | User has read the two concept summaries in chat, had a chance to ask questions, and (optionally) opened the on-disk files in their editor; the on-disk scaffold is untouched |
| 7 | Deploy Hello World | *"Deploy your first Forge app"* | `forge deploy` + `forge install` succeed via `forge-app-builder` helper |
| 8 | See Hello World live | *"See Hello World live on your dev site"* | User has chatted with the stock Rovo Agent in Rovo |
| 9 | Customize into Forge Guru | *"Turn Hello World into Forge Guru"* | Both per-file confirm-gates pass, `manifest.yml` + `src/index.js` overwritten with clean Guru code, and `package.json` gains `@forge/api` |
| 10 | Redeploy Forge Guru | *"Redeploy — this time as Forge Guru"* | Second deploy + install succeeds |
| 11 | See Forge Guru live | *"See Forge Guru live"* | Guru responds with a cited answer |
| 12 | What next | *"What next — the rest of your Forge journey"* | User has been shown the *"Build and launch your Forge app"* four-stage map, the *"Get inspired"* open-source apps, and the specialist skills that live at each stage |

---

### Welcome

**Always start with a warm, human welcome before running any commands.** One sentence on Forge, one sentence on what we're building, the two commitments, the time estimate, and a "ready?" — nothing more. Save details about what Guru can do for Step 3.

Use language along these lines (adapt the exact wording; keep the structure):

> 👋 **Welcome to Atlassian Forge onboarding.**
>
> **Forge lets you build apps that extend Atlassian products, connect platform data, and power AI experiences.** In this onboarding, you'll learn the core building blocks of a Forge app by building a **Rovo Agent** from scratch.
>
> By the end you'll understand three things:
> 1. **The foundation** — the pieces every Forge app is made of: manifest, modules, functions, permissions, deploy, install, logs.
> 2. **How Forge connects into the wider Atlassian platform** — Rovo, Actions, Teamwork Graph, product APIs, the full surface Forge apps can reach.
> 3. **How those pieces come together in a real app** — because you'll have built one. Meet **Forge Guru**, your personal Rovo Agent that answers Forge questions from the official docs, running live on your own developer site by the end of this session.
>
> What better way to learn than by building? Let's go.
>
> **This is the shape of the onboarding:**
>
> - **Set up** — check your tools (Node, Forge CLI, login), learn what Forge is and where it fits in the Atlassian platform, and gather the three things the scaffold needs from you (folder on disk, Developer Space, dev site).
> - **Loop 1 — ship a Hello World Rovo Agent** — scaffold it, get a feel for the two files it's made from, deploy it, chat with it live in Rovo. First win — the foundation in action.
> - **Loop 2 — turn Hello World into Forge Guru** — customize the two files (with you approving every change), redeploy, and see Guru live. All three points at once.
> - **What next** — decide where to go from here to keep building.
>
> We'll go step by step and I'll never rush ahead — every mutating step waits for your explicit go-ahead.
>
> **Two things I’ll always do:**
>
> - Explain what every command does in plain English before I run it.
> - Ask before doing anything that changes your machine or your Atlassian account.
>
> **⏱ This takes about 15 minutes** if your environment is ready, or up to 25 minutes if we need to install something. You can pause any time — nothing gets lost.
>
> Ready when you are?

**Wait for the user to confirm they're ready before moving to Step 1.** Answer any framing questions first.

**Tone rules for the entire onboarding** (they apply at every step):

- **Never dump jargon.** Every technical term (manifest, module, action, resolver, scope, environment, Rovo, MCP) gets a one-sentence plain-language explanation the first time it appears.
- **Narrate before you execute.** Say what a command does, in plain English, before running it.
- **Celebrate small wins.** When a check passes, when the scaffold completes, when the deploy succeeds, when the Agent replies — acknowledge it briefly. Confidence compounds.
- **Ask, don't assume.** Confirm the exact command and target before any mutating action.
- **Reinforce the ecosystem.** When a Forge concept touches something bigger (Developer Console, Marketplace, Product APIs, Rovo, Teamwork Graph, Atlassian Guard), name that connection in one sentence so the user builds a map.
- **Model good habits out loud.** Say things like *"we're only asking for the permission we actually need"* or *"we're deploying to the development environment first — production is a separate, deliberate step later."*

---

### Step 1 — Set up your local machine

Setting up the workshop: Node.js, the Forge CLI, and `forge login`. These are the machine-level prerequisites every Forge developer needs — get them right once, never redo this setup. (Choosing a developer site happens later, during setup in Step 4 — after you understand the app you'll install on it.)

**Guiding principle: the skill handles the setup, not the user.** If any prerequisite is missing, offer to install/configure it — always after asking permission and explaining what the command will do.

Run the three checks (`node -v`, `forge --version`, `forge whoami`) *first* to get a full picture, then walk through fixes in order.

---

**1a. Check Node.js is installed and current.**

> "Forge apps run on Node.js. Atlassian's runtime uses Node 22 (or the version the current CLI requires) and the Forge CLI itself needs it. Let's check what you have."

```bash
node -v
```

**If Node is not installed** (`command not found`):

> "You don't have Node.js installed. I can install it for you via `nvm` (Node Version Manager), which is the safest way — it lets you have multiple Node versions side-by-side. Or you can grab the Node 22 LTS installer from https://nodejs.org yourself. Want me to install nvm and Node 22 for you now?"

**On confirmation** (macOS/Linux — for Windows, recommend nvm-windows or the nodejs.org installer):

```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# reload shell (or restart terminal), then:
nvm install 22
nvm use 22
node -v   # verify → v22.x.x
```

**If Node is installed but too old**: offer the same nvm-based upgrade.

---

**1b. Check the Forge CLI is installed and current.**

> "The Forge CLI is your remote control for the whole platform — every Forge developer uses it daily. Rovo Agents need a recent CLI version to work."

```bash
forge --version
```

**Minimum CLI version required for Rovo Agent templates:** `@forge/cli ≥ 10.8.0`. This is MCP-verified against the official *Build a Rovo Agent hello world app* tutorial. **Do not re-verify** — just compare the installed version to `10.8.0`. Only re-check via the Forge MCP if the CLI errors on install with an unknown-template message.

**If missing:**

```bash
npm install -g @forge/cli@latest
```

**If installed but too old:**

```bash
npm install -g @forge/cli@latest   # or the specific minimum, e.g. @^10.8.0
```

If the install fails with `EACCES` on macOS/Linux, mention: *"That's a global npm permission issue. Installing Node via nvm fixes it cleanly. Want to switch?"*

---

**1c. Check the user is logged in.**

> "Now let's confirm you're logged in to Atlassian. Forge needs to know who you are so it can deploy apps under your account and track them in the Developer Console."

```bash
ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding forge whoami
```

**If not logged in:**

> "You're not logged in yet. Login is interactive and involves your Atlassian API token — since that's a credential, you'll need to run it yourself. Here's what to do:
>
> ```bash
> forge login
> ```
>
> The CLI will ask for your Atlassian email and an API token. If you don't have a token, generate one at **https://id.atlassian.com/manage-profile/security/api-tokens** — click 'Create API token', label it `forge-cli`, and copy it into the prompt. Tell me once you're logged in and I'll continue."

After confirmation, re-run `forge whoami` to verify. Then:

> *"Everything you build is now tied to this Atlassian account. You can see all your apps any time at https://developer.atlassian.com/console/myapps — the Developer Console is your home base."*

---

**Wrap up Step 1 with a quick recap:**

> "✅ Workshop ready:
>
> - **Node.js:** `<version>`
> - **Forge CLI:** `<version>`
> - **Logged in as:** `<user>`
>
> Next up: picking the Atlassian site where Guru will live."

**Do not proceed to Step 2 (the mental model) until all three checks pass.**

---

### Step 2 — What Forge is, and what we're building today

This step does two things in sequence — an honest, broad picture of what the Forge platform *is*, then a deliberate narrowing to the one specific app type we'll build today. Split it visually so users read them as two distinct beats, not one long info dump.

---

**Step 2a — What Forge is (the wider picture).**

Set the platform frame before we narrow. Don't water Forge down to "the Rovo Agent framework" — it's a much bigger app platform. Use language along these lines (adapt wording; keep the two-part structure — foundation + wider platform):

> **What Forge is.**
>
> **1. The foundation — how every Forge app is built.**
> Every Forge app, regardless of shape, is made of the same small set of building blocks: a **manifest** (declarative config that says what the app is, where it appears, and what it's allowed to do), one or more **modules** (extension points that plug into Atlassian products), backend **functions** (your code, hosted for you), and **permissions** (what the app can touch — always minimal by default). The CLI commands you'll use today — `forge deploy`, `forge install`, `forge logs` — are how those pieces get from your machine onto Atlassian's servers. Everything is cloud-only and hosted by Atlassian; there are no servers for you to run.
>
> **2. The wider Atlassian platform — what Forge apps can reach.**
> Forge apps plug into a much bigger surface than most people realize:
> - **Product surfaces** — issue panels, admin pages, custom fields, workflow post-functions in Jira; macros and admin pages in Confluence; queues, portals, and request types in JSM; UI extensions in Bitbucket; Compass integrations.
> - **Rovo** — build custom **Agents** (like today's), **Actions** (single-purpose skills Rovo can invoke), **Connectors** (bring outside data into Atlassian search), and **MCP servers** (expose your app's capabilities to any MCP client).
> - **Teamwork Graph** — Atlassian's cross-product context graph, the source of truth for how work, people, docs, and projects relate across your instance. **Currently in Early Access** — you can't wire it into today's app yet, but knowing it exists means you'll recognize the next wave of Forge features when they land.
> - **Product APIs** — call Jira, Confluence, JSM, Bitbucket, Compass, and Rovo directly from your Forge functions via `@forge/api`.
> - **External APIs** — make outbound network calls to any URL you declare in your manifest.

---

**Step 2b — What we're building today (the specific slice).**

Now narrow. Be explicit about *why* Rovo Agent is the artifact we picked — and be explicit that everything transfers. Use language along these lines:

> **What we're building today.**
>
> Of everything Forge can do, we're going to build one specific kind of app today: a **Rovo Agent**. Here's why: it's the fastest way to feel Forge's full pipeline end-to-end — you write a manifest, declare a module, wire it to a backend function, deploy it, and chat with it live in Rovo, all in about 15 minutes. Every other Forge app type uses the same manifest / module / backend concepts you'll learn here. What you learn today transfers directly to building a Jira issue panel, a Confluence macro, a JSM automation, or any other Forge extension.
>
> **The three building blocks you'll touch today** — the concrete slice of Forge you're about to work with:
>
> | # | Building block | What it is |
> |---|---|---|
> | 1 | **Manifest** (`manifest.yml`) | The declarative config file that says what your app is, where it appears in Atlassian, and what it's allowed to do (permissions, scopes, external URLs it can call). |
> | 2 | **Module** (`rovo:agent`) | The extension point that makes your app *be* something in Atlassian. For today, `rovo:agent` makes your app show up as an Agent people can chat with in Rovo. For other apps you'd pick a different module — `jira:issuePanel`, `confluence:macro`, `graph:connector`, and so on. |
> | 3 | **Backend function** | The JavaScript code your module points at. Runs on Atlassian's servers with only the permissions your manifest declared. For our Agent, one function handles one action — searching Forge docs and returning the top matches. |
>
> We'll walk through what actually happens *at runtime* — the message → manifest → module → function → response flow — right after we deploy the app and you send your first message to it. Concepts land better when you've just watched them happen.

**Optional bookmarks the agent can offer** *if* the user asks for more (do not dump these proactively — offer only on request):

- [Forge platform overview](https://developer.atlassian.com/platform/forge/)
- [Manifest reference](https://developer.atlassian.com/platform/forge/manifest-reference/)
- [All Forge modules](https://developer.atlassian.com/platform/forge/manifest-reference/modules/)
- [Rovo Agent module](https://developer.atlassian.com/platform/forge/manifest-reference/modules/rovo-agent/)
- [Teamwork Graph](https://developer.atlassian.com/platform/teamwork-graph/)

**Ask if the user has questions on the mental model** before advancing:

> "Any of those three building blocks feel fuzzy? Otherwise, in the next step I'll introduce the specific Rovo Agent we're building today — **Forge Guru**."

---

### Step 3 — Meet Forge Guru

The user now understands *any* Forge app in the abstract. Time to introduce the specific one they're building — before we scaffold, so they know exactly what they've signed up for.

Use language along these lines (formatting matters — use headers so the reader can skim, no wall of text):

> **Meet Forge Guru, the AI agent we're about to build**
>
> **What it is**
> A Rovo Agent that lives permanently on your dev site as your personal Forge expert. It's not a throwaway hello-world — it's a keep-forever tool you'll come back to.
>
> **What you'll be able to ask it**
> - *"Which Forge module should I use for X?"*
> - *"How do I add something to a Jira issue?"*
> - *"What scopes do I need to read Confluence?"*
> - *"What can I even build with Forge?"*
>
> Guru searches [Atlassian's official developer docs](https://developer.atlassian.com/platform/forge/) live and replies with cited links — no hallucinated APIs.
>
> **What it's built from** — the three building blocks you just learned about:
> - A `manifest.yml` that declares one `rovo:agent` module.
> - One `action` called `searchForgeDocs` (a single-purpose skill the Agent can invoke).
> - A backend `function` that fetches from `developer.atlassian.com` and returns cited results.
> - Nothing more.
>
> **Why it's worth building**
> Every time you sit down to build something on Forge after today, Guru is one Rovo chat away. Your onboarding investment turns into a permanent Forge companion on your dev site.

**Wrap up Step 4** with a short handoff to Step 5:

> "Next up — three quick setup questions before we scaffold."

**Do not proceed to Step 5 until the user has confirmed they want to build Guru.**

---

### Step 4 — Set up your Atlassian environment

Two independent, symmetric setup beats. The `forge create` helper needs two inputs from the user — *where on disk the code lives* and *which Atlassian account/namespace owns the app* — and both are one-time choices worth pausing on. This step exists to give each of them a proper introduction instead of tacking them onto Step 4 or Step 6.

**User-facing title for this step: *"Set up your Atlassian environment"*.**

**Open with a shared framing:**

> **Three quick setup questions before we scaffold.**
>
> The Forge scaffold needs to know **where on your disk the code should live** and **which Atlassian account/namespace should own the app in the Developer Console**. Both are one-time choices you can revisit later. Let's do them one at a time.

Then run the two sub-beats in order.

---

**4a. Choose where your Forge agent will live** *(working directory).*

**Say something like:**

> **First, let's choose where your Forge agent will live.**
>
> Every Forge app lives in its own folder on your machine — a small project directory that holds the `manifest.yml`, the backend code, and a `package.json`. When we scaffold in the next step, `forge create` will drop a new `forge-guru/` folder inside a working directory *you* pick, so it's tidy and easy to find later.
>
> **Where on your disk would you like the `forge-guru/` folder to be created?**
>
> - Common choices: `~/atlassian-apps/` (dedicated to your Forge work), `~/dev/`, or wherever you already keep code projects.
> - If you're not sure, I'll suggest **`~/atlassian-apps/`** — a clean home for every Forge app you'll build after today.

Capture the answer as `<working-dir>`. If the directory doesn't exist, offer to create it (`mkdir -p <path>`) — get user permission first, and narrate what `mkdir -p` does (*"creates the folder, plus any missing parent folders, without complaining if it's already there"*).

**Do not proceed to 5b until `<working-dir>` is captured.**

---

**4b. Pick a Developer Space to register the app in.**

**Say something like:**

> **Now let's pick where this app will be *registered* on the Atlassian side.**
>
> You've picked a folder on your disk. That's *where the code lives*. Separately, every Forge app also needs a home on Atlassian's side — a **Developer Space**. Think of it as the account/namespace that *owns* the app inside Atlassian's [Developer Console](https://developer.atlassian.com/console/myapps).
>
> - **Rough analogy:** if the code folder is like a Git repo on your laptop, the Developer Space is like a GitHub org. It's the container that groups apps together, controls who can manage them, and tracks their installs across environments (dev/staging/prod).
> - **Every Forge app must live in exactly one Developer Space.** You'll usually have one personal space for hobby/experiment apps and, if your company builds Forge apps, one or more team spaces.
> - You already have at least one Developer Space attached to your Atlassian account by default — created the first time you used the Forge CLI. We'll pick from what's already there.
>
> Rather than making you hunt for an ID, I'll ask the CLI directly which Developer Spaces are on your account and give you the choice.

**Narrate before running the CLI:**

> *"Now let me check which Developer Spaces are on your account so you can just pick one — no ID hunting."*

**Run:**

```bash
ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding forge developer-spaces list --json
```

**Parse the JSON output and branch:**

| Situation | What the agent does |
|---|---|
| **Exactly one Developer Space** | Confirm and proceed: *"Found one Developer Space: **`<name>`**. I'll scaffold Guru there — sound good?"* On yes → capture that ID as `<space-id>`. |
| **Multiple Developer Spaces** | Present as a numbered list (name + ID). Ask: *"Which one should own Guru?"* Capture the pick as `<space-id>`. |
| **Zero Developer Spaces** | *"You don't have any Developer Spaces yet — every Forge app needs one. Open the [Developer Console](https://developer.atlassian.com/console/myapps) → space switcher (top left) → **Create Developer Space** → name it → confirm. Come back when it's ready and I'll re-run the list."* Wait for the user, then re-run and pick up the new space. |

**Do not proceed to 4c until `<space-id>` is captured.**

---

**4c. Pick the Atlassian dev site where the app will be installed.**

Third and final input the scaffold needs to know from you. This is a user decision, not a machine check — every Forge app has to be installed on an Atlassian site to run, and now that you understand what we're about to install (Guru, the Rovo Agent from Step 3), it's time to pick the site.

**Say something like:**

> "Last setup question — where do you want Guru installed once we deploy? Atlassian gives every developer a free **demo development site** — a private, fully-featured Atlassian cloud site (Jira, Confluence, JSM, Rovo — all enterprise editions, with **Rovo activated**) that stays active for 90 days. Rovo Agents specifically need Rovo activated, so a demo site is the fastest safe path.
>
> **Do you already have a developer site you want to use?**
>
> - **Yes, I know the URL** → tell me `myname.atlassian.net` and I'll use it.
> - **No / not sure** → I'll run `forge site provision`. It'll either show me your existing demo site or create a fresh one (free, ~2 min). Demo sites include Rovo by default.
> - **I use an Atlassian site for work** → *technically possible, but strongly discouraged for AI apps. Let's use a demo site so your test Agent is completely isolated from real work data.*
>
> Reply with the URL, `provision` to spin up a demo site, or `work` if you want to talk through the work-site tradeoffs first."

**Important CLI fact (locked, do not re-verify):** the only Forge site subcommand is `forge site provision`. It's **idempotent** — if you already have an active demo site, it displays it; if not, it creates one. There is no `forge site list`. Only re-verify with the Forge MCP if `forge site provision` errors with an unknown-command message.

**Branch A — user provides a URL of a site they already have:**

Capture the URL as `<site-url>`. Say *"Got it — we'll install on `<site-url>` in Step 7."* If they're unsure whether Rovo is active on that site, tell them we can check by attempting the install in Step 7 (it will fail clearly if Rovo is not activated).

**Branch B — user wants us to check for / provision a demo site:**

Ask for permission, then run:

```bash
ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding forge site provision
```

Two possible outcomes:

- **User already has an active demo site** → the CLI prints its name, URL, status, expiry. Capture the URL as `<site-url>`. *"You already have an active demo site — `<site-url>`, valid until `<expiry>`. We'll use it."*
- **User doesn't have one** → CLI provisions a new one. Wait for it to finish (~2 min). Ctrl+C is safe — provisioning continues in the background, and re-running the command shows status.

Note aloud: *"Demo sites are yours for 90 days. Re-run `forge site provision` any time to see or renew yours. Rovo is enabled by default — perfect for what we're about to build."*

**Wrap up 4c:**

> "✅ Site locked in: `<site-url>` (Rovo activated). That's where Guru will live."

**Do not proceed to Step 5 until all three of `<working-dir>`, `<space-id>`, and `<site-url>` are captured.**

---

### Step 5 — Scaffold your Rovo Agent

We're going to scaffold a **stock, minimal, real, working Rovo Agent** — the "Hello World" from Atlassian's official Rovo Agent tutorial. We do *not* customize anything into Forge Guru yet. That comes later — first we ship the stock version end-to-end so the user sees a real deploy → install → chat pipeline work. Then we evolve it into Guru.

**User-facing title for this step: *"Scaffold your Rovo Agent"*** (not "Scaffold Forge Guru" — we're not making Guru yet).

We delegate the actual `forge create` invocation to the **`forge-app-builder` skill's helper** — it already knows the exact non-interactive incantation for a Rovo Agent template and side-steps the entire "which prompt do I answer with what?" problem. Our job in this step is to (a) call the helper, (b) verify the scaffold, and (c) narrate what happened.

**Why delegate:** `forge create` is interactive by default, and template/category names have shifted over the CLI's lifetime. The `forge-app-builder` skill maintains a Python helper (`scripts.create_forge_app`) that runs `forge create` non-interactively with a template flag, a name, a directory, and a Developer Space ID. Using it guarantees we never get stuck in the interactive picker.

**Dependency check — before running the helper, confirm `forge-app-builder` is installed.** Both skills ship together in the standard [`forge-skills` plugin bundle](https://github.com/atlassian/forge-skills), so if the user installed the bundle this check passes silently. If it fails (e.g. because only this skill was symlinked in), stop and tell the user: *"This onboarding skill relies on the `forge-app-builder` skill for the scaffold step. Both ship together in the `forge-skills` plugin bundle — please install the whole bundle rather than just this one skill, then we'll continue."* Do not attempt to hand-roll a `forge create` invocation as a workaround.

**Pre-execution readiness — everything the helper needs, gathered before we call it:**

| Input | Source | Value |
|---|---|---|
| Working directory (parent of `forge-guru/`) | Captured in Step 4a | `<working-dir>` |
| Developer Space ID | Captured in Step 4b | `<space-id>` |
| Dev site URL | Captured in Step 4c | `<site-url>` (needed later in Step 7 deploy) |
| App name | We provide | `forge-guru` |
| Template | We provide | `rovo-agent-rovo` |

If any of the above is missing, ask the user for it *before* invoking the helper — never invoke it and troubleshoot mid-flow.

---

**5a. Delegate the scaffold to `forge-app-builder`.**

**Narrate before invoking:**

> *"Now I'll call the `forge-app-builder` skill's helper to run `forge create` non-interactively. It'll do two things at once: **register a new app with Atlassian** (giving it a unique app ID in the [Developer Console](https://developer.atlassian.com/console/myapps)) and **drop a starter project** at `<working-dir>/forge-guru/`. The helper hides the interactive picker so we don't have to navigate CLI menus by hand. Once it finishes we'll customize the scaffold into Forge Guru."*

**📌 Pinned template name — `rovo-agent-rovo`.** This is the current name of the Rovo Agent template in the Forge CLI, per Atlassian's official *Build a Rovo Agent hello world app* tutorial. **Do not re-verify** and **do not substitute** any other name (older docs and older MCP results may still say `rovo-agent` — that's stale). Only reach for the Forge MCP to look up a different name if the helper *actually errors* with an unknown-template message on `rovo-agent-rovo`.

**Invoke the helper from the `forge-app-builder` skill directory** (adjust the path to your local plugin bundle):

```bash
cd <path-to>/skills/forge-app-builder
ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding python3 -m scripts.create_forge_app \
  --template rovo-agent-rovo \
  --name forge-guru \
  --dev-space-id <space-id> \
  --directory <working-dir>
```

**If the helper reports the `rovo-agent-rovo` template name is not valid** (rare, but possible if the CLI has renamed it again — the template was previously called `rovo-agent` and is currently `rovo-agent-rovo` per Atlassian's official *Build a Rovo Agent hello world app* tutorial), first run:

```bash
python3 -m scripts.list_templates --validate rovo-agent-rovo
```

If validation fails, invoke the Forge MCP (`search-forge-docs` for *"Build a Rovo Agent hello world app"*) to look up the current Rovo Agent template name, and re-run the create helper with the correct `--template` value. **Always land on a Rovo Agent template** — never a blank template or a UI Kit template.

**If the helper errors on the Developer Space** — for example if `<space-id>` was mistyped or the space was deleted — go back to 5a and re-pick.

**If the helper errors that Forge terms have not been accepted**, stop and hand the exact interactive `forge create` command to the user to run themselves. The onboarding skill never accepts Forge terms on the user's behalf.

---

**5b. Verify the scaffold looks right before proceeding.**

```bash
cd <working-dir>
ls forge-guru
```

Expect at minimum: `manifest.yml`, `package.json`, and an `src/` directory. Open `manifest.yml` and confirm it contains a `rovo:agent` module block.

**If any of that is missing** — the wrong template was scaffolded. Delete the `forge-guru/` directory and re-run 5b with the correct `--template` value.

---

**5c. Deliver the "here's what just happened" moment.** Short and specific — this is the "you own a real Atlassian app now" beat.

> **🎉 Scaffold complete — you now own a real Atlassian app.**
>
> - **Globally unique app ID.** The helper called `forge create`, which registered a new app in your Atlassian account under the Developer Space you picked. That app doesn't exist for anyone else in the world.
> - **Real, working Rovo Agent.** The scaffold isn't a placeholder — it's a fully functional Hello World Rovo Agent. We'll deploy it as-is in a moment.
> - **Tracked in the [Developer Console](https://developer.atlassian.com/console/myapps).** Your home base for every Forge app you'll ever own — installs, environments, promotions, audit logs all live there. Bookmark it.
>
> **Quick note on names before we move on** — worth understanding, because it's how Forge works:
>
> When you ran `forge create --name forge-guru`, three names got locked together to the same value in one shot:
>
> - The **folder on disk** — `forge-guru/`, the directory the scaffold just created inside your working directory.
> - The app's **ID** (in `manifest.yml`, near the top) — `forge-guru`, the app's permanent, immutable identity in the Developer Console. Never renamed, never re-generated.
> - Your Rovo Agent's **display name** (from the `name:` field inside `manifest.yml`'s `rovo:agent` block) — **Forge Guru**. This is what you'll type in the Rovo chat picker to find your agent.
>
> That's the last time the name changes. You're **Forge Guru** from this moment on — in Loop 1 when we deploy the stock Hello-World-shaped scaffold, *and* in Loop 2 when we customize what Guru actually does. The customize step later only changes Guru's **behavior** (its prompt, its action, its description) — not its name.
>
> **Next up:** read the two files the scaffold gave us together, so you understand every field before we deploy.

**Wrap up Step 5.** Advance to Step 6.

*(No `npm install` step here. `forge deploy` in Step 7 handles dependency installation automatically for the stock scaffold — no action needed. The first place we actively manage `package.json` is Step 9b, where we add `@forge/api` and then explicitly run `npm install` to sync `node_modules/` before Step 10's redeploy.)*

---

### Step 6 — Take a look at what the scaffold gave us

Before we ship or edit anything, help the user understand the two files the scaffold produced. Concepts live in chat; syntax lives in the actual files on disk — the agent points at them so the user can open them in their editor if they want to see the real code they now own. **The agent must not modify these files during Step 6.** The on-disk scaffold stays exactly as `forge create` produced it until Step 9.

**Thesis callback for this step** (weave into the intro naturally, don't say it as a separate sentence): *"What you're about to walk through **is** point #1 of the onboarding — the foundation. The manifest, the module, the backend function — the pieces every Forge app is made of — are on your disk right now, in a folder you can open."*

**Purpose (internal):** anchor the mental model in something concrete before Loop 2 asks the user to approve changes to it.

**User-facing title for this step: *"Take a look at what the scaffold gave us"*.**

**Shape:**
- **Two short messages, one per file.** First `manifest.yml`, then `src/index.js`. No confirm-gate — pure narration + questions welcome.
- **Concept summary in chat, not code.** 4–6 bullets per file describing *what the file is for*, *what blocks it contains*, and *how the pieces connect* — cross-referenced to the Step 3 mental model. **No code blocks in chat by default.**
- **Point at the file.** Every chat message closes with the exact path to the file on disk, framed as an optional "open it in your editor if you want to see the syntax." The file is unmodified `forge create` output — no annotations, no teaching comments, no rewrites.
- **Invite questions before advancing.** Give the user a clear reply prompt (see the response-formatting rules).

**Runtime instruction to the agent:**
- **Do read the stock files from disk** (`cat <working-dir>/forge-guru/manifest.yml`, `cat <working-dir>/forge-guru/src/index.js`) so the concept summary you write in chat accurately reflects what the current Rovo Agent template actually shipped. Shapes and field names vary slightly across template versions — always work from the real file, not from memory.
- **Do NOT write to the files.** No inline comments, no reformatting, no touching disk. The scaffold on disk between Step 6 and Step 10 must be byte-for-byte identical to what `forge create` produced — this keeps the Step 8 first-deploy predictable and gives the user a clean baseline to compare against when we customize into Guru.
- **In chat, send the concept summary** (4–6 bullets, no code block) + close with the file path so the curious user can open it themselves.

**Say something like — first message, file tree + `manifest.yml` concept summary:**

> **Take a look at what the scaffold gave us — 1/2: `manifest.yml`**
>
> Here's what `forge create` produced. Two files matter (plus `package.json`, which is standard Node):
>
> ```
> forge-guru/
> ├── manifest.yml       ← 🧭 THE MANIFEST (Step 3 concept #1)
> ├── package.json       ← Standard Node.js project — includes @forge/api
> └── src/
>     └── index.js       ← ⚙️ THE BACKEND (Step 3 concept #4)
> ```
>
> **`manifest.yml`** is the file that tells Atlassian what your app is, where it appears, and what it's allowed to do. In the stock scaffold, it contains:
>
> - **`modules.rovo:agent`** — the block that makes the app a Rovo Agent (Step 3 concept #2). Fields include `key` (internal ID), `name` (what Rovo shows the user), `description`, `prompt` (the agent's personality + instructions — this is literal prompt-engineering), `conversationStarters` (quick-tap prompts), and `actions` (what the agent can do).
> - **`modules.action`** — one entry per thing the agent can do (Step 3 concept #4). The stock scaffold declares a single `hello` action whose `description` tells the AI when to call it. `inputs` are the typed parameters the AI knows how to fill in.
> - **`modules.function`** — binds an action key to a real exported handler in the code. The `handler` value (`index.hello`) points at the export named `hello` in `src/index.js`.
> - **`app.id`** — your app's globally unique identity, created by `forge create`. Never edit it by hand.
> - **`app.runtime.name`** — the Node runtime Atlassian runs your backend on (`nodejs22.x`), matching the version we checked in Step 1 (local-machine setup).
> - **No permissions block yet** — the stock agent doesn't call any APIs or external URLs, so it doesn't need any. Loop 2 will add one when we teach Guru to fetch from `developer.atlassian.com`.
>
> **📖 Want to see the exact syntax?** The file lives at `<working-dir>/forge-guru/manifest.yml` — open it in your editor. It's unchanged from what `forge create` produced, so what you see is a real, minimal, deployable Rovo Agent manifest.
>
> **Anything in there you'd like me to unpack before we look at `src/index.js`?**

**Answer any questions on the manifest.** When the user is ready, send a second message walking through `src/index.js` the same way:

> **Take a look at what the scaffold gave us — 2/2: `src/index.js`**
>
> **`src/index.js`** is the backend — the code Atlassian actually runs on its servers when the agent invokes its action (Step 3 concept #4). In the stock scaffold, it contains:
>
> - **One exported handler** (`hello`) — this is the function `manifest.yml` points at via `handler: index.hello`. The exported symbol name must exactly match the manifest's `handler` value, or Forge can't find your code.
> - **A `payload` argument** — what the Rovo Agent passes in when it invokes the action. Contains any `inputs` the agent filled in from the user's message. The stock scaffold doesn't declare any inputs, so payload is essentially empty here.
> - **A return value** — whatever the handler returns goes back to the agent, which uses it to compose a reply. Forge serializes what you return; strings and plain objects both work.
> - **No imports, no permissions, no network calls, no external SDKs.** The stock scaffold is deliberately minimal — everything it needs to be a real, working Rovo Agent is right there.
>
> **📖 Want to see the exact syntax?** The file lives at `<working-dir>/forge-guru/src/index.js` — open it in your editor. It's unchanged from what `forge create` produced.
>
> **That's the whole Rovo Agent.** Two files. Under 50 lines of code between them. And it's ready to deploy right now.
>
> **Any questions on how the pieces connect?** Otherwise, next up: we ship it. First deploy of your Forge career.

**Do not advance to Step 8 until the user has seen both concept summaries and had a chance to ask questions.** Answer generously — this is the "understand the app before you run it" beat.

---

### Step 7 — Deploy your first Forge app

Ship the stock Hello World agent. This is the user's first-ever Forge deploy — the confidence beat depends on it landing cleanly. **Two plain CLI commands, invoked directly.** No helper, no wrapper — the commands are simple and self-explanatory.

**User-facing title for this step: *"Your first Forge app is Deployed and Installed to your <site-url>"*.**

Before running anything, say this out loud:

> "Two commands, done one at a time:
>
> - **`forge deploy`** publishes your code to Atlassian's servers under your app ID. Think of it as 'save to the cloud.' It doesn't affect any site or any user yet.
> - **`forge install`** attaches your deployed app to a specific site. This is what actually makes the agent appear in Rovo on that site.
>
> You'll deploy many times per day while iterating; you install once per site. This is the daily rhythm of every Forge developer."

Also introduce **environments** briefly:

> "Forge apps have three environments: `development`, `staging`, and `production`. Everything we do today lives in `development` — private, safe, breakable. When you eventually have real users, `production` is a separate, deliberate promotion step. Forge is never 'auto-deploy to prod.'"

**No standalone `forge lint`.** `forge deploy` runs the equivalent validation server-side, and the stock scaffold is guaranteed to pass — we haven't touched it.

---

**7a. Confirm the deploy + install plan with the user.**
>
> Now it's time to get your app from your disk onto Atlassian's servers and into Rovo on your dev site. Here's the plan:
>
> - Run **`forge deploy`** — upload the stock scaffold to Atlassian's servers in the `development` environment. No site is affected yet.
> - Run **`forge install`** — attach the deployed app to your dev site: **`<site-url>`** (product: `jira`, environment: `development`). This is what makes the agent appear in Rovo on that site.
>
> The stock scaffold declares no permissions, so no install-time permission prompt should appear. If the CLI ever pauses on a Forge-terms prompt I'll stop and hand it to you — I don't accept Forge terms on your behalf.
>
> **Ready?** (**yes / go / sure / y / ok**)

**Wait for an affirmative.** Answer any last questions.

---

**7b. Run `forge deploy`, then `forge install`.**

Two commands, run in sequence from the app directory. Use the app directory from Step 6 (the scaffold) and the site URL captured in Step 4c.

```bash
cd <working-dir>/forge-guru
ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding forge deploy --non-interactive
ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding forge install --non-interactive --site <site-url> --product jira -e development
```

**Loop 1 install has no `--upgrade` or `--confirm-scopes` flags** — this is a first-time install of an app that declares no permissions, so there's nothing to upgrade from and no scopes to confirm. Loop 2 (Step 10) adds those flags because Guru introduces a new external-fetch permission.

Run each command via your shell tool, wait for it to complete, then run the next.

**Success signals:**
- `forge deploy` prints `Deployed to development` and exits 0.
- `forge install` prints `Installed on <site-url>` and exits 0.

Move on to Step 7c once both have exited cleanly.

---

**7c. Celebrate the first win. Do not skip this.**

> 🎉 **Congrats — you just deployed and installed your first Forge app.**
>
> - **Deployed** to the `development` environment on Atlassian's infrastructure. No server to run — Atlassian hosts the whole thing.
> - **Installed** on your dev site (`<site-url>`).
> - Your stock Hello World Rovo Agent is live and reachable in Rovo *right now*.
>
> Every Forge developer's daily rhythm looks like this: edit → deploy → see it live. You just did it end-to-end. Let's go see it.

**Common failure modes:**

- **Forge terms not accepted** → `forge deploy` stops. Do not accept on the user's behalf. Tell the user: *"Those terms cover what your app is allowed to do with data on the site — reading them yourself is a habit worth keeping. Run `forge deploy` interactively once, accept the terms, then I'll re-run the deploy."*
- **Rovo not activated on the site** → *"Rovo isn't activated on this site. If we provisioned a demo site in Step 4c this shouldn't happen — but if you brought your own site, we may need a different one. Want me to run `forge site provision` for a demo site instead?"*
- **`forge install` reports *"app is already installed"*** → the install actually already succeeded on a previous run and the current attempt is a duplicate. That's the successful outcome — move on to Step 7d to confirm with `forge install list --json`.
- **Any other error** → surface verbatim and consider routing to `forge-debugger`.

---

**7d. Confirm the install (read-only diagnostic).**

`forge install list` is read-only — not app mutation — so this skill invokes it directly to confirm the install landed:

```bash
ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding forge install list --json
```

Parse the JSON. Confirm the app is installed on the right site under the `development` environment.

---

### Step 8 — See Hello World live on your dev site

Walk the user into Rovo and get them to chat with the stock agent. **This is the first confidence beat — do not skip it and do not rush it.** Even though the Hello World agent barely does anything, the user *seeing their own code respond in Rovo* is the moment Forge becomes real.

**User-facing title for this step: *"See Hello World live on your dev site"*.**

**Say something like:**

> 🎉 **Your Hello World Rovo Agent is live. Let's go see it.**
>
> 1. **Open your dev site:** [https://\<your-site\>.atlassian.net](https://<your-site>.atlassian.net) — use the exact URL from Step 4c.
> 2. **Find Rovo.** Rovo appears as a chat surface in Jira and Confluence — typically accessible from the top-right of the Atlassian navigation, or via a "Chat with Rovo" button. On demo sites Rovo is pre-activated.
>    - If you don't see it, look for the Rovo icon in the top nav, or use the site's search bar and type "Rovo".
> 3. **Find your agent.** Rovo shows a list of available Agents — yours will appear with the name from the stock scaffold (typically something like *"Hello World Agent"* or the app name we passed to `forge create`).
>    - Agents typically take up to ~60 seconds after install to appear. If you don't see it immediately, hard-refresh (⌘⇧R / Ctrl+Shift+R).
> 4. **Open a chat with it.** Try the conversation starters from the manifest, or type any message.
> 5. **Watch it respond.** The reply will be short and hello-world-y — that's expected. The point isn't the answer; the point is that **your code, on Atlassian's servers, just handled a real chat message from Rovo.**
>
> **To confirm the backend actually ran**, come back to your terminal and run:
>
> ```bash
> ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding forge logs
> ```
>
> You should see the request from your handler. That's the full loop end-to-end: **you chatted → Rovo picked the action → Forge ran your function on Atlassian's servers → the reply came back.**
>
> **Not seeing your agent, or it's not responding?**
> - Hard-refresh (⌘⇧R / Ctrl+Shift+R).
> - Wait up to 60 seconds for install propagation.
> - Confirm the install landed: `forge install list`.
> - Confirm Rovo is activated on this site (demo sites have it by default).
> - If it's still stuck, ask me to load the `forge-debugger` skill.

**Ask the user to confirm they saw the agent respond before advancing.**

**Once they confirm — walk them through what just happened server-side.** Concepts land better right after you've watched them happen, and this is that moment. Use language along these lines:

> **What just happened, step by step.**
>
> You typed a message and got a reply. Here's the actual server-side loop those seven seconds walked through — this is how *every* Rovo Agent works:
>
> 1. **You typed a message** into the Rovo chat panel on your dev site.
> 2. **Rovo read your app's `manifest.yml`** to see which Agent was being addressed and what actions it had available.
> 3. **The Agent's `prompt` decided what to do** — its personality and instructions steered it toward calling one of its declared actions.
> 4. **The Agent invoked an action** by name, passing along the input arguments it inferred from your message.
> 5. **Forge ran your backend function** — the code in `src/index.js` — on Atlassian's servers, with only the permissions your manifest declared.
> 6. **The function returned data back to the Agent**, which composed a reply and streamed it back to you in chat.
>
> That's the full loop. Every other kind of Forge app follows the same shape: your **manifest** declares one or more **modules** that hook into Atlassian, and each module points at **backend** code that runs on Atlassian's servers with the permissions you declared. Bigger, more capable apps just declare more modules, more actions, more permissions, and pull in more context. The three building blocks don't change.

**Then transition to Step 9:**

> **🎉 You just shipped and used your first Forge app — and you just watched the three building blocks come together end-to-end. Now the fun part: let's turn this Hello World into something you'll actually want to keep.**

**Do not advance to Step 9 until the user confirms they saw the Hello World agent respond in Rovo.**

---

### Step 9 — Turn Hello World into Forge Guru

Now we evolve the stock Hello World agent into **Forge Guru** — a real, useful, keep-forever companion. Two files change, one at a time, each behind its own confirm-gate. The user already understands what these files contain (from the concept summaries in Step 6), so these gates focus on **what's changing and why** — a compact change-list, no full target-file paste by default.

**User-facing title for this step: *"Turn Hello World into Forge Guru"*.**

**Shape of each confirm-gate:**
- **One file per gate.** Manifest first, then `src/index.js`. Don't combine them.
- **Chat message = compact change list only.** Bulleted "what's changing and why" cross-referenced to Step 3 concepts. **No target-file paste in chat by default.** The teaching concepts already landed in Step 6 — this step is about the specific diff.
- **Escape hatch:** *"I can show you the exact final file before I write it if you want — just say 'show me the file'. Otherwise, say the word (yes / go / sure / y / ok) and I'll apply it."*
- **Invite questions.** Advancing without the user understanding is a bug, not a feature. Answer anything they raise before re-offering the gate.
- **Wait for an explicit affirmative** (yes / go / sure / y / ok / or any clear variant) before writing to disk.
- **When writing to disk:** replace the file with **clean, production-shaped Guru code** — a short header comment (`// Forge Guru — generated during forge-onboarding` + 1-line description), then the code. The Step-7 teaching comments were their job in Loop 1; Loop 2 code looks like a real Forge app. **The full target file bodies are pinned in the "Reference — target file bodies" section below** for the agent to use as the exact write payload.

---

**9a. Customize `manifest.yml` — a per-file confirm-gate.**

**Say something like:**

> **Turn Hello World into Forge Guru · file 1 of 2 — `manifest.yml`**
>
> Remember the stock `manifest.yml` we walked through in Step 6? Here's what's changing to turn it into Forge Guru:
>
> - **New `description`** on the `rovo:agent` module — tells Rovo (and future-you) what Guru is *for*, distinct from what Guru is *called*. The `key` and `name` were locked to `forge-guru` / `Forge Guru` when we ran `forge create` — those don't change in Loop 2. *Concept: the `rovo:agent` module (Step 3 #2).*
> - **Prompt replaced** — new instructions that make Guru trustworthy: search the docs, explain plainly, **always cite the doc URL**, never invent APIs. *Prompt-engineering — the difference between a helpful agent and a confident-sounding hallucinator lives here.*
> - **`conversationStarters` added** — five real Forge questions Rovo will offer as quick-tap prompts so a first-time user knows where to start.
> - **Action swapped** — the stock `hello` action is replaced with a new `search-forge-docs` action wired to a `searchForgeDocs` function. Its `description` is what the AI reads to decide *when* to call it. *Concept: Backend, wrapped for AI (Step 3 #4).*
> - **New `permissions.external.fetch.backend` block** with `https://developer.atlassian.com` — Forge's outbound-network permission system. This is the *only* URL Guru is allowed to call on the internet; anything else Forge blocks at the sandbox boundary. *Least-privilege applies to network egress, not just Atlassian scopes.*
> - **`app.id` and `app.runtime` preserved** — never touched. `app.id` is your app's identity.
>
> **📖 Want to see the exact final file before I write it?** Just say *"show me the file"* and I'll paste the full YAML. Otherwise say the word (**yes / go / sure / y / ok**) and I'll apply it.

**If the user says "show me the file"** (or equivalent), paste the pinned target-file YAML from the *"Reference — target file bodies"* section below (9-ref), then re-offer the gate.

**Wait for an explicit affirmative before writing to disk.** Treat questions as first-class — answer them, then re-offer the gate. Do not short-circuit the gate by writing the file and *then* explaining.

**When the user confirms**, replace `manifest.yml` with the pinned target-file YAML (see 9-ref below) — **preserving the real `app.id` value from the stock file** (do *not* overwrite it with the placeholder text).

**After writing:**

> ✅ `manifest.yml` updated. Agent is now Forge Guru, prompt + conversation starters set, `search-forge-docs` action + function declared, egress permission for `https://developer.atlassian.com` added, `app.id` preserved. One file left.

**Sanity-check what you wrote** before advancing — the file must parse as valid YAML, `app.id` must still be the value `forge create` produced (do not overwrite it with the placeholder), and every `handler`/`function` name must match across the `action`, `function`, and (about-to-be-written) `src/index.js` boundaries. If any of that is off, fix it *before* advancing.

---

**9b. Customize `src/index.js` — a per-file confirm-gate (with an inline `package.json` update).**

**Say something like:**

> **Turn Hello World into Forge Guru · file 2 of 2 — `src/index.js`**
>
> The manifest is Guru's. Now the backend code the new `search-forge-docs` action points at. Here's what's changing from the stock hello-world handler:
>
> - **New import: `import api from '@forge/api'`** — the Forge SDK's egress-controlled fetch. It only works because the manifest declares `https://developer.atlassian.com` in `permissions.external.fetch.backend`. Manifest permission + SDK call are two halves of the same coin.
> - **Handler swapped** — the stock `hello` handler is replaced with `searchForgeDocs(payload)`. The manifest's `function.handler` (`index.searchForgeDocs`) points at this exact exported symbol. Reads `payload.query`, calls the Atlassian docs-search endpoint, returns the top 3 results as a structured object.
> - **Empty-query guard** — if the agent invokes us with no query, return a friendly note instead of hitting the network.
> - **Error handling** — non-200 responses, thrown exceptions, and zero-result payloads all funnel into a `fallback` helper so Guru is never useless.
> - **New `fallback(query, note)` helper** — returns three curated top-level Forge doc links (platform overview, manifest reference, CLI reference) so Guru always answers with *something* useful, even if the search endpoint changes shape.
> - **Return shape** — a plain object (`{ query, results }`), not a string. The agent uses the `title`/`url`/`snippet` fields to compose a cited reply.
>
> **📦 One small side-effect: I'll also add `@forge/api` to `package.json`.** The new handler imports `@forge/api`, and the stock scaffold's `package.json` may not list it as a dependency yet. Without this, `forge deploy` in the next step will fail with a `Cannot find module '@forge/api'` error at runtime. I'll add the current version of `@forge/api` to your `dependencies` block as part of applying this file — no separate approval needed, it's just what has to happen for the new code to work. You'll see the extra line in `package.json` if you open it after.
>
> **📖 Want to see the exact final file before I write it?** Just say *"show me the file"* and I'll paste the full JavaScript. Otherwise say the word (**yes / go / sure / y / ok**) and I'll apply it — file + dependency together.

**If the user says "show me the file"** (or equivalent), paste the pinned target-file JavaScript from the *"Reference — target file bodies"* section below (9-ref), then re-offer the gate. If they specifically want to see the `package.json` change too, tell them it's a one-line add under `dependencies` — e.g. `"@forge/api": "^X.Y.Z"` at the current published major — and then re-offer.

**Wait for an explicit affirmative before writing to disk.** Answer any questions first — the whole point of this gate is that the user leaves understanding *why* the code looks the way it does.

**When the user confirms**, do ALL THREE actions as one atomic step:

1. **Replace `src/index.js`** with the pinned target-file JavaScript (see 9-ref below).
2. **Update `package.json`** — read the existing file (do not overwrite it), parse the JSON, ensure `dependencies["@forge/api"]` is present. If it's already there, leave the version untouched. If it's missing, add it at the latest published major (get the current version with `npm view @forge/api version` if unsure, or use the same version the `forge-app-builder` scaffold ships in newer templates). Preserve all other fields in `package.json` exactly as they are — `name`, `version`, `main`, `scripts`, `license`, existing dependencies, etc. Do not reformat or reorder.
3. **Run `npm install`** from the app directory to sync `node_modules/` with the newly-declared `@forge/api` dependency. Editing `package.json` only records the intent — Node still has to actually download the package into `node_modules/` before Forge can bundle it. Without this, Step 10's `forge deploy` will fail with `Cannot find module '@forge/api'`.

```bash
cd <working-dir>/forge-guru
npm install
```

Wait for `npm install` to complete before advancing.

**After all three actions:**

> ✅ `src/index.js` replaced. `searchForgeDocs` handler wired to the manifest, egress-controlled `api.fetch` in place, empty-query / HTTP-error / zero-result paths all route through `fallback`, three curated Forge doc links as the safety net.
>
> ✅ `package.json` updated with `@forge/api` in `dependencies`.
>
> ✅ `npm install` complete — `@forge/api` is now in `node_modules/` and ready for Step 10's redeploy. **Quick teaching moment: `package.json` records *what* dependencies your app needs; `node_modules/` is where they actually live on disk. Editing `package.json` doesn't touch `node_modules/` — you have to run `npm install` to sync them. That's why we ran it right after adding `@forge/api`.**

**Sanity-check what you wrote** before advancing:
- The exported symbol name in `src/index.js` must match the manifest's `handler: index.searchForgeDocs`.
- The `import` line must be at the top of the file, and there must be no leftover scaffold code from the hello-world handler.
- `package.json` must still parse as valid JSON — a broken `package.json` breaks the deploy. If your write may have introduced a trailing-comma or bracket-mismatch, re-read and re-parse before advancing.
- `package.json.dependencies["@forge/api"]` must be present.

If any of that is off, fix it before advancing.

---

**9-ref. Reference — target file bodies (write these to disk on confirm; only paste in chat if the user asks "show me the file").**

**Target `manifest.yml`:**

Every source line below is ≤160 characters and every field value fits Forge's manifest-field length limits. Do not lengthen any line, string block, or field value when writing this file to disk — `forge lint` runs during `forge deploy` (Step 11) and will fail the deploy if you exceed those limits.

```yaml
# Forge Guru — generated during forge-onboarding.
# A Rovo Agent that answers Forge questions
# by searching Atlassian's official developer docs.
modules:
  # 📌 LINT NOTE — every string value below has been kept ≤255 chars after YAML block-scalar
  # folding. If you edit `description`, `prompt`, or any other string, recompute the joined length
  # (fold >- with single spaces, preserve newlines in |) and stay under 255 chars each. See
  # invariant #13 in this skill for the full rule.
  rovo:agent:
    - key: forge-guru
      name: Forge Guru
      description: Your Forge companion — answers Forge questions from the official docs.
      prompt: |
        You are Forge Guru. Answer Forge questions.
        For every question:
        1. Call search-forge-docs first.
        2. Answer plainly and cite the doc URL.
        3. Never invent APIs or CLI commands.
        If search finds nothing, say so.
      conversationStarters:
        - What can I build with Forge?
        - Which Forge module should I use for my idea?
        - How do I add something to a Jira issue?
        - How do I call the Jira REST API from Forge?
        - Difference between UI Kit and Custom UI?
      actions:
        - search-forge-docs
  action:
    - key: search-forge-docs
      function: searchForgeDocs
      actionVerb: GET
      description: Searches the official Forge docs and returns top matching pages with URLs.
      inputs:
        query:
          title: Search query
          type: string
          required: true
          description: The user's Forge question or key search phrases.
  function:
    - key: searchForgeDocs
      handler: index.searchForgeDocs
permissions:
  external:
    fetch:
      backend:
        - 'https://developer.atlassian.com'
app:
  runtime:
    name: nodejs22.x
  # Preserve the app.id value from the stock scaffold.
  # Do not overwrite it with placeholder text.
  id: <your app id here>
```

**Target `src/index.js`:**

```javascript
// Forge Guru — generated during forge-onboarding.
// Backend for the `search-forge-docs` Rovo Agent action. Fetches from
// Atlassian's official developer docs and returns the top 3 results.
import api from '@forge/api';

export async function searchForgeDocs(payload) {
  const query = (payload && payload.query) || '';
  if (!query.trim()) {
    return {
      results: [],
      note: 'No query provided. Ask a specific Forge question.'
    };
  }

  const url =
    'https://developer.atlassian.com/gateway/api/search/?' +
    `q=${encodeURIComponent(query)}&site=developer`;

  try {
    const response = await api.fetch(url);
    if (!response.ok) {
      return fallback(query, `Search returned HTTP ${response.status}.`);
    }
    const data = await response.json();
    const raw = Array.isArray(data.results) ? data.results : [];
    const results = raw.slice(0, 3).map((r) => ({
      title: r.title || r.name || 'Untitled',
      url: r.url || r.link || '',
      snippet: r.snippet || r.description || ''
    }));

    if (results.length === 0) {
      return fallback(query, 'No matching docs found.');
    }
    return { query, results };
  } catch (err) {
    console.error('search-forge-docs failed:', err);
    return fallback(query, `Search errored: ${err.message}`);
  }
}

function fallback(query, note) {
  return {
    query,
    note,
    results: [
      {
        title: 'Forge documentation (home)',
        url: 'https://developer.atlassian.com/platform/forge/',
        snippet:
          'Start here for the full Forge platform documentation.'
      },
      {
        title: 'Forge manifest reference',
        url: 'https://developer.atlassian.com/platform/forge/manifest-reference/',
        snippet:
          'Every module, permission, and manifest property.'
      },
      {
        title: 'Forge CLI reference',
        url: 'https://developer.atlassian.com/platform/forge/cli-reference/',
        snippet: 'All Forge CLI commands and flags.'
      }
    ]
  };
}
```

---

### Step 10 — Redeploy — this time as Forge Guru

Same helper, second time. This is the daily-rhythm beat — the user sees that iterating on a Forge app is just *edit → redeploy → see it live*. No new concepts, just muscle memory.

**User-facing title for this step: *"Redeploy — this time as Forge Guru"*.**

**Say something like:**

> **Redeploy — this time as Forge Guru · plan**
>
> Same two commands as Step 7 (`forge deploy` then `forge install`), same site, same environment (`development`), same app ID. This time they'll ship the Forge Guru version of the manifest + code.
>
> **Differences from Loop 1:** `forge deploy` gets a `--approve` flag, and `forge install` gets `--upgrade --confirm-scopes`.
>
> - `forge deploy --approve MAJOR_VERSION_RULE` — acknowledges the major-version bump on the deploy side. Forge stamps the new scope on the deploy artifact itself, so `forge deploy` pauses on the major-version rule unless we pre-approve it. This flag is what keeps the deploy running non-interactively.
> - `forge install --upgrade` — tells install to update the existing installation (which was placed in Step 7) rather than expecting a fresh one.
> - `forge install --confirm-scopes` — pre-approves the new scope (`developer.atlassian.com` in `permissions.external.fetch.backend`) so the install goes through non-interactively.
>
> This is a real Forge platform pattern — you'll add these flags every time you redeploy an app whose scopes or permissions changed. Loop 1 didn't need them because there was no prior install to upgrade from and no scopes.
>
> **Ready?** (**yes / go / sure / y / ok**)

**Wait for an affirmative.** Then run the two commands in sequence from the app directory:

```bash
cd <working-dir>/forge-guru
ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding forge deploy --non-interactive --approve MAJOR_VERSION_RULE
ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding forge install --non-interactive --upgrade --confirm-scopes --site <site-url> --product jira -e development
```

**Success signals:**
- `forge deploy` prints `Deployed to development` and exits 0.
- `forge install` prints `Installed on <site-url>` and exits 0 (may also print a scope-acknowledgment line).

On success:

> ✅ **Guru is deployed and installed.** Same environment, same site — the app ID hasn't changed, but the agent is now Forge Guru with the new prompt, the new action, and the egress permission for `developer.atlassian.com`.

**Common failure modes** — same as Step 7 (Forge terms, Rovo not activated, other). Manifest-validation errors are the one to watch for here since we just edited the file — surface the CLI output verbatim and route back to Step 9a to fix the specific field.

---

---

### Step 11 — See Forge Guru live

Walk the user into Rovo on their dev site, help them find Guru, and get them to ask a real Forge question. The deploy isn't the win — using Guru is. Do not assume the user knows their way around Rovo; walk them there step by step.

> 🎉 **Forge Guru is live on your dev site. Let's go meet it.**
>
> 1. **Open your dev site in a browser:** `https://<your-site>.atlassian.net`
> 2. **Find Rovo.** Rovo appears as a chat surface in Jira and Confluence — typically accessible from the top-right of the Atlassian navigation, or via a "Chat with Rovo" button. On demo sites Rovo is pre-activated.
>    - If you don't see it right away, look for the Rovo icon in the top navigation, or use the search bar and type "Rovo".
> 3. **Find Forge Guru.** Rovo shows a list of available Agents — yours will appear with the name **Forge Guru** and the description you set in the manifest.
>    - Agents typically take up to ~60 seconds after install to appear. If you don't see it immediately, hard-refresh (⌘⇧R / Ctrl+Shift+R).
> 4. **Open a chat with Guru.** You should see the conversation starters we defined in the manifest — *"What can I build with Forge?"*, *"Which Forge module should I use for my idea?"*, *"How do I add something to a Jira issue?"*, etc.
> 5. **Try a conversation starter, or type your own question.** Good first questions to try:
>    - *"How do I add something to a Jira issue?"*
>    - *"Which Forge module should I use to build a Confluence macro?"*
>    - *"How do I call the Jira REST API from a Forge resolver?"*
> 6. **Watch Guru respond.** Guru should call the `search-forge-docs` action, fetch real documentation from `developer.atlassian.com`, and reply in the chat with a plain-language explanation plus a link to the official doc it found. That link is your proof that the answer came from real Atlassian docs — not from the model guessing.
>
> **Not seeing Guru at all in the Rovo Agent picker?**
> - Hard-refresh the page (⌘⇧R / Ctrl+Shift+R).
> - Wait up to 60 seconds for install propagation.
> - Confirm the install landed: `forge install list`.
> - Confirm Rovo is activated on this site (demo sites have it by default).
> - If it's still stuck, ask me to load the `forge-debugger` skill.

**Once the user has chatted with Guru, ask them the honest evaluation question.** This is the real success signal for a Rovo Agent — the *quality* of the response, not the fact that it responded. Only the user can judge that.

**Thesis callback for this step** (weave into the celebration, don't say it as a separate sentence): *"That was all three points of the onboarding at once — the foundation (#1: manifest, module, function, permissions), running against the wider Atlassian platform (#2: Rovo, external APIs), doing something you'd actually use (#3: your keep-forever Forge companion)."*

> **How did that feel?**
>
> - Did Guru actually answer your question — usefully, with a link to a real Atlassian doc?
> - Or was the answer thin, off-target, missing a citation, or did Guru just say *"I don't know"*?
>
> Reply with **useful** if Guru nailed it, **meh** if it worked but you wish it did something differently, or **broken** if it didn't respond well (empty answer, error, generic fallback).

**Branch on the user's answer — three paths:**

**Path A — user says "useful" (or any positive signal like `great`, `yes`, `it worked`):**

Celebrate. This is the real moment they became a Forge AI developer *and* the moment they gained a permanent Forge companion.

> 🎉 **You built a working Rovo Agent that actually helps.** That's the AI-native loop end-to-end: **you chatted with Guru → Rovo picked the `search-forge-docs` action → Forge ran your function on Atlassian's servers → your function fetched from developer.atlassian.com (allowed because of the egress permission you declared) → the results came back → the Agent composed a cited answer for you.**
>
> **Guru is yours now — forever.** Every time you come back to your dev site, Guru will be in Rovo, ready to help. Ask it anything about Forge as you keep building. It's not a demo — it's your Forge companion. Bookmark your dev site and come back often.

Advance to Step 12.

**Path B — user says "meh" (or "okay but", "I wish it", "it works but…"):**

Great — this is the actual iteration muscle you'll use every day building AI agents. Give a **small nudge**, not a full walkthrough:

> Guru's behavior lives in the **`prompt:`** field of its `rovo:agent` module in `manifest.yml` — that's the main lever. Edit that prompt (make it more opinionated, add a rule like *"always answer in three bullets"*, or restrict what it should refuse to answer), then re-run the same deploy command from Step 10. Guru updates on the next deploy.
>
> **One helpful thing to know:** editing *just* the prompt is **not** a major version bump — that guardrail only fires when you add/remove permissions, modules, or scopes. So a prompt-only redeploy will just work, no `--upgrade` needed. Fastest iteration loop in Forge.
>
> Come back to this whenever — no need to do it now unless you want to. Ready to keep going?

Wait for confirmation, then advance to Step 12.

**Path C — user says "broken" (or "error", "empty", "didn't respond", "I don't know"):**

*Now* introduce `forge logs` — as the debugging tool, not the success signal.

> Let's look at what happened server-side. `forge logs` shows anything your function printed or any errors it threw. When Guru is working, `forge logs` is usually quiet — no news is good news. When it's not working, this is where the story is.
>
> ```bash
> ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-onboarding forge logs
> ```
>
> **Common shapes of what you'll see:**
> - **`fetch is not defined` / permission error** → the manifest is missing `permissions.external.fetch.backend` for `developer.atlassian.com`. Go back to `manifest.yml`, confirm the permission is there, redeploy.
> - **HTTP 4xx/5xx from `developer.atlassian.com`** → the docs-search endpoint may have changed shape. Guru's `fallback` helper should have kicked in and returned the three curated doc links — verify Guru at least gave you *something*.
> - **No logs at all** → the function never ran. That usually means the action definition is off — check `manifest.yml`'s `action` module has `function: searchForgeDocs` and the function module's `handler: index.searchForgeDocs` matches the exported symbol in `src/index.js`.
> - **`Cannot find module '@forge/api'`** → either `package.json` didn't get updated OR `npm install` didn't run after the update. Go back to Step 9b, confirm `package.json` includes `@forge/api` in `dependencies`, run `npm install` in the app directory, then redeploy.
>
> Once you know what happened, fix it and redeploy (same command from Step 10). If you're stuck, ask me to load the `forge-debugger` skill — it's built for exactly this kind of investigation.

Wait for the user to confirm they've resolved the issue (or explicitly want to skip and continue), then advance to Step 12.

**Reply hint for the honest-eval question above:** *"Reply with **useful** / **meh** / **broken** — or describe what you actually saw and I'll figure out which path we're on."*

**Bookmarks for the road** (regardless of which path they took):
- **Your dev site:** `https://<your-site>.atlassian.net` — where Guru lives.
- **Developer Console:** https://developer.atlassian.com/console/myapps — manage all your Forge apps.
- **Rovo Agent docs:** https://developer.atlassian.com/platform/forge/manifest-reference/modules/rovo-agent/
- **Forge docs:** https://developer.atlassian.com/platform/forge/
- **Atlassian Developer Community:** https://community.developer.atlassian.com/

---

### Step 12 — What next

Hand the user a map for the rest of their Forge journey, framed around Atlassian's official [*Build and launch your Forge app*](https://developer.atlassian.com/platform/forge/build-and-launch-your-forge-app/) doc. This onboarding is the guided walkthrough of stage 1 (**Build**); that doc is the map for stages 2–4.

Structure of this final message: **graduation framing → Get inspired → the four stages (Build / Prepare to publish / Distribute / Grow) → Guru CTA.**

**User-facing title for this step: *"What next — the rest of your Forge journey"*.**

**Say something like:**

> 🚀 **You've just completed the guided *Build* stage of your Forge journey.**
>
> You now know the foundation (point #1) and you've seen how Forge connects into the wider Atlassian platform (point #2) — plus you've got the real, working app to prove it (point #3). Everything you did today — pre-flight, scaffold, deploy, install, customize, redeploy — maps to stage 1 of Atlassian's official [Build and launch your Forge app](https://developer.atlassian.com/platform/forge/build-and-launch-your-forge-app/) doc. That doc is your map for the whole journey. Here's what the rest of it looks like, plus what to explore first.
>
> ### Get inspired — see what other Forge apps look like
>
> Before you decide what to build next, take 10 minutes and look at some real Forge apps other developers have built and open-sourced. All three are on [atlassian-labs/forge-inspired](https://github.com/atlassian-labs/forge-inspired) — clone them, run them on your dev site, or just read the code to see how the three building blocks you now know (manifest, module, backend function) show up in more ambitious apps.
>
> - **[Sprint Ready Agent](https://github.com/atlassian-labs/forge-inspired/tree/main/sprint-ready-agent)** — turns a rough Jira issue into a clearer, sprint-ready ticket with useful context, acceptance criteria, and open questions. A more ambitious Rovo Agent than Guru.
> - **[Smart Workflow Follow-up](https://github.com/atlassian-labs/forge-inspired/tree/main/smart-workflow-followup)** — posts a personalized follow-up message whenever a Jira issue reaches a chosen status. A great example of Jira product event handlers.
> - **[Team Pulse Board](https://github.com/atlassian-labs/forge-inspired/tree/main/team-pulse-board)** — surfaces contributors, related Jira work, and recent activity on a Confluence page. A great example of a UI Kit app that reads across Atlassian products via the product APIs.
>
> Poke around, and when something clicks — *"oh, I want to build something like that"* — come back to your dev site and just tell Rovo Dev what you want.
>
> ### 1. Build — you're here 🎯
>
> You've shipped Guru end to end. When you want to build *another* app, you don't have to re-run this onboarding — you can invoke the specialist skills directly.
>
> - **`forge-app-builder`** — scaffold + deploy new apps (any template, any module, any product).
> - **`forge-connector`** — build a Teamwork Graph connector to ingest external data.
> - **`forge-debugger`** — broken deploy, blank UI, unexpected error, tunneling questions.
>
> ### 2. Prepare to publish
>
> Before you share an app with real users, run it through the *[Prepare to publish](https://developer.atlassian.com/platform/forge/build-and-launch-your-forge-app/#prepare-to-publish)* stage — iterate with Forge Tunnel, review your scopes and data handling, watch app behavior via logs and metrics, and debug performance.
>
> - **`forge-security-review`** — audit scopes, permissions, egress, and Rovo Agent AUP compliance.
> - **`forge-app-review`** — pre-release review of a real app end-to-end.
> - **`forge-cost-optimizer`** — Forge's free tier is generous, but knowing what costs money is worth 10 minutes.
>
> ### 3. Distribute
>
> When your app is ready for users, [pick a distribution path](https://developer.atlassian.com/platform/forge/build-and-launch-your-forge-app/#distribute):
>
> - **Share internally** with your organization for internal workflows, feedback, or a controlled rollout — see [Distribute your apps](https://developer.atlassian.com/platform/forge/distribute-your-apps/).
> - **Publish on Marketplace** to reach customers worldwide and unlock revenue — see the [Marketplace publishing guide](https://developer.atlassian.com/platform/marketplace/listing-forge-apps/).
>
> ### 4. Grow
>
> [Keep iterating](https://developer.atlassian.com/platform/forge/build-and-launch-your-forge-app/#grow) — refine the experience, add AI capabilities where they help, and stay connected to the community.
>
> - Browse the [Rovo modules](https://developer.atlassian.com/platform/forge/manifest-reference/modules/rovo-index/) — Rovo Agent, Rovo Action, Rovo MCP, Rovo Connector, Forge LLMs.
> - Join the [Atlassian Developer Community](https://community.developer.atlassian.com/c/forge) and find your local [ACE group](https://ace.atlassian.com/).
>
> ### And Guru is one Rovo chat away whenever you get stuck
>
> Every question from here on — which module to use, what scope you need, how a Forge API works — ask Guru first. It searches [the official docs](https://developer.atlassian.com/platform/forge/) live and cites them, so you can trust the answer and follow the link.
>
> **The mental model you learned today** — the three building blocks (manifest, module, backend function) plus your working picture of the wider Atlassian platform Forge apps connect into — works for every Forge app you'll ever build. When you see a big Marketplace app, decompose it into those pieces and it stops looking scary.
>
> Have fun building. 🛠️

**Reply with `done` (or just close the chat) when you're ready to wrap up. Or reply with any question — Guru is on the dev site now, but I'm here too.**

This skill's job ends when the user has Forge Guru running on their dev site, has asked it at least one real Forge question and gotten a cited answer back, understands the three building blocks (and the wider Atlassian platform Forge apps connect into), and knows exactly which door to knock on next in the four-stage journey.