Skip to main content
Glama
ai-q-labs

Claim Check for Jira

by ai-q-labs
README.md
# Claim Check for Jira

**Verify before you post.** AI agents write status updates about Jira all day — "PROJ-12 is done",
"four issues are still open in this sprint", "Mia owns the release blocker". Some of those sentences are
wrong, and they read exactly like the right ones. Claim Check is an Atlassian Forge app that checks each
fact against live Jira before it is posted, and keeps checking it after.

Built for Codegeist 2026 (Apps for Software Teams).

## What it does

- **Three read-only tools for agents** (a `rovo:mcp` module, usable by Rovo agents and by external MCP clients
  once a site admin enables them):
  - *Verify claims about Jira issues* — one claim per line, `<ISSUE-KEY> <field> <op> <value>`;
    each comes back **MATCH**, **MISMATCH** (with the value Jira has) or **UNVERIFIABLE** (with the reason).
  - *Verify a claimed issue count* — runs the JQL that defines the set and counts exactly.
  - *Get verifiable facts for Jira issues* — so the update is written from evidence in the first place.
- **An issue panel** that finds the claim lines already posted in the issue's comments (for example the
  "Verified by Claim Check" list an agent ends its update with) and re-checks them against Jira *now*.
  A claim that was true when it was posted can stop being true; the panel shows which.
- **An open agent skill** — [`skills/claim-check/SKILL.md`](skills/claim-check/SKILL.md) — that tells any agent
  the loop: draft → turn facts into claim lines → verify → fix every mismatch → post.

## How it decides

Every comparison is deterministic code in a Forge function ([`src/logic.js`](src/logic.js)); no model is asked
whether a claim is true. Two details that matter in practice:

- Jira shows status, type, priority and resolution names **in the reader's language**. An agent writing
  "In Progress" for a Japanese site would look wrong when it is right, so Claim Check also compares against
  the untranslated name Jira stores. When no untranslated name exists (priority, resolution), it answers
  **UNVERIFIABLE** with the name Jira shows, instead of a false MISMATCH.
- Jira turns a typed issue key in a comment into a smart link. The panel reads those links back as keys.

## Privacy and permissions

- One scope: `read:jira-work`. Every read is made **as the person using the app** (`asUser`), so nobody can
  verify — and so learn — anything about an issue they could not open themselves.
- Nothing is stored, nothing leaves Atlassian, no AI model is called by the app.
  See [PRIVACY.md](PRIVACY.md) and [TERMS.md](TERMS.md).

## Try it

1. Install the app on a Jira Cloud site (a free developer site works) with the installation link from the
   submission.
2. **Issue panel:** open an issue, click the **Apps** icon under the title, choose **Claim Check**. Add a comment with
   claim lines such as `ABC-1 status = Done`, then click **Check again**.
3. **Rovo agent:** in Rovo Studio, add the three Claim Check tools to an agent and ask it for a status update
   that it must verify before answering.
4. **External MCP client:** a site or org admin turns it on in *Atlassian Administration → Apps → Sites →
   your site → Connected apps → Claim Check → Tools*. The endpoint is
   `https://mcp.atlassian.com/forge/c604867c-480d-4e4f-825b-23cb2a6af98d`.

## Develop

```
npm install
npm test            # unit tests for the comparison logic (node --test)
forge lint
forge deploy -e development
forge install --site <your-site>.atlassian.net --product jira
```

## License

MIT — see [LICENSE](LICENSE).