@atollhq/skill-codex 0.4.22 → 0.4.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,6 +14,7 @@ write access returns `403`; collection reads may omit unreadable linked rows.
14
14
  ## Table of Contents
15
15
 
16
16
  - [Authentication](#authentication)
17
+ - [Error and routing semantics](#error-and-routing-semantics)
17
18
  - [Organizations](#organizations)
18
19
  - [Projects](#projects)
19
20
  - [Project Members](#project-members)
@@ -25,6 +26,7 @@ write access returns `403`; collection reads may omit unreadable linked rows.
25
26
  - [Subtasks](#subtasks)
26
27
  - [Members](#members)
27
28
  - [Milestones](#milestones)
29
+ - [Artifacts](#artifacts)
28
30
  - [Goals](#goals)
29
31
  - [KPIs](#kpis)
30
32
  - [Initiatives](#initiatives)
@@ -41,6 +43,7 @@ write access returns `403`; collection reads may omit unreadable linked rows.
41
43
  - [Attachments](#attachments)
42
44
  - [Profile Images](#profile-images)
43
45
  - [PR Links](#pr-links)
46
+ - [External References](#external-references)
44
47
  - [Project Status Updates](#project-status-updates)
45
48
  - [Project Health](#project-health)
46
49
  - [Analytics](#analytics)
@@ -61,7 +64,7 @@ write access returns `403`; collection reads may omit unreadable linked rows.
61
64
  | GET | `/api/auth/me` | Resolve the caller's org role, key scopes, and live `projectAccess[]` grants |
62
65
  | POST | `/mcp` | Hosted MCP Streamable HTTP endpoint at `https://atollhq.com/mcp` |
63
66
  | GET | `/.well-known/oauth-protected-resource` | Public MCP protected-resource metadata |
64
- | GET | `/oauth/consent?authorization_id=...` | Human OAuth consent and multi-profile agent selection UI |
67
+ | GET | `/oauth/consent?authorization_id=...` | Inert OAuth continuation page; profile selection or automatic client return starts only after explicit continuation |
65
68
  | POST | `/api/oauth/consent` | Approve or deny an OAuth request after explicitly selecting one or more agents |
66
69
  | GET | `/api/oauth/agent-profiles` | OAuth connection validation and currently usable profile summaries |
67
70
  | GET | `/api/oauth/connections` | List the signed-in human's OAuth connections and grants |
@@ -73,6 +76,15 @@ Project-scoped agents remain organization guests. Use `projectAccess[]` to
73
76
  inspect their effective `view`, `edit`, or `admin` access; membership changes
74
77
  do not require key rotation.
75
78
 
79
+ ## Error and routing semantics
80
+
81
+ Missing authentication on a shared guarded API route returns `401` JSON with
82
+ `{ "error": "Unauthorized", "code": "unauthorized" }`. Unknown `/api/*`
83
+ paths return `404` JSON with `{ "error": "Not found", "code": "not_found" }`.
84
+ Signed-out workspace-style page routes return a neutral real `404` that does
85
+ not confirm whether a workspace exists; fixed protected routes retain their
86
+ normal sign-in behavior.
87
+
76
88
  ## Organizations
77
89
 
78
90
  | Method | Endpoint | Description |
@@ -146,6 +158,17 @@ Plan limits are enforced when creating projects, human members, agents/integrati
146
158
  | POST | `/api/orgs/{id}/issues/{issueId}/initiatives` | Link task to initiative (`{ initiative_id }`) |
147
159
  | DELETE | `/api/orgs/{id}/issues/{issueId}/initiatives/{initiativeId}` | Unlink task from initiative |
148
160
 
161
+ When a task that blocks other work changes projects, include
162
+ `dependencyReleaseMappings: [{ "dependencyId": "uuid", "releaseColumnId": "uuid" }]`
163
+ for every blocking dependency. The destination columns must belong to the new
164
+ project; projectless moves with blocking dependencies are rejected. REST also
165
+ accepts top-level `dependency_release_mappings` and legacy
166
+ `releaseColumnMappings`, plus item aliases `dependency_id` and
167
+ `release_column_id`. MCP uses `dependency_release_mappings` with
168
+ `dependency_id` and `release_column_id`; the CLI equivalent is
169
+ `--dependency-release-mappings '<json-array>'` with camelCase items
170
+ `dependencyId` and `releaseColumnId`.
171
+
149
172
  Issue-centric initiative links follow both resource boundaries. The collection
150
173
  read requires access to the task, omits linked initiatives the caller cannot
151
174
  read, and returns `200`. For project-bound tasks, linking and unlinking require
@@ -170,6 +193,19 @@ The existing `GET /api/orgs/{id}/issues/{issueId}` detail route accepts an autho
170
193
  - `offset` -- pagination offset
171
194
  - `shape=envelope` or `response_shape=cli` -- opt into CLI-compatible list responses: `{ resource, items, total, limit, offset, nextOffset, truncated, hint }`
172
195
 
196
+ Full issue-list items include the canonical project-prefixed `identifier` and
197
+ collision-free `projectSlug` for project issues, or `null` for projectless
198
+ issues. Compact board/list views do not include these fields.
199
+
200
+ The MCP `atoll_list_issues` tool always returns the exact `{ resource, items,
201
+ total, limit, offset, nextOffset, truncated, hint }` envelope. In the full
202
+ profile it is in `structuredContent`; in the public plugin it is under
203
+ `structuredContent.result.data`. Project-scoped calls may add `project_context`
204
+ alongside the envelope. It accepts both legacy REST `{ issues, total, limit,
205
+ offset }` and CLI-compatible REST `{ resource: "issues", items, ... }` upstream
206
+ bodies, projects only declared public issue fields, preserves nullable
207
+ `identifier` and `projectSlug`, and does not expose the CLI-derived `url` field.
208
+
173
209
  **GET task detail** returns enriched data: `milestone`, `creator`, `assignee`, `assignees`, `sub_tasks`, `issue_labels`, and `isBlocked`. Recurring tasks also return normalized `recurrence_days` and `recurrence_schedule`. Create, update, and bulk-create accept `recurrenceDays` only with `recurrenceType: "weekly"`; values must be unique weekdays from `mon` through `sun`.
174
210
 
175
211
  ## Dependencies
@@ -178,9 +214,16 @@ The existing `GET /api/orgs/{id}/issues/{issueId}` detail route accepts an autho
178
214
  |--------|----------|-------------|
179
215
  | GET | `/api/orgs/{id}/issues/{issueId}/dependencies` | List dependencies (`{ blocking, blockedBy }`) |
180
216
  | POST | `/api/orgs/{id}/issues/{issueId}/dependencies` | Add dependency |
217
+ | PATCH | `/api/orgs/{id}/issues/{issueId}/dependencies/{depId}` | Change dependency release point |
181
218
  | DELETE | `/api/orgs/{id}/issues/{issueId}/dependencies/{depId}` | Remove dependency |
182
219
 
183
- Add with `{ "blockedByIssueId": "uuid" }` or `{ "blockingIssueId": "uuid" }`. Circular dependencies rejected (400). Duplicates return 409.
220
+ Add with `{ "blockedByIssueId": "uuid" }` or `{ "blockingIssueId": "uuid" }`; snake_case aliases `{ "blocked_by_issue_id": "uuid" }` and `{ "blocking_issue_id": "uuid" }` are also accepted. The blocking issue must belong to a project; a projectless issue may be the blocked target. Optionally include `releaseColumnId` from the blocking project's board columns. Omit it to use the blocking project's `done` column. PATCH the dependency with `{ "releaseColumnId": "uuid" }`. Circular dependencies rejected (400). Duplicates return 409.
221
+
222
+ Dependency reads include each authorized target issue's canonical `identifier` and `projectSlug` when it belongs to a project. Projectless targets have both fields `null`; inaccessible targets remain `issue: null`. Release fields include `releaseColumnId` and the compatibility alias `release_column_id`; POST and PATCH accept either camelCase or snake_case release-column input. Release metadata is present when the blocking issue is authorized; a `blocking` target projection may still be `issue: null` independently.
223
+ The dependency-release migration backfills existing dependencies to the
224
+ blocking project's `done` column. During a rolling deployment, compatibility
225
+ reads may omit release fields from older rows; treat missing release metadata as
226
+ the legacy open-blocker behavior until the migration is applied.
184
227
 
185
228
  ## Comments
186
229
 
@@ -202,6 +245,8 @@ List-comment responses include `comments[].mentioned_members`, an array of `{ id
202
245
 
203
246
  Replies use `reply_to_comment_id`. List/read responses include a `reply_to_comment` object containing the parent comment's routing-safe `source_metadata`. Agent-authored comments may submit explicit `source_metadata` with `harness`, `thread_id` and/or `session_id`, and optional `host_id`; unknown keys and human-authored provenance are rejected. Omit it unless a real thread or session ID exists, and never invent one. The issue-update comment path uses `comment_source_metadata`.
204
247
 
248
+ Automation-authored comments return `author_type: "automation"` with null `author_id` and null comment routing `source_metadata`; their matching `comment.created` Activity is actorless and keeps automation provenance in metadata.
249
+
205
250
  Responses that create comments include `outcome.persistence` and `outcome.mentions`, with the legacy top-level `mentions` alias. `created` means a new notification row, `deduped` means an existing idempotent row, and `notification_rows.status: "failed"` reports notification setup failure without changing persisted comment state. `transport.dispatch: "scheduled"` is asynchronous Google Chat scheduling, not final delivery, including repair of a missing durable delivery row; `already_scheduled` means the durable delivery row already existed. `transport.final` stays null while any final delivery is unknown, and is `mixed` when all recipient deliveries are terminal but differ. Inspect each recipient outcome for mixed results. `transport.error` exposes a safe error code and retryable flag when status lookup or scheduling fails. Each skipped target includes `member_id` and `reason`.
206
251
 
207
252
  ## Subtasks
@@ -242,6 +287,32 @@ Project-bound reads require effective project access. Create and update require
242
287
  `edit` or `admin` access. Unreadable milestones are concealed as `404`.
243
288
  Milestone deletion remains organization owner/admin-only.
244
289
 
290
+ ## Artifacts
291
+
292
+ The exact opt-in issue request
293
+ `GET /api/orgs/{id}/issues/{issueId}?include=artifact_manifest` adds only PRD
294
+ and Implementation Plan metadata. Default issue detail does not query or expose
295
+ Artifacts.
296
+
297
+ | Method | Endpoint | Description |
298
+ | --- | --- | --- |
299
+ | `GET` | `/api/orgs/{id}/artifacts` | List readable artifact metadata and visible links; revision content is omitted; supports `limit` (1-100, default 50) and `offset` (0-10000), and returns `hasMore` |
300
+ | `POST` | `/api/orgs/{id}/artifacts` | Create artifact and immutable revision 1 atomically |
301
+ | `GET` | `/api/orgs/{id}/artifacts/{artifactId}` | Read artifact metadata and visible links |
302
+ | `GET` | `/api/orgs/{id}/artifacts/{artifactId}/revisions` | List immutable revision summaries without content; supports `limit` (1-100, default 50) and `offset`, and returns `hasMore` |
303
+ | `POST` | `/api/orgs/{id}/artifacts/{artifactId}/revisions` | Create a content revision or title-aware full snapshot with an expected current revision |
304
+ | `GET` | `/api/orgs/{id}/artifacts/{artifactId}/revisions/{revisionId}` | Read one sanitized revision including content |
305
+ | `POST` | `/api/orgs/{id}/artifacts/{artifactId}/links` | Link to an authorized issue or project |
306
+ | `DELETE` | `/api/orgs/{id}/artifacts/{artifactId}/links/{linkId}` | Unlink atomically |
307
+
308
+ Creation accepts `{ type, title, content, content_format?, links? }`. Types are
309
+ `prd`, `implementation_plan`, `test_plan`, `decision`, `research`, and
310
+ `release_checklist`. Content is normalized to safe HTML, titles are capped at
311
+ 200 UTF-8 bytes, and stored revisions at 256 KiB. Stale revision writes return
312
+ `409`. Linked access follows the target; unlinked artifacts are for non-guest
313
+ members and owners/admins have organization-wide access. Removing the final
314
+ link requires owner or admin access.
315
+
245
316
  ## Goals
246
317
 
247
318
  | Method | Endpoint | Description |
@@ -261,7 +332,7 @@ Milestone deletion remains organization owner/admin-only.
261
332
  | GET | `/api/orgs/{id}/kpis/{kpiId}` | Get KPI with visible `initiative_impacts`; non-guest Strategy read access required |
262
333
  | PATCH | `/api/orgs/{id}/kpis/{kpiId}` | Update KPI; owner/admin Strategy write access required |
263
334
  | DELETE | `/api/orgs/{id}/kpis/{kpiId}` | Delete KPI (admin/owner only) |
264
- | GET | `/api/orgs/{id}/kpis/{kpiId}/snapshots` | List snapshots (optional `?limit=50`); non-guest Strategy read access required |
335
+ | GET | `/api/orgs/{id}/kpis/{kpiId}/snapshots` | List snapshots (optional `?limit=50`; `?projection=provenance_v1` adds nullable source-window dates); non-guest Strategy read access required |
265
336
  | POST | `/api/orgs/{id}/kpis/{kpiId}/snapshots` | Record a snapshot; owner/admin Strategy write access required |
266
337
  | GET | `/api/orgs/{id}/kpi-http-sync-policy` | List exact-host KPI HTTP sync allowlist policy |
267
338
  | POST | `/api/orgs/{id}/kpi-http-sync-policy` | Add an allowed exact host (human admin only) |
@@ -303,9 +374,10 @@ direct issue and milestone links. A read is allowed when at least one linked
303
374
  project is readable, but write operations require edit/admin access to every
304
375
  project linked to the initiative. Projectless initiatives are readable by
305
376
  non-guest organization members and writable only by owners/admins. KPI-impact
306
- reads omit unreadable KPIs; KPI-impact writes additionally require owner/admin
307
- Strategy access. Unreadable directly requested resources return `404`; readable
308
- resources without sufficient write access return `403`.
377
+ reads omit unreadable KPIs; KPI-impact writes require write access to the
378
+ initiative and read access to the same-org KPI, not KPI Strategy write access.
379
+ Unreadable directly requested resources return `404`; readable resources
380
+ without sufficient write access return `403`.
309
381
 
310
382
  Detail reads include read-only intended-impact projections. Initiative detail
311
383
  embeds `kpi_impacts` only for KPIs the caller may read. KPI detail embeds
@@ -318,8 +390,8 @@ attribution; mutate them only through the initiative KPI-impact link endpoints.
318
390
  | Method | Endpoint | Description |
319
391
  |--------|----------|-------------|
320
392
  | GET | `.../initiatives/{id}/kpi-impacts` | List KPI impact links whose KPIs are readable |
321
- | POST | `.../initiatives/{id}/kpi-impacts` | Add (`{ kpi_id, expected_impact? }`); owner/admin KPI Strategy write access required |
322
- | DELETE | `.../initiatives/{id}/kpi-impacts/{impactId}` | Remove link; owner/admin KPI Strategy write access required |
393
+ | POST | `.../initiatives/{id}/kpi-impacts` | Add (`{ kpi_id, expected_impact? }`); initiative write access plus readable same-org KPI required |
394
+ | DELETE | `.../initiatives/{id}/kpi-impacts/{impactId}` | Remove link; initiative write access plus readable same-org KPI required |
323
395
  | GET | `.../initiatives/{id}/issues` | List linked issue links; add `?details=1` for accessible task details from linked projects, direct issue links, and linked milestones |
324
396
  | POST | `.../initiatives/{id}/issues` | Link issue by UUID, number, `#number`, `ATOLL-number`, `TSK-number`, or unambiguous project-derived prefix (`{ issue_id }`) |
325
397
  | DELETE | `.../initiatives/{id}/issues/{issueId}` | Unlink issue |
@@ -388,9 +460,9 @@ KPI stale/off-pace signal metadata includes `linked_initiatives` and `recent_att
388
460
  | Method | Endpoint | Description |
389
461
  |--------|----------|-------------|
390
462
  | GET | `/api/orgs/{id}/activity` | Org activity feed (`?limit=&offset=&filter=by_me\|mine`) |
391
- | GET | `/api/orgs/{id}/issues/{issueId}/activity` | Task activity feed |
463
+ | GET | `/api/orgs/{id}/issues/{issueId}/activity?limit=50&offset=0` | Canonical task Activity history |
392
464
 
393
- Filters: `by_me` = your actions; `mine` = activity on issues assigned to you.
465
+ Filters: `by_me` = your actions; `mine` = activity on issues assigned to or created by you.
394
466
 
395
467
  Organization activity is limited to accessible projects; eligible non-guests may
396
468
  also receive projectless activity. Project-bound issue activity requires project
@@ -423,16 +495,16 @@ Custom statuses per project. Each column defines a valid status value and may in
423
495
 
424
496
  | Method | Endpoint | Description |
425
497
  |--------|----------|-------------|
426
- | GET | `/api/orgs/{id}/projects/{projectId}/board-columns` | Return `{ columns, accepted_statuses }`; columns are ordered by position and `cancelled` is a separate system status, not a column row |
498
+ | GET | `/api/orgs/{id}/projects/{projectId}/board-columns` | Return `{ columns, accepted_statuses }`; columns are ordered by position and include nullable `recommendation_role`, `issue_count`, and `release_reference_count` impact counts |
427
499
  | GET | `/api/orgs/{id}/projects/{projectId}/board-context` | Get board milestone and initiative focus context |
428
- | POST | `/api/orgs/{id}/projects/{projectId}/board-columns` | Append column (`{ key, label, description?, color? }`) |
429
- | PATCH | `/api/orgs/{id}/projects/{projectId}/board-columns/{columnId}` | Update column (`{ label?, description?, color? }`) |
430
- | DELETE | `/api/orgs/{id}/projects/{projectId}/board-columns/{columnId}` | Delete column (`?reassignTo={columnId}` is required when the source contains issues) |
500
+ | POST | `/api/orgs/{id}/projects/{projectId}/board-columns` | Append column (`{ key, label, description?, color?, recommendationRole? }`; `recommendation_role` is also accepted) |
501
+ | PATCH | `/api/orgs/{id}/projects/{projectId}/board-columns/{columnId}` | Update column (`{ label?, description?, color?, recommendationRole? }`; `recommendation_role` is also accepted; both values must match when both aliases are present; use `null` to clear) |
502
+ | DELETE | `/api/orgs/{id}/projects/{projectId}/board-columns/{columnId}` | Delete column; use independent `?reassignTo={columnId}&releaseReassignTo={columnId}` targets when issue or release references exist |
431
503
  | PUT | `/api/orgs/{id}/projects/{projectId}/board-columns/reorder` | Bulk reorder (`{ columns: [{id, position}] }`) |
432
504
 
433
505
  Reads require effective project access; mutations require `edit` or `admin`.
434
506
  Delete-with-reassignment and reorder are atomic, the final column cannot be
435
- deleted, reorder requires the complete current column set, and cross-project
507
+ deleted, release references require an explicit independent target, reorder requires the complete current column set, and cross-project
436
508
  targets, duplicate positions, and negative or non-integer positions are
437
509
  rejected. Creation appends; direct `position` changes on create or patch are
438
510
  rejected.
@@ -533,6 +605,21 @@ For project-bound issues, listing requires project access and attaching requires
533
605
  projectless issues. Authorization is bound to the issue's current parent before
534
606
  child reads or writes and occurs before URL parsing or GitHub metadata lookup.
535
607
 
608
+ ## External References
609
+
610
+ | Method | Endpoint | Description |
611
+ |--------|----------|-------------|
612
+ | GET | `/api/orgs/{id}/issues/{issueId}/external-references` | List issue external references |
613
+ | POST | `/api/orgs/{id}/issues/{issueId}/external-references` | Resolve and link a GitHub PR |
614
+ | GET | `/api/orgs/{id}/issues/{issueId}/external-references/{referenceId}` | Inspect a linked reference |
615
+ | DELETE | `/api/orgs/{id}/issues/{issueId}/external-references/{referenceId}` | Unlink a reference |
616
+ | GET | `/api/orgs/{id}/projects/{projectId}/external-references` | List project external references |
617
+ | POST | `/api/orgs/{id}/projects/{projectId}/external-references` | Resolve and link a GitHub PR |
618
+ | GET | `/api/orgs/{id}/projects/{projectId}/external-references/{referenceId}` | Inspect a linked reference |
619
+ | DELETE | `/api/orgs/{id}/projects/{projectId}/external-references/{referenceId}` | Unlink a reference |
620
+
621
+ External Reference POST requests accept `{ "url": "https://github.com/owner/repo/pull/123" }`. They require an authorized GitHub connection and store a reference only when the live response proves numeric immutable repository and pull-request IDs. Missing proof returns `422` with `code: "github_identity_unavailable"`. URLs and caller owner/repo fields are not identity or authorization inputs. Existing PR-link operations remain independent; CLI/MCP tools are deferred to a later slice.
622
+
536
623
  ## Project Status Updates
537
624
 
538
625
  | Method | Endpoint | Description |
@@ -578,10 +665,15 @@ receive projectless work. An inaccessible explicit `projectId` is concealed as
578
665
  | GET | `/api/orgs/{id}/automation-rules/{ruleId}` | Get rule |
579
666
  | PUT | `/api/orgs/{id}/automation-rules/{ruleId}` | Update rule (owner/admin) |
580
667
  | DELETE | `/api/orgs/{id}/automation-rules/{ruleId}` | Delete rule (owner/admin) |
581
- | GET | `/api/orgs/{id}/automation-rules/{ruleId}/activity` | Rule execution history |
668
+ | GET | `/api/orgs/{id}/automation-rules/{ruleId}/activity` | Rule execution history (owner/admin; latest 100 runs) |
582
669
  | POST | `/api/orgs/{id}/automation-rules/{ruleId}/test` | Dry-run test |
583
670
 
584
671
  Trigger events: `issue.created`, `issue.status_changed`, `issue.assigned`, `issue.priority_changed`.
672
+ Create and update requests reject unsupported action types or malformed action
673
+ values before persistence. Activity returns safe durable run/action history;
674
+ non-matches, dry runs, and rules without executable actions create no history,
675
+ and action inputs, raw event payloads, credentials, headers, and response
676
+ bodies are not returned.
585
677
 
586
678
  ## Webhooks
587
679
 
@@ -648,7 +740,8 @@ Google Chat mention cards include the task title, a safely formatted plain-text
648
740
  | Method | Endpoint | Description |
649
741
  |--------|----------|-------------|
650
742
  | GET | `/api/orgs/{id}/agents` | List agents (owner/admin) |
651
- | GET | `/api/orgs/{id}/agents/manageable` | List manageable agents with visible project IDs, named accessible projects, and heartbeat policy status/focus summary |
743
+ | GET | `/api/orgs/{id}/agents/workforce` | Read a bounded workforce projection; org owners/admins may list all agents, project admins must pass `?projectId=...`, and individual owners may read their own agents |
744
+ | GET | `/api/orgs/{id}/agents/manageable` | List manageable agents with visible project IDs, named accessible projects, heartbeat policy status/focus summary, API-key usage metadata, and aggregate active-key/OAuth activity |
652
745
  | POST | `/api/orgs/{id}/agents` | Create org agent (`{ name, role?, setupScoped? }`), project-scoped agent (`{ name, projectIds }` or legacy `{ name, projectId, projectIds? }`), or personal agent (`{ name, personal: true }`); key-minting responses include one-time `apiKey` and stable `apiKeyId` (`oauthOnly` omits both) |
653
746
  | DELETE | `/api/orgs/{id}/agents/{agentId}` | Revoke manageable agent |
654
747
  | PATCH | `/api/orgs/{id}/agents/{agentId}/projects` | Replace project access for a manageable non-personal agent |
@@ -658,6 +751,11 @@ Google Chat mention cards include the task title, a safely formatted plain-text
658
751
  | DELETE | `/api/orgs/{id}/agents/{agentId}/keys/{keyId}` | Revoke key for a manageable agent |
659
752
  | POST | `/api/orgs/{id}/agents/{agentId}/rotate` | Rotate all keys for a manageable agent |
660
753
  | POST | `/api/orgs/{id}/agents/{agentId}/install-snippets` | Get install snippets for a manageable agent (`{ key, profileName?, projectId?, teamId?, baseUrl? }`) |
754
+ | GET | `/api/orgs/{id}/runners/self` | Read the authenticated agent's runner installation and computed presence state |
755
+ | PUT | `/api/orgs/{id}/runners/self` | Register or refresh the authenticated agent's runner installation |
756
+ | DELETE | `/api/orgs/{id}/runners/self` | Disconnect the authenticated agent's current runner installation; idempotent |
757
+ | POST | `/api/orgs/{id}/runner-leases/claim` | Atomically claim or safely replay a runner lease; untouched pre-intent replays can reissue a token |
758
+ | PATCH | `/api/orgs/{id}/runner-leases/{leaseId}` | Apply a fenced lifecycle transition; paused or stale runners cannot mutate or replay |
661
759
 
662
760
  Install snippets returns config for `claude-code`, `codex`, `gemini`, `openclaw` (agent prompt), `openclaw-manual`, `hermes` (agent prompt), and `hermes-manual`. The server resolves the org slug and validates optional project/team IDs before generating snippets.
663
761
 
@@ -693,6 +791,9 @@ The default new-agent local path (without `setupAgentMemberId`) atomically creat
693
791
  | Method | Endpoint | Description |
694
792
  |--------|----------|-------------|
695
793
  | GET | `/api/orgs/{id}/github-connections` | List GitHub connections (owner/admin) |
794
+ | PATCH | `/api/orgs/{id}/github-connections/{connectionId}` | Update workflow verification mode, 1–10 paths of at most 255 characters each, or delivery agent (owner/admin) |
795
+ | POST | `/api/orgs/{id}/github-connections/{connectionId}/reconcile` | Reconcile the signed GitHub hook and retry pending workflow evidence after current GitHub and PR-link readback (owner/admin) |
796
+ | GET | `/api/orgs/{id}/github-connections/{connectionId}/workflow-runs` | List bounded workflow-run evidence (owner/admin; `limit` defaults to 25 and has a maximum of 100) |
696
797
  | GET | `/api/integrations/github/repos` | List available repos |
697
798
  | POST | `/api/integrations/github/connect` | Connect a repo |
698
799
  | POST | `/api/integrations/github/disconnect` | Disconnect a repo |
@@ -3,6 +3,7 @@
3
3
  ## Table of Contents
4
4
 
5
5
  - [Auth Context](#auth-context)
6
+ - [Error Responses](#error-responses)
6
7
  - [OAuth Agent Profiles](#oauth-agent-profiles)
7
8
  - [Task Fields](#task-fields)
8
9
  - [Goal Fields](#goal-fields)
@@ -17,6 +18,7 @@
17
18
  - [Private Inbox Fields](#private-inbox-fields)
18
19
  - [Setup Proposal Fields](#setup-proposal-fields)
19
20
  - [Heartbeat Response](#heartbeat-response)
21
+ - [Artifact Fields](#artifact-fields)
20
22
  - [Analytics Response](#analytics-response)
21
23
  - [Plan Limit Errors](#plan-limit-errors)
22
24
  - [Agent Fields](#agent-fields)
@@ -54,6 +56,50 @@ the selected agent connection:
54
56
  Project-scoped agents intentionally remain organization guests. Role and
55
57
  project-access changes are read live and do not require key rotation.
56
58
 
59
+ ## Error Responses
60
+
61
+ Shared missing-auth failures return `401` JSON with `error: "Unauthorized"`
62
+ and `code: "unauthorized"`. Unknown `/api/*` paths return `404` JSON with
63
+ `error: "Not found"` and `code: "not_found"`. The `code` field is additive;
64
+ other route-specific legacy errors may contain only `error`.
65
+
66
+ ## Local runner presence
67
+
68
+ `GET`, `PUT`, and `DELETE /api/orgs/{id}/runners/self` are agent-only. The
69
+ organization and agent member come from authentication. `PUT` accepts
70
+ `instanceId`, optional `hostId` (the server-bound host routing identity), `platform` (`darwin`, `linux`, or `windows`), `arch` (`arm64`,
71
+ `x64`, or `amd64`), `capabilities` (unique values from `codex` and `git`),
72
+ `clientVersion` (numeric semantic version), and `intakeState` (`active` or
73
+ `paused`). The server derives the display name. Responses include computed
74
+ `presence_state`: `connected`, `stale` after 10 minutes, or `offline` after
75
+ explicit disconnect. They contain no API keys, profile names, prompts,
76
+ process IDs, or local/machine/worktree paths. Refreshes are limited to 60
77
+ per authenticated agent per minute and return `429` with `Retry-After`. If the
78
+ shared rate-limit check fails, the route fails closed with `503` and
79
+ `code: "RATE_LIMIT_CHECK_FAILED"`. Rate-limit responses also include
80
+ `code: "RATE_LIMITED"`, `retryAfterSeconds`, `limit`, and `currentCount`;
81
+ recent-instance conflicts use `code: "RUNNER_INSTALLATION_CONFLICT"`.
82
+
83
+ ## Local runner leases
84
+
85
+ `POST /api/orgs/{id}/runner-leases/claim` atomically claims an assigned,
86
+ accessible, dependency-satisfied issue for the authenticated agent's current
87
+ runner. The body accepts `issueId` and `idempotencyKey`; `attention_resume`
88
+ also requires `attentionItemId`, `runnerHostId` (maximum 255 characters), `preservedThreadId`, and
89
+ `actionKind`. The response returns an ephemeral token; only its SHA-256 hash is
90
+ stored. An untouched, unexpired, pre-intent `active` replay returns a new token
91
+ with `token_reissued: true` and invalidates the original token. During overlapping recovery retries, the four newest prior recovery tokens remain valid for one minute or until one is used, which promotes it. Other replays
92
+ return `token: null`; terminal attention replays are acknowledgement-only. `PATCH /api/orgs/{id}/runner-leases/{leaseId}` accepts fenced renew,
93
+ progress, turn-milestone, terminal, reconciliation, and acknowledgement
94
+ transitions, including `model_completed`. Organization, agent, runner, generation, token, and sequence must
95
+ match. Exact mutation retries are idempotent, and `uncertain_outcome` blocks
96
+ automatic replacement. Paused, disconnected, stale, or replaced runners cannot
97
+ mutate or replay. Lease rows enforce a composite `(issue_id, org_id)` foreign key.
98
+ Mutation metadata is closed: `progress` accepts `preparing`,
99
+ `turn_intent_persisted`, `sdk_accepted`, `running`, `model_completed`, or
100
+ `finalizing`; `errorCode` accepts `runner_error`, `sdk_error`, `model_error`,
101
+ `timeout`, `cancelled`, or `unknown`. Free-form runtime details are rejected.
102
+
57
103
  ## OAuth Agent Profiles
58
104
 
59
105
  `GET /api/oauth/agent-profiles` and `atoll_list_agent_profiles` return only
@@ -83,7 +129,7 @@ calls return stable errors: `no_profiles_authorized`, `profile_required`
83
129
 
84
130
  ## Task Fields
85
131
 
86
- Request bodies accept **camelCase** (`assigneeId`, `projectId`). Snake_case also accepted for backward compatibility. Responses always use snake_case.
132
+ Request bodies accept **camelCase** (`assigneeId`, `projectId`). Snake_case also accepted for backward compatibility. Responses generally use snake_case; dependency responses retain camelCase release fields (`releaseColumnId`, `releaseColumn`, and nested `projectId`) plus the `release_column_id` compatibility alias.
87
133
 
88
134
  ## Avatar Upload Response
89
135
 
@@ -137,6 +183,19 @@ Most fields work on both POST (create) and PATCH (update). `labelIds` is accepte
137
183
  - **Archived tasks**: Have `archived_at` timestamp. Excluded by default; pass `includeArchived=true`.
138
184
  - **GET detail** returns enriched data: `milestone`, `creator`, `assignee`, `assignees`, `sub_tasks`, `issue_labels`, `isBlocked`.
139
185
 
186
+ Full `GET /api/orgs/{id}/issues` list items include the canonical
187
+ project-prefixed `identifier` and collision-free `projectSlug` for project
188
+ issues, or `null` for projectless issues. Compact `view=board` and `view=list`
189
+ items do not include these fields.
190
+
191
+ The MCP `atoll_list_issues` projection exposes optional nullable
192
+ `identifier` and `projectSlug`, drops undeclared REST enrichment including the
193
+ CLI-derived `url`, and normalizes both legacy `{ issues, total, limit, offset }`
194
+ and CLI-compatible `{ resource: "issues", items, ... }` responses into the
195
+ exact public list envelope. The full profile exposes it in `structuredContent`;
196
+ the public plugin exposes it under `structuredContent.result.data`. Project-
197
+ scoped calls may add `project_context` alongside the envelope.
198
+
140
199
  **Bulk create** (`POST /issues/bulk`):
141
200
  ```json
142
201
  { "issues": [{ "title": "Task 1", "status": "todo", "priority": 1, "projectId": "..." }] }
@@ -166,6 +225,10 @@ Create org-wide agents with `{ "name": "...", "role": "member", "setupScoped": f
166
225
 
167
226
  Key-minting agent creation responses contain the one-time raw `apiKey` and its stable `apiKeyId`. Creation with `oauthOnly: true` omits both fields.
168
227
 
228
+ Manageable-agent rows always include nullable `key_prefix`, `last_used_at`, and `activity_last_used_at`. `key_prefix` and `last_used_at` describe only the selected active API key. `activity_last_used_at` is the latest timestamp from an active API key or a non-revoked OAuth agent profile. Historical OAuth use is not backfilled.
229
+
230
+ Workforce read rows from `GET /api/orgs/{id}/agents/workforce` contain bounded identity fields, safe `projects` summaries, `project_ids`, `created_at`, nullable aggregated `last_used_at`, nullable personal-agent `owner` display metadata, `scope` (`personal`, `project`, or `organization`), and `capabilities` with `can_view`, `can_manage_access`, `can_manage_keys`, `can_disable`, and `can_revoke` booleans. Project-admin visibility sets only `can_view` unless an existing creator/personal-owner management rule independently grants more. `key_prefix` is optional and is returned only when existing key-management authority allows it. The response never includes emails, auth IDs, hidden projects, credentials, OAuth grants, prompts, raw activity, lifecycle fields, or organization capacity.
231
+
169
232
  ## Agent Heartbeat Policy Fields
170
233
 
171
234
  Heartbeat policy replacement uses a complete object with `sections` booleans for `goals`, `standalone_kpis`, `standalone_initiatives`, `assigned_issues`, `project_context`, `signals`, and `attention`; `signal_categories` booleans for `task`, `initiative`, `kpi`, and `project`; `project_ids`; `initiative_ids`; and `columns` entries shaped as `{ "project_id": "...", "column_id": "..." }`. Empty focus arrays mean all. Policy fields narrow proactive attention and never grant access. Management `saved_policy` retains stale IDs so saved previews and real heartbeats fail closed; `effective_policy` is the sanitized editable form, `stale_selections` reports removals, and saving it clears stale restrictions. Manageable-agent list rows include visible `project_ids`, named `accessible_projects`, and `heartbeat_policy_summary.{status,focus_summary}`.
@@ -236,6 +299,12 @@ Calculated KPIs do not accept manual snapshots.
236
299
 
237
300
  `api_poll` snapshots are written by published KPI HTTP Syncs and include provenance: `source_sync_id`, `source_sync_run_id`, `source_config_hash`, `source_recorded_for`, `observed_at`, and optional `provider_recorded_at`.
238
301
 
302
+ Snapshot list/create responses keep an explicit legacy projection. Use
303
+ `projection=provenance_v1` on the list route to add nullable
304
+ `source_window_start` and `source_window_end` calendar dates. Before the
305
+ source-window migration is active, both opt-in fields are `null`. Existing
306
+ clients and snapshot-create responses do not receive the added fields.
307
+
239
308
  ## KPI detail relationship fields
240
309
 
241
310
  KPI detail includes `initiative_impacts` for initiatives visible to the caller
@@ -403,8 +472,31 @@ multiple exact-name milestones already exist, upsert returns a structured
403
472
  }
404
473
  ```
405
474
 
475
+ Supported action values are: `set_status` (lowercase status key using letters,
476
+ digits, and underscores), `set_assignee` (member UUID or `null`),
477
+ `set_priority` (integer `0` through `3`), `add_label` (label UUID),
478
+ `post_comment` (non-empty text), and `close_issue` (no value or `null`).
479
+ Unsupported action types or malformed values return `400` and are not saved.
480
+
406
481
  **Dry-run test**: Send `{ "issue_id": "uuid" }` or `{ "issue": { "status": "todo", "priority": 2 } }`. Returns `{ matched, actions_that_would_run }`.
407
482
 
483
+ **Automation run history**: `GET /api/orgs/{id}/automation-rules/{ruleId}/activity`
484
+ returns `{ runs }` to owner/admin members, newest first and limited to the
485
+ latest 100 runs. Each run contains its status,
486
+ timestamps, safe error fields, a safe source-event projection, and ordered
487
+ `automation_action_runs` for actions that were actually attempted. Non-matching
488
+ events, dry runs, and rules with no executable actions create no run row. The
489
+ response excludes event payloads, action inputs, request headers, credentials,
490
+ and third-party response bodies.
491
+
492
+ If a definitive action-audit start fails after an earlier action, the run is
493
+ terminal with safe `error_code: "automation_execution_partial"` and message
494
+ `automation execution stopped after one or more earlier actions`; earlier
495
+ action evidence is not replayed. Deleting a rule or its project preserves the
496
+ run and action rows with the original rule UUID as an immutable snapshot, so
497
+ authorized Activity lookup remains possible. Deleting the organization may
498
+ remove its organization-owned history.
499
+
408
500
  ## Custom View Fields
409
501
 
410
502
  ```json
@@ -423,9 +515,12 @@ multiple exact-name milestones already exist, upsert returns a structured
423
515
  ## Board Column Mutation Fields
424
516
 
425
517
  Delete a board column with
426
- `DELETE .../board-columns/{columnId}?reassignTo={targetColumnId}`. The target is
427
- required when the source column contains issues and must belong to the same
428
- project; reassignment and deletion are atomic.
518
+ `DELETE .../board-columns/{columnId}?reassignTo={targetColumnId}&releaseReassignTo={releaseTargetColumnId}`.
519
+ `reassignTo` is required when the source column contains issues and
520
+ `releaseReassignTo` is required when it has dependency release references;
521
+ the targets are independent, must belong to the same project, and reassignment
522
+ and deletion are atomic. The board-column list reports `issue_count` and
523
+ `release_reference_count` so clients can fail closed before deletion.
429
524
  The final board column cannot be deleted. Reorder with
430
525
  `{ "columns": [{ "id": "column-uuid", "position": 0 }] }` and include the
431
526
  complete current column set. Duplicate, missing, partial, or mixed-project IDs
@@ -629,7 +724,7 @@ Proposal JSON currently supports at most one item in each collection: `projects`
629
724
 
630
725
  Heartbeat is org-scoped, but project-bound goals, KPIs, initiatives, issue health, milestone signals, assigned work, and `project_context` are filtered by the caller's project access. Project-scoped guests receive every explicitly accessible board while idle; personal agents retain relevant inherited-project context. Non-guest members can also see unprojected org-level strategy. Shared initiatives can appear with counts and signals based only on accessible work.
631
726
 
632
- Heartbeat also includes `attention_items` for direct current-member notifications such as mentions, assignments, direct replies, assignee comments, and creator-visible status changes. Each attention item includes `id`, `source`, `event_type`, `severity`, `action_kind`, resource fields, `comment_id`, `reply_to_comment_id`, optional validated parent `routing`, `target_path`, `created_at`, and `ack_endpoint`; after handling the referenced item, call `ack_endpoint` so the notification is acknowledged and removed from later heartbeat attention results. `attention_summary` includes counts such as `mentions`, `assignments`, `blockers`, and `total_unread`.
727
+ Heartbeat also includes `attention_items` for direct current-member notifications such as mentions, assignments, direct replies, assignee comments, and creator-visible status changes. Authorized REST and CLI heartbeat calls can also include `verification.completed`; the public MCP heartbeat excludes this private event type. Verification items include a validated `verification` object with bounded repository, PR, workflow, run attempt, head SHA, conclusion, canonical run URL, and `next_action` fields. They contain no raw payloads, secrets, logs, or thread identifiers. Each attention item includes `id`, `source`, `event_type`, `severity`, `action_kind`, resource fields, `comment_id`, `reply_to_comment_id`, optional validated parent `routing`, `target_path`, `created_at`, and `ack_endpoint`; after handling the referenced item, call `ack_endpoint` so the notification is acknowledged and removed from later heartbeat attention results. `attention_summary` includes counts such as `mentions`, `assignments`, `blockers`, and `total_unread`.
633
728
 
634
729
  Current-member notifications can use `event_type` values such as `mention.created`, `issue.assigned`, `comment.added`, and `issue.status_changed`. Notification preferences use `event_type`, `channel` (`in_app` or `google_chat`), and `enabled` for current-member delivery preferences. The single Google Chat preference is stored under `mention.created` and controls mentions, assignments, and direct-reply comments; ordinary comments and status changes are excluded. Setting `enabled: false` for `google_chat` stops future Chat delivery without acknowledging in-app notifications. Setting `enabled: false` for in-app `mention.created` also attempts to acknowledge that member's currently unread mention notifications; when cleanup succeeds, they no longer appear in notification lists or heartbeat `attention_items`. New direct-message installations receive a welcome before configuration. Classic Chat interaction apps link humans through a short-lived `REQUEST_CONFIG` session after `connect`; Workspace add-ons use `basic_authorization_prompt`. Both flows retain display-safe Chat identity fields and memberships owned by the signed-in human. Add-on callbacks require the endpoint URL audience and exact per-project add-on service account email; classic callbacks continue to trust Google's Chat service account and can use a project-number audience. Connect-session and member endpoints require a human web session; a one-time `connect <token>` command remains a manual fallback.
635
730
 
@@ -671,6 +766,22 @@ Each finding carries whichever entity ids apply: `goal_id`, `kpi_id`, `initiativ
671
766
  - Initiative health: `initiative_missing_impact`, `initiative_missing_execution`, `initiative_stalled`, `initiative_target_missing_execution`, `initiative_target_overdue`, `initiative_target_blocked`
672
767
  - Execution: `issue_blocked`, `issue_overdue`, `milestone_overdue`
673
768
 
769
+ ## Artifact Fields
770
+
771
+ Artifacts contain `id`, `org_id`, `type`, `title`, `current_revision_id`,
772
+ `created_by`, `created_at`, and `updated_at`. Artifact links contain `id`,
773
+ `artifact_id`, canonical `artifact_type`, `target_type` (`issue` or `project`), `target_id`, `created_by`,
774
+ and `created_at`. Revisions contain `id`, `artifact_id`, `revision_number`, immutable `title_snapshot`,
775
+ `content_format`, `content_digest`, `created_by`, and `created_at`; the full
776
+ revision endpoint also returns sanitized `content`. Revision summaries never
777
+ return content. Content formats are `markdown` and `html`; both are stored as
778
+ sanitized HTML. Titles are limited to 200 UTF-8 bytes and revisions to 256 KiB.
779
+ If a member is deleted, creator provenance is retained as `null`.
780
+ The opt-in issue manifest contains only `id`, `type`, `title`,
781
+ `current_revision_id`, `created_at`, and `updated_at`. Issue PRD and
782
+ Implementation Plan links are limited to one slot per issue, and each such
783
+ Artifact can be authoritative for only one issue.
784
+
674
785
  ## Analytics Response
675
786
 
676
787
  ```json
@@ -690,12 +801,14 @@ Each finding carries whichever entity ids apply: `goal_id`, `kpi_id`, `initiativ
690
801
  |--------|-------|--------|
691
802
  | Task | `status` | Project-defined stored board-column key matching `^[a-z0-9_]+$`; defaults are `backlog`, `todo`, `in_progress`, `done`, with system status `cancelled` |
692
803
  | Board column | `description` | Optional stage criteria or agent guidance |
804
+ | Board column | `recommendationRole` / `recommendation_role` | Nullable workflow role request field: `candidate`, `active`, or `excluded`; both aliases must match when both are present. Responses use `recommendation_role`; `null` means unconfigured and not eligible for future recommendations. |
693
805
  | Task | `priority` | `0` (urgent), `1` (high), `2` (medium), `3` (low) |
694
806
  | Task update request | `comment_body` | Optional Markdown/plain text or rich-text HTML comment body created with the issue update; stored and returned as sanitized HTML |
695
807
  | Task update request | `comment_mentions[].member_id` | Stable Atoll org member ID to mention in the issue update comment created by `comment_body`; not an auth user ID or display name |
696
808
  | Task update request | `comment_source_metadata` | Optional explicit agent provenance using the same validated shape as direct comment `source_metadata` |
697
809
  | Comment create request | `reply_to_comment_id` | Optional comment ID that this flat, one-level reply addresses; target must be an active comment on the same task |
698
810
  | Comment create request | `source_metadata` | Optional agent-only routing object: `harness`, real `thread_id` and/or `session_id`, optional `host_id`; omit it when the host lacks a real identifier, and never invent one |
811
+ | Comment response | `author_type` | `human`, `agent`, or `automation`; automation comments have null `author_id` and null comment routing `source_metadata` |
699
812
  | Comment response | `reply_to_comment` | Parent context including `id`, `body`, `author_type`, and routing-safe `source_metadata` |
700
813
  | Comment list response | `comments[].mentioned_members[]` | Persisted mention recipient summary with `id`, nullable `display_name`, and nullable `type`; empty when no mentions are recorded |
701
814
  | Comment create request | `mentions[].member_id` | Stable Atoll org member ID to mention in a direct comment API request; recommended for agents and integrations |
@@ -744,6 +857,72 @@ Storage bucket and path fields are intentionally not returned. Project-scoped
744
857
  reads require project access; upload and delete require `edit` or `admin`.
745
858
  Guests cannot access attachments on unprojected issues.
746
859
 
860
+ ## Dependencies
861
+
862
+ Dependency creation requires the blocking issue to belong to a project because
863
+ the persistent release point is a board column there. A projectless issue may
864
+ be the blocked target when the caller has permission to use it.
865
+
866
+ `GET /api/orgs/{id}/issues/{issueId}/dependencies` returns `blocking` and
867
+ `blockedBy` arrays. Each dependency includes:
868
+
869
+ | Response field | Type | Notes |
870
+ |---|---|---|
871
+ | `id` | UUID | Dependency identifier |
872
+ | `issue` | object or null | Authorized target projection with `id`, `number`, `identifier`, `projectSlug`, `title`, and `status`; inaccessible targets are `null` |
873
+ | `issue.identifier` | string or null | Canonical project-prefixed issue reference for navigation; `null` for projectless targets |
874
+ | `issue.projectSlug` | string or null | Collision-free project route segment; `null` for projectless targets |
875
+ | `createdAt` | timestamp | Dependency creation time |
876
+ | `releaseColumnId` | UUID | Persistent release column in the blocking issue's project; present when the blocking issue is authorized |
877
+ | `release_column_id` | UUID | Compatibility alias for `releaseColumnId`; present with the canonical field |
878
+ | `releaseColumn` | object or null | `{ id, key, label, position, projectId }` release column projection |
879
+ | `satisfied` | boolean or null | Whether the blocker reached the release column position, or is cancelled |
880
+
881
+ The dependency-release migration backfills existing dependencies to the
882
+ blocking project's `done` column. During a rolling deployment, compatibility
883
+ reads may omit release fields from older rows; treat missing release metadata as
884
+ the legacy open-blocker behavior until the migration is applied.
885
+
886
+ ## External References
887
+
888
+ External-reference response items contain `link_id`, `id`, `org_id`,
889
+ `target_type` (`issue` or `project`), `target_id`, `provider`, `object_type`,
890
+ `provider_object_id`, `provider_container_id`, `canonical_url`, bounded
891
+ `display_metadata`, `provenance`, `resolvable`, `resolution_error`,
892
+ `last_observed_at`, `created_at`, `updated_at`, and `linked_at`. The REST POST
893
+ request accepts `url` plus optional `provider: "github"` and
894
+ `object_type: "pull_request"`; provider identity fields are not caller
895
+ inputs. GitHub links require numeric immutable IDs from the authorized live
896
+ provider response or return `422` with
897
+ `code: "github_identity_unavailable"`. Link and unlink writes emit the
898
+ metadata-only Activity actions `external_reference.linked`,
899
+ `external_reference.updated`, or `external_reference.unlinked`.
900
+
901
+ ## Task Activity
902
+
903
+ `GET /api/orgs/{id}/activity` returns `{ data, currentMemberId, limit, offset,
904
+ hasMore }` and accepts `filter=all|by_me|mine`. `GET
905
+ /api/orgs/{id}/issues/{issueId}/activity` returns `{ data, items, limit, offset,
906
+ hasMore }`. Items retain the `activity_events` fields. Top-level `actor` is a
907
+ current member projection and can reflect later profile changes; the immutable
908
+ event-time actor snapshot is `metadata.actor` with `id`, `display_name`, `type`,
909
+ and `avatar_url`. The
910
+ canonical actions cover task lifecycle, comments, assignees, labels,
911
+ dependencies, initiative/target links, GitHub PR links and updates, attachments,
912
+ and subtasks. Notification, webhook, realtime, and delivery records are excluded.
913
+ The exact canonical `action` values are `issue.created`, `issue.updated`,
914
+ `issue.archived`, `issue.unarchived`, `comment.created`, `comment.updated`,
915
+ `comment.deleted`, `assignee.added`, `assignee.removed`, `label.added`,
916
+ `label.removed`, `dependency.added`, `dependency.removed`, `dependency.release_updated`,
917
+ `initiative.linked`, `initiative.unlinked`, `initiative_target.linked`,
918
+ `initiative_target.unlinked`, `github_pr.linked`, `github_pr.updated`,
919
+ `attachment.added`, `attachment.removed`, `subtask.created`,
920
+ `subtask.completed`, `subtask.reopened`, `subtask.removed`, `subtask.updated`,
921
+ `external_reference.linked`, `external_reference.updated`, and
922
+ `external_reference.unlinked`.
923
+ Use `limit` in `1..100` and a non-negative `offset`; older history may be
924
+ partial because pre-contract events are not fabricated or backfilled.
925
+
747
926
  ## Response Format
748
927
 
749
928
  Most endpoints return JSON; attachment content returns binary bytes. Successful: