# What does jira.comment.added prove?

> Prove that the comment sits on the issue that the person named. Version 1.0.0, certification Provisional.

Canonical: https://provely.sh/verify/jira/jira.comment.added  
Last reviewed: 2026-09-05  
Skill version: 0.1.0  
Certification: provisional  

**Prove that the comment sits on the issue that the person named. A comment that exists is not a comment on the right issue. The level reads the comment through the issue that the person named.**

*Contract identity.*

| Fact | Value |
| --- | --- |
| Contract id | `jira.comment.added` |
| Version | `1.0.0` |
| Hash | `b52241d56dcb4ebf` |
| Completion level | `added` |
| Publisher | Built and signed by Provely. |
| Certification | Provisional |
| Skill | [Jira Cloud platform REST API 0.1.0](/verify/jira) |
| Valid for provider API versions | `3` |

## What is the intent?

Add this comment to the issue.

## What is the subject and the action?

| Member | Value |
| --- | --- |
| Subject type | `jira.comment` |
| Subject identity | comment_id = `$action.result.id` |
| Canonical effect | `work_tracking.comment_create` |
| Provider operation | `POST /rest/api/3/issue/{issueIdOrKey}/comment` |
| Idempotency | none, retry is not safe |

## How does the evidence correlate with this operation?

| Strategy | Assurance | Keys | Required |
| --- | --- | --- | --- |
| `resource_id` | strong | comment_id from `$action.result.id` | yes |
| `fingerprint` | weak | issue_id from `$input.issue_id`; body_text from `$input.body_text` | no |

## Which evidence does the contract require?

Minimum evidence level `E2`. An independent channel is required. Minimum channels: 1.

| Channel | Level | Independence | Verifier | Description |
| --- | --- | --- | --- | --- |
| `comment_readback` | E2 | provider readback | `http` | Read the comment of the issue. A condition path is $observed.comment_readback.body.content[0].content[0].text, because the version 3 states the body as a document. |
| `comment_creation_events_on_issue` | E3 | provider event | `webhook` | The comment_created callbacks of this issue since the operation started. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}. A count above one shows a second comment, and Jira states no idempotency key to stop it. |

## Which conditions must all hold for VERIFIED?

| Condition | Meaning | Path | Operator | Expected | Evidence |
| --- | --- | --- | --- | --- | --- |
| `comment_present` | The provider holds the comment with the identifier of the answer. | `$observed.comment_readback.id` | `eq` | `$action.result.id` | `comment_readback` |
| `comment_names_the_requested_issue` | The URL of the comment names the issue that the intent named. | `$observed.comment_readback.self` | `regex` | `/issue/${$input.issue_id}/comment/` | `comment_readback` |
| `comment_text_matches` | The text of the comment equals the requested text. The version 3 states the body as a document, so the path names the text node. | `$observed.comment_readback.body.content[0].content[0].text` | `eq` | `$input.body_text` | `comment_readback` |
| `comment_created_in_window` | The provider created the comment after the operation started. | `$observed.comment_readback.created` | `time_after` | `$operation.created_at` | `comment_readback` |
| `comment_creation_event` | At least one comment_created callback names this issue. | `$observed.comment_creation_events_on_issue.count` | `gte` | `1` | `comment_creation_events_on_issue` |

## Which conditions give CONTRADICTED?

| Condition | Class | Reason | Path | Operator | Expected |
| --- | --- | --- | --- | --- | --- |
| `comment_with_another_text` | wrong subject | The comment carries a different text than the intent stated. | `$observed.comment_readback.body.content[0].content[0].text` | `ne` | `$input.body_text` |
| `comment_predates_operation` | pre existing state | The comment is older than the operation. It proves nothing. | `$observed.comment_readback.created` | `time_before` | `$operation.created_at` |
| `duplicate_comment_present` | duplicate side effect | Jira wrote more than one comment on the issue since the operation started. Do not retry. | `$observed.comment_creation_events_on_issue.count` | `gt` | `1` |

## Which observed states map to a verdict before completion?

The contract declares no verdict map. The completion block decides.

## How long does the runtime observe?

| Timing member | Value |
| --- | --- |
| Initial delay | 1000 ms |
| Poll interval | 5000 ms |
| Backoff | exponential factor 2, max 60000 ms |
| Maximum attempts | 40 |
| Timeout | 900000 ms |
| Stale read window | 20000 ms |
| On timeout | UNVERIFIABLE (`evidence_unavailable_before_timeout`), escalated to a person |

## Where do these rules come from?

- `jira.openapi#/paths/~1rest~1api~13~1issue~1{issueIdOrKey}~1comment/post`: [jira.openapi](https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json), retrieved 2026-09-09
- `jira.openapi#/paths/~1rest~1api~13~1issue~1{issueIdOrKey}~1comment/post/responses/201`: [jira.openapi](https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json), retrieved 2026-09-09
- `jira.docs.comments#comments/add-a-comment`: [jira.docs.comments](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/), retrieved 2026-09-09
- `jira.docs.comments#comments/the-body-of-a-comment-is-a-document-not-a-string`: [jira.docs.comments](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/), retrieved 2026-09-09
- `jira.openapi#/components/schemas/Comment/properties/id`: [jira.openapi](https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json), retrieved 2026-09-09
- `jira.openapi#/paths/~1rest~1api~13~1issue~1{issueIdOrKey}~1comment~1{id}/get/responses/200`: [jira.openapi](https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json), retrieved 2026-09-09
- `jira.openapi#/paths/~1rest~1api~13~1issue~1{issueIdOrKey}~1comment~1{id}/get`: [jira.openapi](https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json), retrieved 2026-09-09
- `jira.openapi#/components/schemas/Comment/properties/self`: [jira.openapi](https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json), retrieved 2026-09-09
- `jira.openapi#/components/schemas/Comment/properties/body`: [jira.openapi](https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json), retrieved 2026-09-09
- `jira.openapi#/components/schemas/Comment/properties/created`: [jira.openapi](https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json), retrieved 2026-09-09
- `jira.events#/events/comment_created`: [jira.events](https://developer.atlassian.com/cloud/jira/platform/webhooks/), retrieved 2026-09-09
- `jira.docs.webhooks#webhooks/the-event-names`: [jira.docs.webhooks](https://developer.atlassian.com/cloud/jira/platform/webhooks/), retrieved 2026-09-09
- `jira.openapi#/components/schemas/Webhook/properties/events`: [jira.openapi](https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json), retrieved 2026-09-09

### Can jira.comment.added return VERIFIED from the action response alone?

No. The minimum evidence level is E2. The action response is E1. The completion conditions read `comment_readback` and `comment_creation_events_on_issue`.

### What happens after the timeout?

The verdict is UNVERIFIABLE with the reason `evidence_unavailable_before_timeout`. The operation goes to a person for review.

## Read next

- [Read the Jira Cloud platform REST API verification page](https://provely.sh/verify/jira)
- [Read the jira.issue.created contract](https://provely.sh/verify/jira/jira.issue.created)
- [Read the jira.issue.in_status contract](https://provely.sh/verify/jira/jira.issue.in_status)
- [Read what a completion contract contains](https://provely.sh/contracts)
- [Read what a receipt proves](https://provely.sh/docs/receipts)
