@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.
- package/README.md +22 -8
- package/bin/install.mjs +179 -43
- package/package.json +1 -1
- package/skill/SKILL.md +263 -5
- package/skill/agents/openai.yaml +11 -0
- package/skill/references/api-endpoints.md +118 -17
- package/skill/references/api-fields.md +184 -5
|
@@ -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=...` |
|
|
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
|
|
307
|
-
|
|
308
|
-
|
|
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? }`);
|
|
322
|
-
| DELETE | `.../initiatives/{id}/kpi-impacts/{impactId}` | Remove link;
|
|
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` |
|
|
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
|
|
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
|
|
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/
|
|
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
|
|
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}`.
|
|
427
|
-
required when the source column contains issues and
|
|
428
|
-
|
|
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:
|