@atollhq/skill-codex 0.4.34 → 0.4.36

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atollhq/skill-codex",
3
- "version": "0.4.34",
3
+ "version": "0.4.36",
4
4
  "description": "Install the Atoll project management integration for Codex CLI",
5
5
  "bin": {
6
6
  "skill-codex": "bin/install.mjs"
package/skill/SKILL.md CHANGED
@@ -12,6 +12,15 @@ clients, use the connected Atoll tools; do not assume a shell, installed CLI,
12
12
  local profile, or API key. In CLI environments, prefer the typed Atoll CLI.
13
13
  Live tool schemas, CLI help, and linked references define the contract.
14
14
 
15
+ Heartbeat is compact by default for REST and private CLI/MCP calls. Read the
16
+ strategy and heartbeat reference for bounded pages, terminal acknowledgement,
17
+ delta cursors, grouped dependency blockers, and the explicit `--full`/`view=full`
18
+ legacy response. The public plugin MCP heartbeat remains legacy full mode. If a
19
+ requested `max_bytes` cannot fit the mandatory actionable record and compact
20
+ envelope, REST returns `413 heartbeat_budget_too_small` without advancing a page
21
+ cursor or terminal receipt; retry with a larger budget or the 16 KiB default.
22
+ Dependency-chain cursors are signed and revision-bound; graph drift returns `409 Stale dependency chain cursor`, so restart without the cursor.
23
+
15
24
  ## Route to the relevant reference
16
25
 
17
26
  Read only the references required for the current task:
@@ -213,6 +213,7 @@ bodies, projects only declared public issue fields, preserves nullable
213
213
  | Method | Endpoint | Description |
214
214
  |--------|----------|-------------|
215
215
  | GET | `/api/orgs/{id}/issues/{issueId}/dependencies` | List dependencies (`{ blocking, blockedBy }`) |
216
+ | GET | `/api/orgs/{id}/issues/{issueId}/dependencies?view=chain` | Read a bounded normalized dependency chain |
216
217
  | POST | `/api/orgs/{id}/issues/{issueId}/dependencies` | Add dependency |
217
218
  | PATCH | `/api/orgs/{id}/issues/{issueId}/dependencies/{depId}` | Change dependency release point |
218
219
  | DELETE | `/api/orgs/{id}/issues/{issueId}/dependencies/{depId}` | Remove dependency |
@@ -226,6 +227,19 @@ blocking project's `done` column. During a rolling deployment, compatibility
226
227
  reads may omit release fields from older rows; treat missing release metadata as
227
228
  the legacy open-blocker behavior until the migration is applied.
228
229
 
230
+ For `view=chain`, use `direction=upstream|downstream|both` (default
231
+ `both`), `depth` (default `2`, maximum `5`), `limit` (default `50`), and
232
+ the opaque `cursor`. The response normalizes readable nodes and edges, includes
233
+ release-condition satisfaction and permission flags, and returns readable node
234
+ `assignee_id`, nullable `due_date`, nullable `ready_if_released`, and readiness.
235
+ It returns opaque restricted node tokens with `readiness: "unknown"` when an
236
+ issue is not readable. The top-level `partial` is true when the depth bound, restricted nodes, or unknown readiness
237
+ prevent a complete graph. The response is read-only and can
238
+ be truncated; follow `page.next_cursor` only when present. Chain cursors are
239
+ signed and bound to the current graph revision and caller scope. Graph changes
240
+ while paging return `409 Stale dependency chain cursor`; restart without the
241
+ cursor.
242
+
229
243
  ## Comments
230
244
 
231
245
  | Method | Endpoint | Description |
@@ -467,13 +481,46 @@ The create body is strict and requires `execution_id`, `expected_state_version`,
467
481
 
468
482
  | Method | Endpoint | Description |
469
483
  |--------|----------|-------------|
470
- | GET | `/api/orgs/{id}/heartbeat` | Get heartbeat context for the authenticated agent |
484
+ | GET | `/api/orgs/{id}/heartbeat` | Get compact heartbeat context by default; use `?view=full` for the legacy full response |
485
+ | POST | `/api/orgs/{id}/heartbeat/ack` | Acknowledge a terminal compact heartbeat page with `{ "ack_cursor": "..." }` |
471
486
  | GET | `/api/orgs/{id}/agents/{agentId}/heartbeat-policy` | Human-only manageable-agent policy, selectable scope, and stale selections |
472
487
  | PUT | `/api/orgs/{id}/agents/{agentId}/heartbeat-policy` | Human-only complete atomic policy replacement |
473
488
  | DELETE | `/api/orgs/{id}/agents/{agentId}/heartbeat-policy` | Human-only reset to default heartbeat behavior |
474
489
  | POST | `/api/orgs/{id}/agents/{agentId}/heartbeat-preview` | Human-only saved/draft preview composed as the target agent without persistence |
475
490
 
476
- Returns computed briefing with goal status, KPI pace/trend, initiative progress, assigned work, direct `attention_items`, `attention_summary`, signals, and a deterministic `recommended_action` when Atoll can propose one concrete strategy-backed next action. The endpoint is org-scoped, but project-bound payload details 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, and shared initiatives can appear with counts and signals based only on accessible work.
491
+ REST and private CLI/MCP calls return compact delivery by default: grouped
492
+ actionable signals, bounded attention, counts, delta, and a page descriptor.
493
+ The page is limited to 25 groups and 16,384 UTF-8 bytes. A page with
494
+ `has_more: true` returns `next_cursor`; only the terminal page returns an
495
+ `ack_cursor`. Acknowledge that cursor with the POST endpoint before using it as
496
+ `since`. Cursor or baseline conflicts return `409`; an expired acknowledged
497
+ baseline sets `delta.reset_required: true`. If the requested `max_bytes` cannot fit the
498
+ mandatory actionable record and compact response envelope, the server returns
499
+ `413` with `code: "heartbeat_budget_too_small"` and does not advance a page
500
+ cursor or terminal receipt. Retry with a larger `max_bytes` or omit it for the
501
+ 16,384-byte default. Use `?view=full` for the full
502
+ briefing with goals, KPI pace/trend, initiatives, assigned work, project
503
+ context, attention, signals, and recommendation. Full mode cannot use
504
+ `since` or cursor pagination.
505
+
506
+ Cursors are opaque, server-issued, and single-use in sequence. Pass the exact
507
+ `next_cursor` from the immediately previous page. Do not manufacture, skip, or
508
+ replay a page cursor.
509
+
510
+ Expected waits are suppressed for an unsatisfied dependency when the readable
511
+ blocker is before its release column and there is no active stall, threatened or
512
+ overdue commitment, or explicit deadline, gate, permission, or stale anomaly.
513
+ An unowned backlog or Todo blocker by itself is an ordinary wait and never
514
+ alerts. Actionable groups surface active stalls, threatened or overdue
515
+ commitments, and explicit anomalies; escalation metadata alone does not surface
516
+ an expected wait. When every dependency fact behind an initiative-target or
517
+ stalled aggregate is an expected wait, that aggregate is suppressed too. Dependency blockers are grouped
518
+ by root blocker and release condition, with bounded normalized-chain facts and
519
+ `suggested_read` calls when additional read-only evidence is needed. The endpoint is org-scoped, but all
520
+ project-bound details remain filtered by caller project access. Public plugin
521
+ MCP heartbeat remains legacy full mode and does not expose compact ack or chain
522
+ tools; private MCP exposes compact heartbeat, `atoll_ack_heartbeat`, and
523
+ `atoll_get_dependency_chain`.
477
524
 
478
525
  An authorized human may save a per-agent attention policy for context sections, semantic signal categories, accessible projects, visible initiatives, and stable per-project board-column IDs. The API applies it before CLI/MCP severity or signals-only narrowing. Policies never broaden project access; assigned work and direct attention remain independent of generated-signal focus.
479
526
 
@@ -823,6 +823,53 @@ Proposal JSON currently supports at most one item in each collection: `projects`
823
823
 
824
824
  ## Heartbeat Response
825
825
 
826
+ `GET /api/orgs/{id}/heartbeat` returns compact delivery by default for REST
827
+ and private CLI/MCP callers. Compact responses contain `mode: "compact"`,
828
+ `agent`, `timestamp`, `attention_items`, `attention_summary`, grouped `signals`, `recommended_action`,
829
+ `counts`, `delta`, and `page`. Full legacy context is available only with
830
+ `view=full` (or the CLI `--full` flag).
831
+
832
+ ### Compact heartbeat fields
833
+
834
+ | Field | Notes |
835
+ |---|---|
836
+ | `signals[]` | Grouped actionable signal or dependency-blocker groups. Each group has `key`, `revision`, `severity`, `kind`, `action_reason`, root and impact counts, readiness, bounded `evidence`, and optional `suggested_read`. |
837
+ | `attention_items` | Bounded direct attention projections with required `id`, `event_type`, `severity`, `title`, `resource_type`, and `ack_endpoint`; optional `resource_id` is included when present. |
838
+ | `attention_summary` | Counts for included direct attention items. |
839
+ | `counts` | `actionable_groups`, severity counts, `direct_blocked`, `downstream_blocked`, `ready_if_released`, `unknown_readiness`, `restricted`, and `suppressed_expected_waits`. |
840
+ | `delta` | `since`, `new_count`, `changed_count`, `escalated_count`, `ready_count`, suppression counts, and `reset_required`. |
841
+ | `page` | Requested `max_bytes` (1,024-16,384) and `max_items` (1-25), returned counts/bytes, `has_more`, `next_cursor`, and terminal `ack_cursor`. |
842
+
843
+ Compact pages are deterministic and use opaque, server-issued cursors. Request
844
+ the next page with the exact `next_cursor` from the immediately previous page;
845
+ do not manufacture, skip, or replay a page cursor. Cursors are single-use in sequence. Acknowledge only the terminal `ack_cursor` using
846
+ `POST /api/orgs/{id}/heartbeat/ack`, then use that acknowledged cursor as
847
+ `since` on a later request. Invalid cursors return `400`; stale pages or an
848
+ unacknowledged `since` return `409`. An expired acknowledged baseline returns a
849
+ fresh compact response with `delta.reset_required: true`. If the requested
850
+ `max_bytes` cannot fit the mandatory actionable record and compact response
851
+ envelope, the route returns `413` with `code: "heartbeat_budget_too_small"`;
852
+ no page cursor or terminal receipt advances. Retry with a larger `max_bytes` or
853
+ omit it for the 16,384-byte default. Policy, authorization, or candidate
854
+ changes while paging invalidate the cursor.
855
+
856
+ Expected waits are suppressed for an unsatisfied dependency when the readable
857
+ blocker is before its release column and there is no active stall, threatened or
858
+ overdue commitment, or explicit deadline, gate, permission, or stale anomaly.
859
+ An unowned backlog or Todo blocker by itself is an ordinary wait and never
860
+ alerts. Actionable groups surface active stalls, threatened or overdue
861
+ commitments, and explicit anomalies; escalation metadata alone does not surface
862
+ an expected wait. Initiative-target and stalled aggregates are also suppressed
863
+ when every underlying dependency is an expected wait. Dependency blockers are grouped by
864
+ root and release condition. A dependency chain may
865
+ include readable nodes and edges, opaque restricted node tokens, readiness,
866
+ release-condition satisfaction, and explicit permission flags; unknown
867
+ readiness remains unknown. Suggested reads are safe GET/CLI/private-MCP calls.
868
+
869
+ The public plugin MCP heartbeat keeps its legacy full response and does not
870
+ expose compact acknowledgement or dependency-chain tools. Private MCP supports
871
+ compact heartbeat, `atoll_ack_heartbeat`, and `atoll_get_dependency_chain`.
872
+
826
873
  ```json
827
874
  {
828
875
  "agent": { "id": "...", "display_name": "Growth Agent" },
@@ -1144,6 +1191,26 @@ blocking project's `done` column. During a rolling deployment, compatibility
1144
1191
  reads may omit release fields from older rows; treat missing release metadata as
1145
1192
  the legacy open-blocker behavior until the migration is applied.
1146
1193
 
1194
+ ### Dependency chain fields
1195
+
1196
+ `GET /api/orgs/{id}/issues/{issueId}/dependencies?view=chain` returns a bounded
1197
+ normalized graph:
1198
+
1199
+ | Field | Notes |
1200
+ |---|---|
1201
+ | `root_issue_id` | Authorized root issue UUID. |
1202
+ | `direction` | `upstream`, `downstream`, or `both`; default `both`. |
1203
+ | `depth` | Traversal depth, default `2`, capped at `5`. |
1204
+ | `nodes[]` | Readable issue projections with readiness and dependency counts, or opaque restricted tokens with `readiness: "unknown"` and `permissions.read: false`. |
1205
+ | `edges[]` | Upstream/downstream node IDs, permission flags, optional `release_condition`, `satisfied`, and reason (`release_reached`, `release_not_reached`, or `readiness_unknown`). |
1206
+ | `counts` | Returned/known nodes and edges, direction counts, readiness counts, restricted nodes, and unsatisfied release conditions. |
1207
+ | `page` | `limit`, `truncated`, and opaque `next_cursor`. |
1208
+
1209
+ The chain is read-only. Use `limit` and `cursor` for bounded traversal; do not
1210
+ infer restricted issue identity from the token. Chain cursors are signed,
1211
+ opaque, and bound to the current graph revision, root, direction, depth, limit,
1212
+ and caller scope. If the graph changes while paging, the route returns `409 Stale dependency chain cursor`; restart without `cursor`.
1213
+
1147
1214
  ## External References
1148
1215
 
1149
1216
  External-reference response items contain `link_id`, `id`, `org_id`,
@@ -47,6 +47,10 @@ atoll heartbeat
47
47
  atoll heartbeat --signals-only
48
48
  atoll heartbeat --severity critical
49
49
  atoll heartbeat --json
50
+ atoll heartbeat --full --json
51
+ atoll heartbeat --since <ack-cursor> --json
52
+ atoll heartbeat --cursor <page-cursor> --json
53
+ atoll heartbeat --ack <terminal-ack-cursor> --json
50
54
  atoll agent-context
51
55
 
52
56
  # List tasks
@@ -117,6 +121,7 @@ atoll api get /api/orgs/$ATOLL_ORG_ID/labels --json
117
121
 
118
122
  # Dependencies
119
123
  atoll dependency bulk-add --file ./dependencies.json --continue-on-error
124
+ atoll dependency chain ATOLL-42 --direction downstream --depth 2 --json
120
125
 
121
126
  Dependency reads include a target issue `identifier` and `projectSlug` when the target belongs to a project. Inaccessible targets remain `issue: null`; projectless targets have both fields set to `null`.
122
127
  Dependencies persist a release point in the blocking project's ordered board columns. Add `releaseColumnId` when creating an edge, or omit it to default to that project's `done` column. Use the dependency API PATCH route to change the release point; reads include `releaseColumnId`, `releaseColumn`, and `satisfied`.
@@ -132,6 +137,14 @@ snake_case consumers need it; POST and PATCH accept either `releaseColumnId` or
132
137
  `release_column_id`. When deleting a board column, migrate issue
133
138
  statuses and dependency release references with separate explicit targets.
134
139
 
140
+ `atoll dependency chain <identifier>` reads a bounded normalized dependency
141
+ graph. Use `--direction upstream|downstream|both` (default `both`),
142
+ `--depth` (default `2`, maximum `5`), `--limit`, and `--cursor`. Readable nodes
143
+ include readiness and release-condition state. Restricted nodes use opaque
144
+ tokens and `readiness: "unknown"`; never infer their issue identity. The cursor
145
+ is signed and revision-bound; graph changes while paging return `409 Stale
146
+ dependency chain cursor`, so restart without the cursor.
147
+
135
148
  # Graph plans
136
149
  atoll plan validate --file ./plan.json
137
150
  atoll plan apply --file ./plan.json --dry-run
@@ -157,6 +170,7 @@ atoll goal create --title "Reach 100 paying customers by Q2" --target-date 2026-
157
170
  atoll kpi create --name paying_customers --goal "Reach 100 paying customers by Q2" --unit count --target 100 --current 34
158
171
  atoll kpi create --name mvp_tasks_done --goal "Launch MVP" --internal-task-completion
159
172
  atoll initiative create --title "Content pipeline" --goal "Reach 100 paying customers by Q2" --status active
173
+ atoll initiative delete "Content pipeline" --confirm DELETE
160
174
  atoll initiative kpi link "Content pipeline" paying_customers --impact "+30 customers/mo"
161
175
  atoll initiative target create "Content pipeline" --title "Publish 10 comparison posts" --mode progress --target 10 --current 0 --unit count --unit-label posts
162
176
  atoll initiative target create "Retailer coverage" --title "Get 5 retailers live by July 5" --mode gate --target 5 --current 0 --unit count --unit-label retailers --target-date 2026-07-05 --due-soon-days 7
@@ -183,7 +197,13 @@ CLI JSON conventions:
183
197
  - Interactive CLI update notices also go to stderr and are suppressed for JSON/non-TTY/CI/completion flows.
184
198
  - `atoll agent-context` returns a versioned command/flag manifest, available profile context, and structured `cli.update_available` metadata.
185
199
  - Weekly issue recurrence accepts unique selected weekdays with `--recurrence weekly --recurrence-days mon,wed,fri --recurrence-mode schedule --recurrence-time 09:00 --recurrence-timezone Asia/Singapore`. Read JSON exposes normalized `recurrence_days` and `recurrence_schedule`; unrelated updates preserve the schedule. Scheduled recurrence intervals are limited to `10000`. Use `--recurrence-mode schedule` with `--recurrence-time HH:MM` and `--recurrence-timezone IANA/Zone` to create the next task from the maintenance sweep while the current task remains open; `completion` remains the default and can retain larger positive intervals.
186
- - `atoll heartbeat --json` includes the same structured `cli` update metadata for agents, plus `attention_items`, `attention_summary`, and `recommended_action` when Atoll can propose one concrete strategy-backed next action. `atoll heartbeat --signals-only --json` preserves filtered `signals`, `attention_items`, `attention_summary`, and `recommended_action` for short polling. Handle direct attention items first, then call each handled item's `ack_endpoint`. Follow `recommended_action.usage_guidance`: prefer `suggested_write.operation` when it still matches the board, preserve KPI/initiative/initiative_target/why-now/expected-impact/first-step/success-criteria evidence, and avoid copying deferred busywork into issue or comment payloads. If a `start_work` recommendation uses `issue.update` with a body, update the issue status and preserve that body as an issue comment; `PATCH /issues/{issueId}` accepts `comment_body` for this same-request progress note.
200
+ - `atoll heartbeat` uses compact delivery by default. Compact JSON is bounded to 25 signal groups and 16,384 UTF-8 bytes, with `counts`, `delta`, and `page`. Follow `page.next_cursor` until the terminal page, then acknowledge its `page.ack_cursor` with `atoll heartbeat --ack <cursor> --json`. Use an acknowledged cursor with `--since`; invalid or stale cursors return an error, and an expired baseline sets `delta.reset_required: true`. If a requested REST
201
+ `max_bytes` cannot fit the mandatory actionable record and compact response
202
+ envelope, the API returns `413 heartbeat_budget_too_small` without advancing a
203
+ page cursor or terminal receipt; retry with a larger budget or the 16 KiB
204
+ default. Use `--full` for the legacy full context; full mode cannot combine with `--since` or `--cursor`.
205
+ - Compact signal groups include dependency blockers grouped by root blocker and release condition. Expected waits are suppressed for an unsatisfied dependency when the readable blocker is before its release column and there is no active stall, threatened or overdue commitment, or explicit deadline, gate, permission, or stale anomaly. An unowned backlog or Todo blocker by itself is an ordinary wait and never alerts. Actionable groups surface active stalls, threatened or overdue commitments, and explicit anomalies; escalation metadata alone does not surface an expected wait. Initiative-target and stalled aggregates are also suppressed when every underlying dependency is an expected wait. Groups can include a bounded `suggested_read` REST, CLI, or private-MCP call. Public plugin MCP keeps legacy full heartbeat behavior; private MCP supports compact heartbeat, `atoll_ack_heartbeat`, and `atoll_get_dependency_chain`.
206
+ - `atoll heartbeat --json` includes the structured `cli` update metadata for agents, plus direct `attention`/`attention_items` and `recommended_action` when Atoll can propose one concrete strategy-backed next action. Handle direct attention items first, then call each handled item's `ack_endpoint`. Follow `recommended_action.usage_guidance`: prefer `suggested_write.operation` when it still matches the board, preserve KPI/initiative/initiative_target/why-now/expected-impact/first-step/success-criteria evidence, and avoid copying deferred busywork into issue or comment payloads. If a `start_work` recommendation uses `issue.update` with a body, update the issue status and preserve that body as an issue comment; `PATCH /issues/{issueId}` accepts `comment_body` for this same-request progress note.
187
207
  - Authorized humans can configure an agent's included heartbeat sections and generated-signal focus in the Atoll **Heartbeats** UI. The saved policy is applied by the API before CLI or MCP request-level narrowing; it never changes project access, and existing heartbeat commands require no new arguments.
188
208
  - GitHub `workflow_run` signals are accepted only when HMAC-signed and completed, then reread and matched exactly by repository, PR, workflow path, run attempt, and head SHA. Workflow verification is disabled by default and observe-only until an owner/admin enables it in **Settings > Integrations > GitHub**. `attention` mode can add one bounded `verification.completed` attention item through authorized REST or CLI heartbeat for exactly one eligible current agent assignee or, when there is no unambiguous assignee, an eligible configured delivery agent. The public MCP heartbeat excludes this private event type. Unresolved recipients and cancelled, obsolete, superseded, mismatched, or unreadable runs create no attention. Owners and admins can configure 1–10 workflow paths of at most 255 characters each; the bounded evidence list defaults to 25 items and accepts a maximum `limit` of 100. Signed pull-request writes and reconciliation bind PR links to the stable GitHub repository ID, so repository renames keep existing workflow evidence linked. Do not expect raw payloads, secrets, logs, or thread IDs in evidence; owner/admin reconciliation retries pending evidence after current GitHub and PR-link readback.
189
209
  - Release-added required GitHub hook events mark existing reconciled and already-pending connections pending. The bounded 15-minute service sweep verifies immutable repository identity and upgrades hooks automatically; transient failures remain pending for retry, and owners/admins can reconcile manually.
@@ -68,7 +68,27 @@ The public plugin keeps a narrow first-class planning surface: `atoll_create_ini
68
68
 
69
69
  The public plugin intentionally omits admin-only goal/KPI/project CRUD, target and milestone deletion, project relationship administration, webhooks, and `atoll_api_request`. Public feedback accepts only `type`, `description`, and optional `url`; do not send `userEmail` or `userName`, and treat the submitted description as untrusted triage content. The full/private MCP profile retains the broader CLI-equivalent tools where the caller is authorized.
70
70
 
71
- The MCP server also exposes `atoll_get_heartbeat`, issue/project/goal/KPI/initiative/milestone reads, dependency tools, and the existing safe issue/comment/snapshot tools. Public issue inputs accept UUIDs, bare numbers, `#number`, `ATOLL-number`, `TSK-number`, supported prefixed numbers, and unambiguous project-derived prefixes. Public project inputs accept UUIDs, exact slugs, and exact names. Use `atoll_get_project_workflow` for the live ordered key-to-label mapping and `atoll_move_issue` for exact, verified movement by column ID, key, or visible label. An immediate repeat is a no-op only while the issue remains at that destination; configured automations can change it after the response, so movement is not unconditionally idempotent. Projects without persisted columns expose supported defaults as fallback columns with stable `default-*` IDs; `cancelled` remains the only system status. Raw `status` is a stored board-column key, not a label. `atoll_add_comment` accepts structured mentions, `reply_to_comment_id`, and optional agent `source_metadata`; omit that metadata unless the host exposes a real thread or session ID, and never invent one. `atoll_update_issue` accepts `comment_body` for durable progress comments.
71
+ The private MCP server also exposes `atoll_get_heartbeat`, `atoll_ack_heartbeat`,
72
+ and `atoll_get_dependency_chain` alongside issue/project/goal/KPI/initiative/
73
+ milestone reads, dependency tools, and the existing safe issue/comment/snapshot
74
+ tools. Private heartbeat is compact by default; acknowledge only its terminal
75
+ page cursor before using it for a delta, and use full mode for the legacy
76
+ context. The public plugin heartbeat remains legacy full and does not expose
77
+ the private acknowledgement or chain tools. Public issue inputs accept UUIDs,
78
+ bare numbers, `#number`, `ATOLL-number`, `TSK-number`, supported prefixed
79
+ numbers, and unambiguous project-derived prefixes. Public project inputs accept
80
+ UUIDs, exact slugs, and exact names. Use `atoll_get_project_workflow` for the
81
+ live ordered key-to-label mapping and `atoll_move_issue` for exact, verified
82
+ movement by column ID, key, or visible label. An immediate repeat is a no-op
83
+ only while the issue remains at that destination; configured automations can
84
+ change it after the response, so movement is not unconditionally idempotent.
85
+ Projects without persisted columns expose supported defaults as fallback
86
+ columns with stable `default-*` IDs; `cancelled` remains the only system
87
+ status. Raw `status` is a stored board-column key, not a label.
88
+ `atoll_add_comment` accepts structured mentions, `reply_to_comment_id`, and
89
+ optional agent `source_metadata`; omit that metadata unless the host exposes a
90
+ real thread or session ID, and never invent one. `atoll_update_issue` accepts
91
+ `comment_body` for durable progress comments.
72
92
 
73
93
  Snapshot list/create outputs keep their strict legacy fields. Use the separate
74
94
  read-only MCP tool `atoll_list_kpi_snapshots_with_provenance` only when the
@@ -2,6 +2,67 @@
2
2
 
3
3
  Read this reference for goals, KPIs, initiatives, targets, heartbeat signals, autonomous prioritization, and strategy-linked execution workflows.
4
4
 
5
+ ## Compact heartbeat delivery
6
+
7
+ `GET /api/orgs/{id}/heartbeat` returns a compact response by default for REST
8
+ callers and private CLI/MCP callers. The compact response keeps direct
9
+ `attention_items`, grouped actionable `signals`, `recommended_action`,
10
+ `counts`, `delta`, and `page` metadata. It does not include the full goals,
11
+ KPI, initiative, assigned-issue, or board-context collections.
12
+
13
+ Compact responses are bounded to 16,384 UTF-8 bytes and 25 signal groups by
14
+ default. A response can contain a `next_cursor` when more groups remain. Read
15
+ that cursor with `cursor=<value>` and continue until `page.has_more` is false.
16
+ Only the terminal page contains `page.ack_cursor`.
17
+
18
+ Process every returned page before acknowledging it:
19
+
20
+ ```bash
21
+ page=$(atoll heartbeat --json)
22
+ # If .page.has_more is true, repeat with --cursor .page.next_cursor.
23
+ atoll heartbeat --ack <terminal-ack-cursor>
24
+ ```
25
+
26
+ `POST /api/orgs/{id}/heartbeat/ack` accepts `{ "ack_cursor": "..." }`. The
27
+ cursor must be the terminal cursor from the final page. A page cursor cannot
28
+ be acknowledged. Acknowledgement is idempotent. Use an acknowledged terminal
29
+ cursor with `since=<cursor>` to receive only new, changed, or escalated groups.
30
+ Unchanged groups and expected waits are reported in compact counts and are
31
+ suppressed from the signal list. An invalid cursor returns `400`; a stale page
32
+ cursor or an unacknowledged `since` cursor returns `409`. If an acknowledged
33
+ baseline has expired, Atoll returns a fresh compact response with
34
+ `delta.reset_required: true`.
35
+
36
+ If the requested `max_bytes` cannot fit the mandatory actionable record and
37
+ compact response envelope, the server returns `413` with
38
+ `code: "heartbeat_budget_too_small"`. It does not advance a page cursor or
39
+ terminal receipt. Retry with a larger `max_bytes` (up to `16,384`) or omit the
40
+ parameter to use the default.
41
+
42
+ If policy, authorization, or the candidate set changes while a page is being
43
+ read, restart without the cursor after `409 heartbeat_cursor_stale`. Compact
44
+ dependency groups use an actionable upstream blocker and release condition as
45
+ their root. Expected waits are suppressed for an unsatisfied dependency when the readable
46
+ blocker is before its release column and there is no active stall, threatened or
47
+ overdue commitment, or explicit deadline, gate, permission, or stale anomaly.
48
+ An unowned backlog or Todo blocker by itself is an ordinary wait and never
49
+ alerts. Actionable groups surface active stalls, threatened or overdue
50
+ commitments, and explicit anomalies; escalation metadata alone does not surface
51
+ an expected wait. Initiative-target and stalled aggregates are also suppressed
52
+ when every underlying dependency is an expected wait. Actionable groups can include a
53
+ `suggested_read` with an executable REST path, CLI command, or private MCP tool
54
+ call. Dependency-chain cursors are signed and revision-bound. If the graph
55
+ changes while paging, the chain request returns `409 Stale dependency chain
56
+ cursor`; restart without the cursor.
57
+
58
+ Use `atoll heartbeat --full` or `?view=full` for the legacy full context. Full
59
+ requests cannot include `since` or `cursor`.
60
+
61
+ The public ChatGPT/Codex plugin MCP profile keeps the legacy full heartbeat
62
+ shape and does not expose compact heartbeat acknowledgement or dependency-chain
63
+ tools. The private MCP profile supports compact heartbeat paging and
64
+ `atoll_ack_heartbeat`, plus `atoll_get_dependency_chain`.
65
+
5
66
  ## The Heartbeat Loop
6
67
 
7
68
  The primary pattern for autonomous agents. Prefer `atoll heartbeat --json` when the CLI is available; it wraps `GET /api/orgs/{id}/heartbeat` and returns the same computed briefing:
@@ -30,6 +91,11 @@ atoll heartbeat
30
91
  atoll heartbeat --signals-only
31
92
  atoll heartbeat --severity critical
32
93
  atoll heartbeat --json
94
+ atoll heartbeat --full --json
95
+ atoll heartbeat --since <ack-cursor> --json
96
+ atoll heartbeat --cursor <page-cursor> --json
97
+ atoll heartbeat --ack <terminal-ack-cursor>
98
+ atoll dependency chain <issue> --direction upstream --depth 2 --limit 50 --json
33
99
  ```
34
100
 
35
101
  **The agent loop:**