Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/coven-run-history.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@opencoven/coven-client": minor
---

Add `automations.runHistory(automationId, { limit, cursor, occurrenceId })`
over the capability-gated `coven.automations.run.history.v1` producer action:
one automation's runs, newest first by start instant, as an sdk-core `Page`
with a keyset cursor of at most 256 characters. Also add `iterateRunHistory()`
on `iteratePages`. Pages that cross automations or occurrences, break
ordering, or do not echo the cursor are refused, and responses share the
256 KiB history cap. Requires OpenCoven/coven#1160.
51 changes: 44 additions & 7 deletions api-baselines/coven.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,14 @@ interface CovenAutomationReceiptVerification {
/** Pure local verification. Unknown or malformed host values produce fixed, non-secret reasons. */
declare function verifyReceipt(receipt: unknown, trustContext: CovenAutomationReceiptTrustContext): CovenAutomationReceiptVerification;

/** A keyset history page's position, shaped as an sdk-core `PageCursor`. */
interface CovenAutomationHistoryCursor {
readonly hasMore: boolean;
/** The cursor this page was read from; absent on the first page. */
readonly current?: string;
readonly next?: string;
}

interface CovenAutomationRunsOptions {
/** Newest-first history size, 1–100 (default 20). No pagination cursor is exposed by the producer. */
readonly limit?: number;
Expand Down Expand Up @@ -202,6 +210,24 @@ interface CovenAutomationRun {
interface CovenAutomationRunsResult {
readonly runs: readonly CovenAutomationRun[];
}
interface CovenAutomationRunHistoryOptions {
/** 1–100, default 20. */
readonly limit?: number;
/** An opaque `cursor.next` from an earlier page of the same query. */
readonly cursor?: string;
/** Restricts the history to one occurrence's runs. */
readonly occurrenceId?: string;
}
/**
* One page of an automation's runs, newest first by start instant then
* `id`, each with its attempts. Shaped as an sdk-core `Page`.
*/
interface CovenAutomationRunHistoryPage {
readonly automationId: string;
readonly occurrenceId?: string;
readonly data: readonly CovenAutomationRun[];
readonly cursor: CovenAutomationHistoryCursor;
}

/** Domain streams only: the global feed has a separate, non-domain cursor. */
interface CovenAutomationEventStream {
Expand Down Expand Up @@ -371,12 +397,7 @@ interface CovenAutomationOccurrenceHistoryOptions {
interface CovenAutomationOccurrenceHistoryPage {
readonly automationId: string;
readonly data: readonly CovenAutomationOccurrence[];
readonly cursor: {
readonly hasMore: boolean;
/** The cursor this page was read from; absent on the first page. */
readonly current?: string;
readonly next?: string;
};
readonly cursor: CovenAutomationHistoryCursor;
}
interface CovenAutomationOccurrenceResult {
readonly occurrence: CovenAutomationOccurrenceDetail | null;
Expand Down Expand Up @@ -474,6 +495,12 @@ type CovenAutomationDefinitionReadRequest = {
} | {
readonly action: 'coven.automations.occurrence.get.v1';
readonly id: string;
} | {
readonly action: 'coven.automations.run.history.v1';
readonly automationId: string;
readonly limit: number;
readonly occurrenceId?: string;
readonly cursor?: string;
} | {
readonly action: 'coven.automations.run.get.v1';
readonly id: string;
Expand Down Expand Up @@ -545,6 +572,16 @@ declare class CovenAutomationsClient {
* `maxPages` or a caller-owned `signal`; `timeoutMs` bounds the whole walk.
*/
iterateOccurrenceHistory(automationId: string, options: BoundedPageOptions): AsyncGenerator<CovenAutomationOccurrence>;
/** One page of one automation's runs, optionally for one occurrence, newest first. */
runHistory(automationId: string, query?: CovenAutomationRunHistoryOptions, options?: OperationOptions): Promise<CovenAutomationRunHistoryPage>;
/**
* Every run of one automation, optionally for one occurrence, newest first
* across pages. Requires `maxPages` or a caller-owned `signal`; `timeoutMs`
* bounds the whole walk.
*/
iterateRunHistory(automationId: string, options: BoundedPageOptions, query?: {
readonly occurrenceId?: string;
}): AsyncGenerator<CovenAutomationRun>;
/** One run and its attempts by run id, read from one producer snapshot. */
getRun(runId: string, options?: OperationOptions): Promise<CovenAutomationRunResult>;
getOccurrence(id: string, options?: OperationOptions): Promise<CovenAutomationOccurrenceResult>;
Expand Down Expand Up @@ -1057,4 +1094,4 @@ type CovenAutomationEventReduction = {
/** Bounded supplied-batch reference projection; no persistence, transport or execution authority. */
declare function reduceAutomationEvents(events: unknown): CovenAutomationEventReduction;

export { COVEN_DAEMON_PROTOCOL, COVEN_SESSION_POLICY_CONTRACT, COVEN_SESSION_POLICY_PROFILE, type CovenAutomationAttempt, type CovenAutomationCapabilities, type CovenAutomationCapabilityProfile, type CovenAutomationDefinition, type CovenAutomationDefinitionDigestResult, type CovenAutomationDefinitionDocument, type CovenAutomationDefinitionList, type CovenAutomationDefinitionReadRequest, type CovenAutomationEvent, type CovenAutomationEventIntegrity, type CovenAutomationEventPage, type CovenAutomationEventReduction, type CovenAutomationEventStream, type CovenAutomationEventsOptions, type CovenAutomationEventsRequest, type CovenAutomationHealth, type CovenAutomationHealthResult, type CovenAutomationListOptions, type CovenAutomationOccurrence, type CovenAutomationOccurrenceDetail, type CovenAutomationOccurrenceHistoryOptions, type CovenAutomationOccurrenceHistoryPage, type CovenAutomationOccurrenceResult, type CovenAutomationOccurrenceRun, type CovenAutomationOccurrenceView, type CovenAutomationOccurrencesOptions, type CovenAutomationOccurrencesResult, type CovenAutomationProjectionJson, type CovenAutomationReceipt, type CovenAutomationReceiptDigest, type CovenAutomationReceiptReadVerification, type CovenAutomationReceiptResult, type CovenAutomationReceiptTrustContext, type CovenAutomationReceiptVerification, type CovenAutomationReceiptVerificationCheck, type CovenAutomationReceiptVerificationReason, type CovenAutomationRoutine, type CovenAutomationRun, type CovenAutomationRunCancellation, type CovenAutomationRunResult, type CovenAutomationRunsOptions, type CovenAutomationRunsResult, type CovenAutomationVariant, CovenAutomationsClient, type CovenAutomationsClientOptions, type CovenAutomationsTransport, type CovenAutomationsUnixTransportOptions, type CovenAutomationsWindowsTransportOptions, CovenClient, CovenClientError, type CovenClientOptions, type CovenConnectedSocket, type CovenDaemonFailure, CovenDaemonResponseError, type CovenDiscoveredClientOptions, type CovenDiscoveredEndpoint, type CovenDiscoveredUnixClientOptions, type CovenDiscoveredUnixTransportOptions, type CovenDiscoveredWindowsClientOptions, type CovenDiscoveredWindowsTransportOptions, type CovenDiscoveryDependencies, type CovenDiscoveryFileIdentity, type CovenDiscoverySource, type CovenEndpointFreshness, type CovenEndpointOwner, type CovenExecFile, type CovenExecFileError, type CovenExecFileOptions, type CovenExecutableResolver, type CovenHealth, type CovenHealthResponse, type CovenHealthTransportLimits, type CovenIpcDiagnostics, CovenIpcError, type CovenIpcErrorCode, type CovenMetadataFileHandle, type CovenRestrictedLaunchRequest, CovenSessionPolicyClient, type CovenSessionPolicyClientOptions, type CovenSessionPolicyDelivery, type CovenSessionPolicyDiscovery, CovenSessionPolicyError, type CovenSessionPolicyErrorCode, type CovenSessionPolicyRefusal, type CovenSessionPolicyTransport, type CovenSessionPolicyTransportRequest, type CovenSessionPolicyTransportResponse, type CovenSessionPolicyUnixTransportOptions, type CovenSocket, type CovenSocketConnector, type CovenTransport, type CovenTransportSecurityProvider, type CovenUnixFileIdentity, type CovenUnixPeerIdentity, type CovenUnixPeerIdentityAdapter, type CovenUnixTransportDependencies, type CovenUnixTransportOptions, type CovenUnixTransportSecurityProvider, type CovenWindowsFileTrustValidator, type CovenWindowsPipeIdentity, type CovenWindowsPipeOwnershipAdapter, type CovenWindowsTransportDependencies, type CovenWindowsTransportOptions, type CovenWindowsTransportSecurityProvider, type DiscoverCovenEndpointOptions, computeDefinitionDigest, createCovenAutomationsClient, createCovenAutomationsUnixTransport, createCovenAutomationsWindowsTransport, createCovenClient, createCovenSessionPolicyClient, createCovenSessionPolicyUnixTransport, createCovenUnixTransport, createCovenWindowsTransport, createDiscoveredCovenClient, discoverCovenEndpoint, isCovenClientError, isCovenDaemonResponseError, isCovenIpcError, isCovenSessionPolicyError, normalizeCovenError, reduceAutomationEvents, verifyEventIntegrity, verifyReceipt };
export { COVEN_DAEMON_PROTOCOL, COVEN_SESSION_POLICY_CONTRACT, COVEN_SESSION_POLICY_PROFILE, type CovenAutomationAttempt, type CovenAutomationCapabilities, type CovenAutomationCapabilityProfile, type CovenAutomationDefinition, type CovenAutomationDefinitionDigestResult, type CovenAutomationDefinitionDocument, type CovenAutomationDefinitionList, type CovenAutomationDefinitionReadRequest, type CovenAutomationEvent, type CovenAutomationEventIntegrity, type CovenAutomationEventPage, type CovenAutomationEventReduction, type CovenAutomationEventStream, type CovenAutomationEventsOptions, type CovenAutomationEventsRequest, type CovenAutomationHealth, type CovenAutomationHealthResult, type CovenAutomationHistoryCursor, type CovenAutomationListOptions, type CovenAutomationOccurrence, type CovenAutomationOccurrenceDetail, type CovenAutomationOccurrenceHistoryOptions, type CovenAutomationOccurrenceHistoryPage, type CovenAutomationOccurrenceResult, type CovenAutomationOccurrenceRun, type CovenAutomationOccurrenceView, type CovenAutomationOccurrencesOptions, type CovenAutomationOccurrencesResult, type CovenAutomationProjectionJson, type CovenAutomationReceipt, type CovenAutomationReceiptDigest, type CovenAutomationReceiptReadVerification, type CovenAutomationReceiptResult, type CovenAutomationReceiptTrustContext, type CovenAutomationReceiptVerification, type CovenAutomationReceiptVerificationCheck, type CovenAutomationReceiptVerificationReason, type CovenAutomationRoutine, type CovenAutomationRun, type CovenAutomationRunCancellation, type CovenAutomationRunHistoryOptions, type CovenAutomationRunHistoryPage, type CovenAutomationRunResult, type CovenAutomationRunsOptions, type CovenAutomationRunsResult, type CovenAutomationVariant, CovenAutomationsClient, type CovenAutomationsClientOptions, type CovenAutomationsTransport, type CovenAutomationsUnixTransportOptions, type CovenAutomationsWindowsTransportOptions, CovenClient, CovenClientError, type CovenClientOptions, type CovenConnectedSocket, type CovenDaemonFailure, CovenDaemonResponseError, type CovenDiscoveredClientOptions, type CovenDiscoveredEndpoint, type CovenDiscoveredUnixClientOptions, type CovenDiscoveredUnixTransportOptions, type CovenDiscoveredWindowsClientOptions, type CovenDiscoveredWindowsTransportOptions, type CovenDiscoveryDependencies, type CovenDiscoveryFileIdentity, type CovenDiscoverySource, type CovenEndpointFreshness, type CovenEndpointOwner, type CovenExecFile, type CovenExecFileError, type CovenExecFileOptions, type CovenExecutableResolver, type CovenHealth, type CovenHealthResponse, type CovenHealthTransportLimits, type CovenIpcDiagnostics, CovenIpcError, type CovenIpcErrorCode, type CovenMetadataFileHandle, type CovenRestrictedLaunchRequest, CovenSessionPolicyClient, type CovenSessionPolicyClientOptions, type CovenSessionPolicyDelivery, type CovenSessionPolicyDiscovery, CovenSessionPolicyError, type CovenSessionPolicyErrorCode, type CovenSessionPolicyRefusal, type CovenSessionPolicyTransport, type CovenSessionPolicyTransportRequest, type CovenSessionPolicyTransportResponse, type CovenSessionPolicyUnixTransportOptions, type CovenSocket, type CovenSocketConnector, type CovenTransport, type CovenTransportSecurityProvider, type CovenUnixFileIdentity, type CovenUnixPeerIdentity, type CovenUnixPeerIdentityAdapter, type CovenUnixTransportDependencies, type CovenUnixTransportOptions, type CovenUnixTransportSecurityProvider, type CovenWindowsFileTrustValidator, type CovenWindowsPipeIdentity, type CovenWindowsPipeOwnershipAdapter, type CovenWindowsTransportDependencies, type CovenWindowsTransportOptions, type CovenWindowsTransportSecurityProvider, type DiscoverCovenEndpointOptions, computeDefinitionDigest, createCovenAutomationsClient, createCovenAutomationsUnixTransport, createCovenAutomationsWindowsTransport, createCovenClient, createCovenSessionPolicyClient, createCovenSessionPolicyUnixTransport, createCovenUnixTransport, createCovenWindowsTransport, createDiscoveredCovenClient, discoverCovenEndpoint, isCovenClientError, isCovenDaemonResponseError, isCovenIpcError, isCovenSessionPolicyError, normalizeCovenError, reduceAutomationEvents, verifyEventIntegrity, verifyReceipt };
42 changes: 38 additions & 4 deletions packages/coven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ provider, and platform dependencies. Construction sends no health, capability,
or action request. Each later request authenticates its own connection.
The `unix`/`windows` health response-limit options still apply only to health;
Automations keeps its fixed 16 KiB body limit, except for the event (1 MiB) and
occurrence-history (256 KiB) reads described below.
occurrence- and run-history (256 KiB) reads described below.

`client.automations` is `CovenAutomationsClient | undefined`.
`client.requireAutomations()` returns that same namespace or throws
Expand Down Expand Up @@ -135,6 +135,7 @@ does not poll or activate Automations.
| `list()`, `get()`, `health()` | Allowlisted reads | Same actions and decoders |
| `runs()`, `occurrences()`, `getOccurrence()`, `getRun()` | Bounded diagnostic reads | Same actions and decoders |
| `occurrenceHistory()`, `iterateOccurrenceHistory()` | Keyset-paged diagnostic reads | Same actions and decoders |
| `runHistory()`, `iterateRunHistory()` | Keyset-paged diagnostic reads | Same actions and decoders |
| `getReceipt()` | Public/operational receipt result | Same result and privacy checks |
| `events()`, `subscribe()` | Bounded domain event pages | Same pages and cancellation |
| Normal/discovered client and `sdk.coven` | Explicit opt-in | Explicit opt-in |
Expand Down Expand Up @@ -209,7 +210,7 @@ missing action names fail with `capability_unsupported` without posting an actio
Custom capability-only transports remain compatible; reads without the optional
`readDefinitions` hook fail with `unsupported_operation`.

The built-in Unix and Windows transports send only these nine allowlisted JSON actions to
The built-in Unix and Windows transports send only these ten allowlisted JSON actions to
`POST /api/v1/actions`. It authenticates each connection, including the separate
capability request, under one client deadline/cancellation scope. It cannot send
mutations through this hook. IDs are trimmed as the producer does; the SDK
Expand Down Expand Up @@ -254,7 +255,7 @@ Failure/exhaustion counters are nonnegative safe integers and `maxAttempts` is
Missing routines produce sanitized `action_rejected`, not an invented null result.
Health is store-derived diagnostic data, not execution or receipt authority.
Custom transports use the existing optional `readDefinitions` hook, whose
historical name now covers all nine explicitly allowlisted read actions.
historical name now covers all ten explicitly allowlisted read actions.

Health source authority was independently read from Coven
[`b3b2d043a4ee586ccbf25ef6aad21db8a1171a54`](https://github.com/OpenCoven/coven/tree/b3b2d043a4ee586ccbf25ef6aad21db8a1171a54):
Expand Down Expand Up @@ -635,6 +636,39 @@ per-call timeout. Both need a Coven producer that advertises the action
([coven#1157](https://github.com/OpenCoven/coven/issues/1157)); an older
producer yields `capability_unsupported`.

### Run history

```ts
const page = await automations.runHistory('morning', { limit: 20, occurrenceId: 'occurrence-1' });
for await (const run of automations.iterateRunHistory('morning', { limit: 50, maxPages: 10 })) {
console.log(run.startedAt, run.status, run.attempts.length);
}
```

`runHistory(automationId, { limit?, cursor?, occurrenceId? }, operationOptions?)`
calls `coven.automations.run.history.v1`. It returns an sdk-core `Page` of
`{ automationId, occurrenceId?, data, cursor }`: one automation's runs, newest
first by start instant then `id`, each with its attempts and any cancellation,
read in one producer snapshot. Each run has the same projection and validation
as `runs()`. `occurrenceId` restricts the page to one occurrence's runs. Its
cursors are bounded at **256 characters**, tighter than occurrence history's 512.

The SDK refuses a page that:

- names another automation;
- echoes an `occurrenceId` that was not requested, or omits one that was;
- holds a run of another occurrence;
- breaks newest-first order by instant;
- misreports `hasMore` or `next`;
- does not echo the requested cursor.

Responses share the 256 KiB history cap, so a page of large `logJson` values
fails closed and a smaller `limit` reads it.

`iterateRunHistory(automationId, boundedPageOptions, { occurrenceId? })` walks
pages with sdk-core `iteratePages`. Both need a Coven producer that advertises
the action ([coven#1160](https://github.com/OpenCoven/coven/pull/1160)).

`getOccurrence(id, operationOptions?)` calls
`coven.automations.occurrence.get.v1` and returns `{ occurrence: null } for
absence, or a diagnostic detail record. The detail contains up to **20 oldest
Expand Down Expand Up @@ -733,7 +767,7 @@ events on reconnect.
Event responses are capped at 1 MiB and 100 wire events, with the existing
16-level JSON depth limit. Oversized or malformed pages fail closed without
yielding partial events. All other Automations and policy response limits
remain 16 KiB, except occurrence history (256 KiB). A producer page larger than the event byte cap cannot be
remain 16 KiB, except occurrence and run history (256 KiB). A producer page larger than the event byte cap cannot be
retried with a smaller subscription limit because the producer forbids that
field. The SDK does not silently truncate it.

Expand Down
Loading
Loading