client.entities.publishEntity(request) -> Entityclient.entities.getEntity(entityId) -> Entityclient.entities.overrideEntity(entityId, fieldPath, request) -> Entityclient.entities.removeEntityOverride(entityId, fieldPath) -> Entityclient.entities.longPollEntityEvents(request) -> EntityEventResponseclient.entities.streamEntities(request) -> Iterable<StreamEntitiesResponse>client.tasks.createTask(request) -> Taskclient.tasks.getTask(taskId) -> Taskclient.tasks.updateTaskStatus(taskId, request) -> Taskclient.tasks.queryTasks(request) -> TaskQueryResultsclient.tasks.listenAsAgent(request) -> AgentRequestclient.objects.listObjects() -> SyncPagingIterable<PathMetadata>client.objects.getObject(objectPath) -> InputStreamclient.objects.uploadObject(objectPath, request) -> PathMetadataclient.objects.deleteObject(objectPath)client.objects.getObjectMetadata(objectPath)client.oAuth2.getToken(request) -> GetTokenResponseAn entity ID must be provided when calling this endpoint. If the entity referenced by the entity ID does not exist + * then it will be created. Otherwise the entity will be updated. An entity will only be updated if its + * provenance.sourceUpdateTime is greater than the provenance.sourceUpdateTime of the existing entity.
+ */ + public CompletableFutureNote that overrides are applied in an eventually consistent manner. If multiple overrides are created + * concurrently for the same field path, the last writer wins.
+ */ + public CompletableFutureThis endpoint enables clients to maintain a real-time view of the common operational picture (COP) + * by first streaming all pre-existing entities that match filter criteria, then continuously delivering + * updates as entities are created, modified, or deleted.
+ *The server first sends events with type PREEXISTING for all live entities matching the filter that existed before the stream was open, + * then streams CREATE events for newly created entities, UPDATE events when existing entities change, and DELETED events when entities are removed. The stream remains open + * indefinitely unless preExistingOnly is set to true.
+ *Heartbeat messages can be configured to maintain connection health and detect disconnects by setting the heartbeatIntervalMS + * parameter. These heartbeats help keep the connection alive and allow clients to verify the server is still responsive.
+ *Clients can optimize bandwidth usage by specifying which entity components they need populated using the componentsToInclude parameter. + * This allows receiving only relevant data instead of complete entities.
+ *The connection automatically recovers from temporary disconnections, resuming the stream where it left off. Unlike polling approaches, + * this provides real-time updates with minimal latency and reduced server load.
+ */ + public CompletableFutureAn entity ID must be provided when calling this endpoint. If the entity referenced by the entity ID does not exist + * then it will be created. Otherwise the entity will be updated. An entity will only be updated if its + * provenance.sourceUpdateTime is greater than the provenance.sourceUpdateTime of the existing entity.
+ */ + public CompletableFutureNote that overrides are applied in an eventually consistent manner. If multiple overrides are created + * concurrently for the same field path, the last writer wins.
+ */ + public CompletableFutureThis endpoint enables clients to maintain a real-time view of the common operational picture (COP) + * by first streaming all pre-existing entities that match filter criteria, then continuously delivering + * updates as entities are created, modified, or deleted.
+ *The server first sends events with type PREEXISTING for all live entities matching the filter that existed before the stream was open, + * then streams CREATE events for newly created entities, UPDATE events when existing entities change, and DELETED events when entities are removed. The stream remains open + * indefinitely unless preExistingOnly is set to true.
+ *Heartbeat messages can be configured to maintain connection health and detect disconnects by setting the heartbeatIntervalMS + * parameter. These heartbeats help keep the connection alive and allow clients to verify the server is still responsive.
+ *Clients can optimize bandwidth usage by specifying which entity components they need populated using the componentsToInclude parameter. + * This allows receiving only relevant data instead of complete entities.
+ *The connection automatically recovers from temporary disconnections, resuming the stream where it left off. Unlike polling approaches, + * this provides real-time updates with minimal latency and reduced server load.
+ */ + public CompletableFutureAn entity ID must be provided when calling this endpoint. If the entity referenced by the entity ID does not exist + * then it will be created. Otherwise the entity will be updated. An entity will only be updated if its + * provenance.sourceUpdateTime is greater than the provenance.sourceUpdateTime of the existing entity.
+ */ + public Entity publishEntity(RequestOptions requestOptions) { + return this.rawClient.publishEntity(requestOptions).body(); + } + /** * Publish an entity for ingest into the Entities API. Entities created with this method are "owned" by the originator: other sources, * such as the UI, may not edit or delete these entities. The server validates entities at API call time and @@ -71,6 +83,10 @@ public Entity getEntity(String entityId) { return this.rawClient.getEntity(entityId).body(); } + public Entity getEntity(String entityId, RequestOptions requestOptions) { + return this.rawClient.getEntity(entityId, requestOptions).body(); + } + public Entity getEntity(String entityId, GetEntityRequest request) { return this.rawClient.getEntity(entityId, request).body(); } @@ -91,6 +107,20 @@ public Entity overrideEntity(String entityId, String fieldPath) { return this.rawClient.overrideEntity(entityId, fieldPath).body(); } + /** + * Only fields marked with overridable can be overridden. Please refer to our documentation to see the comprehensive + * list of fields that can be overridden. The entity in the request body should only have a value set on the field + * specified in the field path parameter. Field paths are rooted in the base entity object and must be represented + * using lower_snake_case. Do not include "entity" in the field path. + *Note that overrides are applied in an eventually consistent manner. If multiple overrides are created + * concurrently for the same field path, the last writer wins.
+ */ + public Entity overrideEntity(String entityId, String fieldPath, RequestOptions requestOptions) { + return this.rawClient + .overrideEntity(entityId, fieldPath, requestOptions) + .body(); + } + /** * Only fields marked with overridable can be overridden. Please refer to our documentation to see the comprehensive * list of fields that can be overridden. The entity in the request body should only have a value set on the field @@ -125,6 +155,15 @@ public Entity removeEntityOverride(String entityId, String fieldPath) { return this.rawClient.removeEntityOverride(entityId, fieldPath).body(); } + /** + * This operation clears the override value from the specified field path on the entity. + */ + public Entity removeEntityOverride(String entityId, String fieldPath, RequestOptions requestOptions) { + return this.rawClient + .removeEntityOverride(entityId, fieldPath, requestOptions) + .body(); + } + /** * This operation clears the override value from the specified field path on the entity. */ @@ -192,6 +231,26 @@ public IterableThis endpoint enables clients to maintain a real-time view of the common operational picture (COP) + * by first streaming all pre-existing entities that match filter criteria, then continuously delivering + * updates as entities are created, modified, or deleted.
+ *The server first sends events with type PREEXISTING for all live entities matching the filter that existed before the stream was open, + * then streams CREATE events for newly created entities, UPDATE events when existing entities change, and DELETED events when entities are removed. The stream remains open + * indefinitely unless preExistingOnly is set to true.
+ *Heartbeat messages can be configured to maintain connection health and detect disconnects by setting the heartbeatIntervalMS + * parameter. These heartbeats help keep the connection alive and allow clients to verify the server is still responsive.
+ *Clients can optimize bandwidth usage by specifying which entity components they need populated using the componentsToInclude parameter. + * This allows receiving only relevant data instead of complete entities.
+ *The connection automatically recovers from temporary disconnections, resuming the stream where it left off. Unlike polling approaches, + * this provides real-time updates with minimal latency and reduced server load.
+ */ + public IterableAn entity ID must be provided when calling this endpoint. If the entity referenced by the entity ID does not exist + * then it will be created. Otherwise the entity will be updated. An entity will only be updated if its + * provenance.sourceUpdateTime is greater than the provenance.sourceUpdateTime of the existing entity.
+ */ + public LatticeHttpResponseNote that overrides are applied in an eventually consistent manner. If multiple overrides are created + * concurrently for the same field path, the last writer wins.
+ */ + public LatticeHttpResponseThis endpoint enables clients to maintain a real-time view of the common operational picture (COP) + * by first streaming all pre-existing entities that match filter criteria, then continuously delivering + * updates as entities are created, modified, or deleted.
+ *The server first sends events with type PREEXISTING for all live entities matching the filter that existed before the stream was open, + * then streams CREATE events for newly created entities, UPDATE events when existing entities change, and DELETED events when entities are removed. The stream remains open + * indefinitely unless preExistingOnly is set to true.
+ *Heartbeat messages can be configured to maintain connection health and detect disconnects by setting the heartbeatIntervalMS + * parameter. These heartbeats help keep the connection alive and allow clients to verify the server is still responsive.
+ *Clients can optimize bandwidth usage by specifying which entity components they need populated using the componentsToInclude parameter. + * This allows receiving only relevant data instead of complete entities.
+ *The connection automatically recovers from temporary disconnections, resuming the stream where it left off. Unlike polling approaches, + * this provides real-time updates with minimal latency and reduced server load.
+ */ + public LatticeHttpResponseThe client identifier
+ */ + @JsonSetter(value = "client_id", nulls = Nulls.SKIP) + public Builder clientId(OptionalThe client secret
+ */ + @JsonSetter(value = "client_secret", nulls = Nulls.SKIP) + public Builder clientSecret(OptionalThe access token
+ */ + TokenTypeStage accessToken(@NotNull String accessToken); + + Builder from(GetTokenResponse other); + } + + public interface TokenTypeStage { + /** + *The type of token (typically "Bearer")
+ */ + _FinalStage tokenType(@NotNull String tokenType); + } + + public interface _FinalStage { + GetTokenResponse build(); + + /** + *Lifetime of the access token in seconds
+ */ + _FinalStage expiresIn(OptionalLifetime of the refresh token
+ */ + _FinalStage refreshExpiresIn(OptionalEnforce that a token cannot be used before a specific unixtime
+ */ + _FinalStage notBeforePolicy(OptionalThe scope of the access token
+ */ + _FinalStage scope(OptionalThe access token
+ *The access token
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("access_token") + public TokenTypeStage accessToken(@NotNull String accessToken) { + this.accessToken = Objects.requireNonNull(accessToken, "accessToken must not be null"); + return this; + } + + /** + *The type of token (typically "Bearer")
+ *The type of token (typically "Bearer")
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("token_type") + public _FinalStage tokenType(@NotNull String tokenType) { + this.tokenType = Objects.requireNonNull(tokenType, "tokenType must not be null"); + return this; + } + + /** + *The scope of the access token
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage scope(String scope) { + this.scope = Optional.ofNullable(scope); + return this; + } + + /** + *The scope of the access token
+ */ + @java.lang.Override + @JsonSetter(value = "scope", nulls = Nulls.SKIP) + public _FinalStage scope(OptionalEnforce that a token cannot be used before a specific unixtime
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage notBeforePolicy(Integer notBeforePolicy) { + this.notBeforePolicy = Optional.ofNullable(notBeforePolicy); + return this; + } + + /** + *Enforce that a token cannot be used before a specific unixtime
+ */ + @java.lang.Override + @JsonSetter(value = "not-before-policy", nulls = Nulls.SKIP) + public _FinalStage notBeforePolicy(OptionalLifetime of the refresh token
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage refreshExpiresIn(Integer refreshExpiresIn) { + this.refreshExpiresIn = Optional.ofNullable(refreshExpiresIn); + return this; + } + + /** + *Lifetime of the refresh token
+ */ + @java.lang.Override + @JsonSetter(value = "refresh_expires_in", nulls = Nulls.SKIP) + public _FinalStage refreshExpiresIn(OptionalLifetime of the access token in seconds
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage expiresIn(Integer expiresIn) { + this.expiresIn = Optional.ofNullable(expiresIn); + return this; + } + + /** + *Lifetime of the access token in seconds
+ */ + @java.lang.Override + @JsonSetter(value = "expires_in", nulls = Nulls.SKIP) + public _FinalStage expiresIn(OptionalThis method initiates a new task with a unique ID (either provided or auto-generated), + * sets the initial task state to STATUS_CREATED, and establishes task ownership. The task + * can be assigned to a specific agent through the Relations field.
+ *Once created, a task enters the lifecycle workflow and can be tracked, updated, and managed + * through other Tasks API endpoints.
+ */ + public CompletableFutureThis method initiates a new task with a unique ID (either provided or auto-generated),
@@ -154,6 +166,18 @@ public CompletableFuture This method returns detailed information about a task including its current status,
+ * specification, relations, and other metadata. The response includes the complete Task object
+ * with all associated fields. By default, the method returns the latest definition version of the task from the manager's
+ * perspective. This method returns detailed information about a task including its current status,
@@ -254,6 +278,20 @@ public CompletableFuture This method allows agents or operators to report the current state of a task,
+ * which could include changes to task status, and error information. Each status update increments the task's status_version. When updating status,
+ * clients must provide the current version to ensure consistency. The system rejects
+ * updates with mismatched versions to prevent race conditions. Terminal states ( This method allows agents or operators to report the current state of a task,
@@ -373,6 +411,26 @@ public CompletableFuture This method allows filtering tasks based on multiple criteria including: Results are returned in pages. When more results are available than can be returned in a single
+ * response, a page_token is provided that can be used in subsequent requests to retrieve the next
+ * set of results. By default, this returns the latest task version for each matching task from the manager's perspective. This method allows filtering tasks based on multiple criteria including: This method creates a persistent connection from Tasks API to an agent, allowing the server
+ * to push tasks to the agent as they become available. The agent receives a stream of tasks that
+ * match its selector criteria (entity IDs). The stream delivers three types of requests: This is the primary method for taskable agents to receive and process tasks in real-time.
+ * Agents should maintain this connection and process incoming tasks according to their capabilities. When an agent receives a task, it should update the task status using the UpdateStatus endpoint
+ * to provide progress information back to Tasks API. This is a long polling API that will block until a new task is ready for delivery. If no new task is
+ * available then the server will hold on to your request for up to 5 minutes, after that 5 minute timeout
+ * period you will be expected to reinitiate a new request. This method creates a persistent connection from Tasks API to an agent, allowing the server
diff --git a/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java b/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java
index 075a5c2e..5305bdfc 100644
--- a/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java
+++ b/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java
@@ -44,6 +44,18 @@ public CompletableFuture This method initiates a new task with a unique ID (either provided or auto-generated),
+ * sets the initial task state to STATUS_CREATED, and establishes task ownership. The task
+ * can be assigned to a specific agent through the Relations field. Once created, a task enters the lifecycle workflow and can be tracked, updated, and managed
+ * through other Tasks API endpoints. This method initiates a new task with a unique ID (either provided or auto-generated),
@@ -80,6 +92,18 @@ public CompletableFuture This method returns detailed information about a task including its current status,
+ * specification, relations, and other metadata. The response includes the complete Task object
+ * with all associated fields. By default, the method returns the latest definition version of the task from the manager's
+ * perspective. This method returns detailed information about a task including its current status,
@@ -118,6 +142,20 @@ public CompletableFuture This method allows agents or operators to report the current state of a task,
+ * which could include changes to task status, and error information. Each status update increments the task's status_version. When updating status,
+ * clients must provide the current version to ensure consistency. The system rejects
+ * updates with mismatched versions to prevent race conditions. Terminal states ( This method allows agents or operators to report the current state of a task,
@@ -167,6 +205,26 @@ public CompletableFuture This method allows filtering tasks based on multiple criteria including: Results are returned in pages. When more results are available than can be returned in a single
+ * response, a page_token is provided that can be used in subsequent requests to retrieve the next
+ * set of results. By default, this returns the latest task version for each matching task from the manager's perspective. This method allows filtering tasks based on multiple criteria including: This method creates a persistent connection from Tasks API to an agent, allowing the server
+ * to push tasks to the agent as they become available. The agent receives a stream of tasks that
+ * match its selector criteria (entity IDs). The stream delivers three types of requests: This is the primary method for taskable agents to receive and process tasks in real-time.
+ * Agents should maintain this connection and process incoming tasks according to their capabilities. When an agent receives a task, it should update the task status using the UpdateStatus endpoint
+ * to provide progress information back to Tasks API. This is a long polling API that will block until a new task is ready for delivery. If no new task is
+ * available then the server will hold on to your request for up to 5 minutes, after that 5 minute timeout
+ * period you will be expected to reinitiate a new request. This method creates a persistent connection from Tasks API to an agent, allowing the server
diff --git a/src/main/java/com/anduril/resources/tasks/RawTasksClient.java b/src/main/java/com/anduril/resources/tasks/RawTasksClient.java
index 26e6f983..50fca287 100644
--- a/src/main/java/com/anduril/resources/tasks/RawTasksClient.java
+++ b/src/main/java/com/anduril/resources/tasks/RawTasksClient.java
@@ -50,6 +50,18 @@ public LatticeHttpResponse This method initiates a new task with a unique ID (either provided or auto-generated),
+ * sets the initial task state to STATUS_CREATED, and establishes task ownership. The task
+ * can be assigned to a specific agent through the Relations field. Once created, a task enters the lifecycle workflow and can be tracked, updated, and managed
+ * through other Tasks API endpoints. This method initiates a new task with a unique ID (either provided or auto-generated),
@@ -132,6 +144,18 @@ public LatticeHttpResponse This method returns detailed information about a task including its current status,
+ * specification, relations, and other metadata. The response includes the complete Task object
+ * with all associated fields. By default, the method returns the latest definition version of the task from the manager's
+ * perspective. This method returns detailed information about a task including its current status,
@@ -212,6 +236,20 @@ public LatticeHttpResponse This method allows agents or operators to report the current state of a task,
+ * which could include changes to task status, and error information. Each status update increments the task's status_version. When updating status,
+ * clients must provide the current version to ensure consistency. The system rejects
+ * updates with mismatched versions to prevent race conditions. Terminal states ( This method allows agents or operators to report the current state of a task,
@@ -312,6 +350,26 @@ public LatticeHttpResponse This method allows filtering tasks based on multiple criteria including: Results are returned in pages. When more results are available than can be returned in a single
+ * response, a page_token is provided that can be used in subsequent requests to retrieve the next
+ * set of results. By default, this returns the latest task version for each matching task from the manager's perspective. This method allows filtering tasks based on multiple criteria including: This method creates a persistent connection from Tasks API to an agent, allowing the server
+ * to push tasks to the agent as they become available. The agent receives a stream of tasks that
+ * match its selector criteria (entity IDs). The stream delivers three types of requests: This is the primary method for taskable agents to receive and process tasks in real-time.
+ * Agents should maintain this connection and process incoming tasks according to their capabilities. When an agent receives a task, it should update the task status using the UpdateStatus endpoint
+ * to provide progress information back to Tasks API. This is a long polling API that will block until a new task is ready for delivery. If no new task is
+ * available then the server will hold on to your request for up to 5 minutes, after that 5 minute timeout
+ * period you will be expected to reinitiate a new request. This method creates a persistent connection from Tasks API to an agent, allowing the server
diff --git a/src/main/java/com/anduril/resources/tasks/TasksClient.java b/src/main/java/com/anduril/resources/tasks/TasksClient.java
index bbfa2e2e..32ac79ec 100644
--- a/src/main/java/com/anduril/resources/tasks/TasksClient.java
+++ b/src/main/java/com/anduril/resources/tasks/TasksClient.java
@@ -43,6 +43,18 @@ public Task createTask() {
return this.rawClient.createTask().body();
}
+ /**
+ * Creates a new Task in the system with the specified parameters.
+ * This method initiates a new task with a unique ID (either provided or auto-generated),
+ * sets the initial task state to STATUS_CREATED, and establishes task ownership. The task
+ * can be assigned to a specific agent through the Relations field. Once created, a task enters the lifecycle workflow and can be tracked, updated, and managed
+ * through other Tasks API endpoints. This method initiates a new task with a unique ID (either provided or auto-generated),
@@ -79,6 +91,18 @@ public Task getTask(String taskId) {
return this.rawClient.getTask(taskId).body();
}
+ /**
+ * Retrieves a specific Task by its ID, with options to select a particular task version or view.
+ * This method returns detailed information about a task including its current status,
+ * specification, relations, and other metadata. The response includes the complete Task object
+ * with all associated fields. By default, the method returns the latest definition version of the task from the manager's
+ * perspective. This method returns detailed information about a task including its current status,
@@ -117,6 +141,20 @@ public Task updateTaskStatus(String taskId) {
return this.rawClient.updateTaskStatus(taskId).body();
}
+ /**
+ * Updates the status of a Task as it progresses through its lifecycle.
+ * This method allows agents or operators to report the current state of a task,
+ * which could include changes to task status, and error information. Each status update increments the task's status_version. When updating status,
+ * clients must provide the current version to ensure consistency. The system rejects
+ * updates with mismatched versions to prevent race conditions. Terminal states ( This method allows agents or operators to report the current state of a task,
@@ -165,6 +203,26 @@ public TaskQueryResults queryTasks() {
return this.rawClient.queryTasks().body();
}
+ /**
+ * Searches for Tasks that match specified filtering criteria and returns matching tasks in paginated form.
+ * This method allows filtering tasks based on multiple criteria including: Results are returned in pages. When more results are available than can be returned in a single
+ * response, a page_token is provided that can be used in subsequent requests to retrieve the next
+ * set of results. By default, this returns the latest task version for each matching task from the manager's perspective. This method allows filtering tasks based on multiple criteria including: This method creates a persistent connection from Tasks API to an agent, allowing the server
+ * to push tasks to the agent as they become available. The agent receives a stream of tasks that
+ * match its selector criteria (entity IDs). The stream delivers three types of requests: This is the primary method for taskable agents to receive and process tasks in real-time.
+ * Agents should maintain this connection and process incoming tasks according to their capabilities. When an agent receives a task, it should update the task status using the UpdateStatus endpoint
+ * to provide progress information back to Tasks API. This is a long polling API that will block until a new task is ready for delivery. If no new task is
+ * available then the server will hold on to your request for up to 5 minutes, after that 5 minute timeout
+ * period you will be expected to reinitiate a new request. This method creates a persistent connection from Tasks API to an agent, allowing the server
diff --git a/src/main/java/com/anduril/types/AgentStreamEvent.java b/src/main/java/com/anduril/types/AgentStreamEvent.java
new file mode 100644
index 00000000..d7c84459
--- /dev/null
+++ b/src/main/java/com/anduril/types/AgentStreamEvent.java
@@ -0,0 +1,125 @@
+/**
+ * This file was auto-generated by Fern from our API Definition.
+ */
+package com.anduril.types;
+
+import com.anduril.core.ObjectMappers;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import org.jetbrains.annotations.NotNull;
+
+@JsonInclude(JsonInclude.Include.NON_ABSENT)
+@JsonDeserialize(builder = AgentStreamEvent.Builder.class)
+public final class AgentStreamEvent {
+ private final AgentStreamEventEvent event;
+
+ private final AgentTaskRequest data;
+
+ private final Map The timestamp at which the heartbeat message was sent. The selector criteria to determine which tasks the agent receives. The time interval, defined in seconds, that determines the frequency at which to send heartbeat events. Defaults to 30s.STATUS_DONE_OK and STATUS_DONE_NOT_OK) are permanent; once a task
+ * reaches these states, no further updates are allowed.
+ *
+ *
+ *
+ * STATUS_DONE_OK and STATUS_DONE_NOT_OK) are permanent; once a task
+ * reaches these states, no further updates are allowed.
+ *
+ *
+ *
+ * STATUS_DONE_OK and STATUS_DONE_NOT_OK) are permanent; once a task
+ * reaches these states, no further updates are allowed.
+ *
+ *
+ *
+ * STATUS_DONE_OK and STATUS_DONE_NOT_OK) are permanent; once a task
+ * reaches these states, no further updates are allowed.
+ *
+ *
+ *
+ *