proto: widen error-on-paused for ADR 0013's auto-pause signal (1.3.0)

DAEMON's docs/adr/0013-task-state-machine-ownership.md needs a wire signal
for the difference between a paused task the daemon entered unilaterally
(auth_required, server_file_changed, disk_full) and one that was requested
(user, schedule, queue stop, admission reconcile) -- without it, DAEMON's §3
resume rule ("resume only when the reason matches the event that justifies
resuming") has nothing correctness-preserving to key on, and would have to
guess from timing. CORE has already accepted the ADR; this was the sole
remaining blocker per DAEMON's own status line on it.

No retype, no new field -- error was already TaskError | null on both
event.task.state and TaskSummary, exactly as DAEMON characterized the ask.
Only the *description* of when it is populated widens: previously "failed or
retry_wait", now also "paused, when the daemon entered it on its own
initiative". A deliberate pause still carries error: null. TaskError's own
top-level description gets the same widening, since it previously also said
"failed or retry_wait" and would otherwise contradict the field that embeds
it.

New fixture (event.task.state.auto-paused.json) exercises the case directly:
an auth_required pause with error populated, contrasted in its own
description against download.pause.json's error: null for a requested pause.
The existing event.task.state.json fixture's first assertion was stale
("error is present exactly when failed or retry_wait") and is corrected.

Minor bump, 1.2.0 -> 1.3.0: a description widening on an already-nullable,
already-optional field changes no JSON Schema shape, but it is a real
behavioral commitment change worth a version bump so downstream regenerates
and notices, per the same reasoning ADR 0010 applied to TaskErrorCode.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_012fgjnqFCS5h5L7gZTZo3rV
This commit is contained in:
2026-09-10 00:04:35 +04:00
co-authored by Claude Sonnet 5
parent 203d4a662f
commit 6db304a0ae
16 changed files with 179 additions and 40 deletions
+9 -6
View File
@@ -3,14 +3,17 @@
**This directory is the interface between every lane.** Owner: agent **PROTO**. **This directory is the interface between every lane.** Owner: agent **PROTO**.
Nobody else commits here. Everybody else *generates from* here. Nobody else commits here. Everybody else *generates from* here.
> ## Status: **v1.2.0** (frozen at v1.0.0 on 2026-09-09; minor bumps since) > ## Status: **v1.3.0** (frozen at v1.0.0 on 2026-09-09; minor bumps since)
> >
> **v1.0.0** froze 38 methods, 9 events, 26 named types. **v1.1.0** widened `bufferBytes` > **v1.0.0** froze 38 methods, 9 events, 26 named types. **v1.1.0** widened `bufferBytes`
> bounds, added `connection.maxTotalBufferBytes` / `connection.maxActiveSegments`, and > bounds and added the segment-budget settings (`docs/adr/0012-...`). **v1.2.0** added
> `TaskDetail.effectiveBufferBytes` (`docs/adr/0012-...`). **v1.2.0** (current) adds > `download.provideAuth`, F2's credential return path. **v1.3.0** (current) widens when
> `download.provideAuth` — F2's credential return path for a paused 401/407, UDS-only > `event.task.state.error` / `TaskSummary.error` are populated to also cover a `paused`
> and privileged. See also `docs/adr/0005-...` for the versioning rule and > the daemon entered unilaterally (`auth_required`, `server_file_changed`, disk full),
> `docs/adr/0010-...` for the failure taxonomy and segment ranges. > not just `failed`/`retry_wait` — the wire shape is unchanged (`error` was already
> `TaskError | null`), only the description of when it's set. Landed for DAEMON's
> `docs/adr/0013-task-state-machine-ownership.md`. See also `docs/adr/0005-...` for the
> versioning rule and `docs/adr/0010-...` for the failure taxonomy and segment ranges.
> >
> Lane requests are answered in writing: `contracts/proto-answers-m1.md` responds to > Lane requests are answered in writing: `contracts/proto-answers-m1.md` responds to
> `core/docs/proto-requests-m1.md` point by point. > `core/docs/proto-requests-m1.md` point by point.
+1 -1
View File
@@ -1 +1 @@
1.2.0 1.3.0
@@ -0,0 +1,57 @@
{
"name": "event.task.state \u2014 the daemon auto-pauses on a 401",
"description": "The CORE-auto-pause case ADR 0013 (docs/adr/) needs a wire signal for: the daemon paused this task on its own initiative -- not because the user clicked pause, a schedule window closed, or admission control reconciled a lowered cap -- and error explains why. Compare download.pause.json, where the same target state (paused) carries error: null because that pause was requested.",
"notification": {
"jsonrpc": "2.0",
"method": "event.task.state",
"params": {
"taskId": "8c1d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
"state": "paused",
"previousState": "connecting",
"summary": {
"taskId": "8c1d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
"filename": "film.mkv",
"saveDir": "/home/sami/Downloads/Video",
"url": "https://example.org/film.mkv",
"effectiveUrl": "https://example.org/film.mkv",
"sizeBytes": 1503238553,
"downloadedBytes": 0,
"state": "paused",
"speedBps": 0,
"etaSeconds": null,
"resumable": true,
"segments": 4,
"categoryId": "video",
"queueId": null,
"queuePosition": null,
"description": null,
"createdAt": "$isoDate",
"lastTryAt": "$isoDate",
"completedAt": null,
"error": {
"code": "auth_required",
"message": "the server asked for credentials (401)",
"httpStatus": 401,
"retryable": false,
"cause": null,
"attempt": 1,
"nextRetryAt": null
}
},
"error": {
"code": "auth_required",
"message": "the server asked for credentials (401)",
"httpStatus": 401,
"retryable": false,
"cause": null,
"attempt": 1,
"nextRetryAt": null
}
}
},
"assertions": [
"error is set here specifically because the daemon paused this task itself, not the user -- the trigger is event.auth.required on the same task shortly before",
"the scheduler must not resume this task on a schedule window or queue restart: only download.provideAuth (or the user explicitly resuming) may clear it -- resuming blindly re-fails immediately and looks like a flapping bug",
"a client distinguishes an auto-pause from a deliberate one by this field being non-null, not by inspecting previousState or any other heuristic"
]
}
@@ -50,7 +50,7 @@
} }
}, },
"assertions": [ "assertions": [
"error is present exactly when state is failed or retry_wait", "error is present on every failed or retry_wait transition, and also on a paused transition the daemon entered unilaterally -- never on a paused transition the user or scheduler requested",
"error.code is a TaskErrorCode, never a JSON-RPC ErrorCode \u2014 the two are different spaces", "error.code is a TaskErrorCode, never a JSON-RPC ErrorCode \u2014 the two are different spaces",
"retryable false means the scheduler will not pick this up again on its own" "retryable false means the scheduler will not pick this up again on its own"
] ]
+7 -5
View File
@@ -2,7 +2,7 @@
"openrpc": "1.2.6", "openrpc": "1.2.6",
"info": { "info": {
"title": "Velox Download Manager", "title": "Velox Download Manager",
"version": "1.2.0", "version": "1.3.0",
"description": "The wire contract between veloxd and every client: the Qt GUI, the CLI, the native-messaging host and the Firefox extension. One JSON-RPC 2.0 payload set over four framings; only the framing differs.\n\nGENERATED from contracts/schema/ by contracts/codegen/gen_openrpc.py. Do not edit by hand.", "description": "The wire contract between veloxd and every client: the Qt GUI, the CLI, the native-messaging host and the Firefox extension. One JSON-RPC 2.0 payload set over four framings; only the framing differs.\n\nGENERATED from contracts/schema/ by contracts/codegen/gen_openrpc.py. Do not edit by hand.",
"license": { "license": {
"name": "See repository LICENSE" "name": "See repository LICENSE"
@@ -4184,7 +4184,7 @@
"title": "TaskDetail" "title": "TaskDetail"
}, },
"TaskError": { "TaskError": {
"description": "Why a task is in the failed or retry_wait state. Distinct from the JSON-RPC Error, which describes a failed call rather than a failed download \u2014 the two live in different code spaces on purpose, and `code` here is a TaskErrorCode string, never a JSON-RPC integer.", "description": "Why a task is in the failed, retry_wait, or (when the daemon paused it on its own initiative rather than the user) paused state. Distinct from the JSON-RPC Error, which describes a failed call rather than a failed download \u2014 the two live in different code spaces on purpose, and `code` here is a TaskErrorCode string, never a JSON-RPC integer. A pause the user or the scheduler requested carries no error: this field only explains a paused state the daemon entered unilaterally (auth_required, server_file_changed, disk_full and the like), never a deliberate one.",
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"required": [ "required": [
@@ -4569,7 +4569,8 @@
{ {
"type": "null" "type": "null"
} }
] ],
"description": "Set when state is failed or retry_wait, and also when state is paused and the daemon entered that state on its own initiative rather than at a user's or scheduler's request. null on every other state, including a deliberate pause."
} }
}, },
"title": "TaskSummary" "title": "TaskSummary"
@@ -4884,7 +4885,7 @@
}, },
{ {
"name": "event.task.state", "name": "event.task.state",
"description": "A task changed lifecycle state. Carries the summary so the row can be repainted in full without a round trip, and error whenever the new state is failed or retry_wait.", "description": "A task changed lifecycle state. Carries the summary so the row can be repainted in full without a round trip, and error whenever the daemon has something to say about why: on every failed or retry_wait transition, and on a paused transition the daemon entered unilaterally rather than at a user's or scheduler's request.",
"params": { "params": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
@@ -4928,7 +4929,8 @@
{ {
"type": "null" "type": "null"
} }
] ],
"description": "Set when the new state is failed or retry_wait, and also when it is paused and the daemon entered that state on its own initiative \u2014 auth_required, server_file_changed, disk_full and the like \u2014 rather than because of a user action, a schedule window closing, or an admission-control decision. null on every other transition, including every deliberately-requested pause. A client must not assume a paused task has no error just because it usually doesn't; check this field rather than the state name alone."
} }
} }
}, },
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema", "$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://velox.dev/schema/events/event.task.state.schema.json", "$id": "https://velox.dev/schema/events/event.task.state.schema.json",
"title": "event.task.state", "title": "event.task.state",
"description": "A task changed lifecycle state. Carries the summary so the row can be repainted in full without a round trip, and error whenever the new state is failed or retry_wait.", "description": "A task changed lifecycle state. Carries the summary so the row can be repainted in full without a round trip, and error whenever the daemon has something to say about why: on every failed or retry_wait transition, and on a paused transition the daemon entered unilaterally rather than at a user's or scheduler's request.",
"x-direction": "server-to-client", "x-direction": "server-to-client",
"type": "object", "type": "object",
"properties": { "properties": {
@@ -49,7 +49,8 @@
{ {
"type": "null" "type": "null"
} }
] ],
"description": "Set when the new state is failed or retry_wait, and also when it is paused and the daemon entered that state on its own initiative \u2014 auth_required, server_file_changed, disk_full and the like \u2014 rather than because of a user action, a schedule window closing, or an admission-control decision. null on every other transition, including every deliberately-requested pause. A client must not assume a paused task has no error just because it usually doesn't; check this field rather than the state name alone."
} }
} }
} }
+52 -9
View File
@@ -2,17 +2,60 @@
"$schema": "https://json-schema.org/draft/2020-12/schema", "$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://velox.dev/schema/types/TaskError.schema.json", "$id": "https://velox.dev/schema/types/TaskError.schema.json",
"title": "TaskError", "title": "TaskError",
"description": "Why a task is in the failed or retry_wait state. Distinct from the JSON-RPC Error, which describes a failed call rather than a failed download the two live in different code spaces on purpose, and `code` here is a TaskErrorCode string, never a JSON-RPC integer.", "description": "Why a task is in the failed, retry_wait, or (when the daemon paused it on its own initiative rather than the user) paused state. Distinct from the JSON-RPC Error, which describes a failed call rather than a failed download \u2014 the two live in different code spaces on purpose, and `code` here is a TaskErrorCode string, never a JSON-RPC integer. A pause the user or the scheduler requested carries no error: this field only explains a paused state the daemon entered unilaterally (auth_required, server_file_changed, disk_full and the like), never a deliberate one.",
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"required": ["code", "message", "retryable"], "required": [
"code",
"message",
"retryable"
],
"properties": { "properties": {
"code": { "$ref": "https://velox.dev/schema/types/TaskErrorCode.schema.json" }, "code": {
"message": { "type": "string", "description": "Human-readable, safe to show a user. Never carries a credential, a token or a full local path outside the download roots." }, "$ref": "https://velox.dev/schema/types/TaskErrorCode.schema.json"
"httpStatus": { "type": ["integer", "null"], "minimum": 100, "maximum": 599, "description": "Set for the codes listed in TaskErrorCode's x-carriesHttpStatus, and null otherwise." }, },
"retryable": { "type": "boolean", "description": "Whether the scheduler will pick this task up again on its own. Carried per-occurrence rather than derived from the code, because 'probe_failed' is retryable or not depending on what the probe hit." }, "message": {
"cause": { "oneOf": [{ "$ref": "https://velox.dev/schema/types/TaskErrorCode.schema.json" }, { "type": "null" }], "description": "The underlying failure, for codes that wrap one. max_retries_exhausted sets it to whatever the last attempt actually failed with, so a user learns the reason rather than just that Velox gave up." }, "type": "string",
"attempt": { "type": ["integer", "null"], "minimum": 0, "description": "How many attempts have been made so far." }, "description": "Human-readable, safe to show a user. Never carries a credential, a token or a full local path outside the download roots."
"nextRetryAt":{ "type": ["string", "null"], "format": "date-time" } },
"httpStatus": {
"type": [
"integer",
"null"
],
"minimum": 100,
"maximum": 599,
"description": "Set for the codes listed in TaskErrorCode's x-carriesHttpStatus, and null otherwise."
},
"retryable": {
"type": "boolean",
"description": "Whether the scheduler will pick this task up again on its own. Carried per-occurrence rather than derived from the code, because 'probe_failed' is retryable or not depending on what the probe hit."
},
"cause": {
"oneOf": [
{
"$ref": "https://velox.dev/schema/types/TaskErrorCode.schema.json"
},
{
"type": "null"
}
],
"description": "The underlying failure, for codes that wrap one. max_retries_exhausted sets it to whatever the last attempt actually failed with, so a user learns the reason rather than just that Velox gave up."
},
"attempt": {
"type": [
"integer",
"null"
],
"minimum": 0,
"description": "How many attempts have been made so far."
},
"nextRetryAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
} }
} }
@@ -132,7 +132,8 @@
{ {
"type": "null" "type": "null"
} }
] ],
"description": "Set when state is failed or retry_wait, and also when state is paused and the daemon entered that state on its own initiative rather than at a user's or scheduler's request. null on every other state, including a deliberate pause."
} }
} }
} }
+1 -1
View File
@@ -3,7 +3,7 @@
// //
// Source: contracts/schema/** // Source: contracts/schema/**
// Generator: contracts/codegen/gen_cpp.py // Generator: contracts/codegen/gen_cpp.py
// Contract: v1.2.0 // Contract: v1.3.0
// //
// Hand-editing this file is a merge blocker. Fix the schema and regenerate: // Hand-editing this file is a merge blocker. Fix the schema and regenerate:
// python3 contracts/codegen/gen_cpp.py // python3 contracts/codegen/gen_cpp.py
+18 -5
View File
@@ -3,7 +3,7 @@
// //
// Source: contracts/schema/** // Source: contracts/schema/**
// Generator: contracts/codegen/gen_cpp.py // Generator: contracts/codegen/gen_cpp.py
// Contract: v1.2.0 // Contract: v1.3.0
// //
// Hand-editing this file is a merge blocker. Fix the schema and regenerate: // Hand-editing this file is a merge blocker. Fix the schema and regenerate:
// python3 contracts/codegen/gen_cpp.py // python3 contracts/codegen/gen_cpp.py
@@ -27,7 +27,7 @@
// docs/adr/0009-generated-protocol-library.md. // docs/adr/0009-generated-protocol-library.md.
namespace velox::proto { namespace velox::proto {
inline constexpr std::string_view kProtocolVersion = "1.2.0"; inline constexpr std::string_view kProtocolVersion = "1.3.0";
/// Why a payload could not be turned into a typed value. `path` is a JSON Pointer /// Why a payload could not be turned into a typed value. `path` is a JSON Pointer
/// into the offending document, so a conformance failure names the exact field. /// into the offending document, so a conformance failure names the exact field.
@@ -750,9 +750,13 @@ struct Settings {
std::optional<std::int64_t> connection_maxActiveSegments{}; std::optional<std::int64_t> connection_maxActiveSegments{};
}; };
/// Why a task is in the failed or retry_wait state. Distinct from the JSON-RPC Error, which /// Why a task is in the failed, retry_wait, or (when the daemon paused it on its own initiative
/// describes a failed call rather than a failed download — the two live in different code /// rather than the user) paused state. Distinct from the JSON-RPC Error, which describes a
/// spaces on purpose, and `code` here is a TaskErrorCode string, never a JSON-RPC integer. /// failed call rather than a failed download — the two live in different code spaces on
/// purpose, and `code` here is a TaskErrorCode string, never a JSON-RPC integer. A pause the
/// user or the scheduler requested carries no error: this field only explains a paused state
/// the daemon entered unilaterally (auth_required, server_file_changed, disk_full and the
/// like), never a deliberate one.
struct TaskError { struct TaskError {
TaskErrorCode code{}; TaskErrorCode code{};
/// Human-readable, safe to show a user. Never carries a credential, a token or a full local /// Human-readable, safe to show a user. Never carries a credential, a token or a full local
@@ -808,6 +812,9 @@ struct TaskSummary {
std::string createdAt{}; std::string createdAt{};
std::optional<std::string> lastTryAt{}; std::optional<std::string> lastTryAt{};
std::optional<std::string> completedAt{}; std::optional<std::string> completedAt{};
/// Set when state is failed or retry_wait, and also when state is paused and the daemon entered
/// that state on its own initiative rather than at a user's or scheduler's request. null on
/// every other state, including a deliberate pause.
std::optional<TaskError> error{}; std::optional<TaskError> error{};
}; };
@@ -1394,6 +1401,12 @@ struct TaskStateEvent {
TaskState state{}; TaskState state{};
std::optional<TaskState> previousState{}; std::optional<TaskState> previousState{};
std::optional<TaskSummary> summary{}; std::optional<TaskSummary> summary{};
/// Set when the new state is failed or retry_wait, and also when it is paused and the daemon
/// entered that state on its own initiative — auth_required, server_file_changed, disk_full and
/// the like — rather than because of a user action, a schedule window closing, or an
/// admission-control decision. null on every other transition, including every
/// deliberately-requested pause. A client must not assume a paused task has no error just
/// because it usually doesn't; check this field rather than the state name alone.
std::optional<TaskError> error{}; std::optional<TaskError> error{};
}; };
+4 -2
View File
@@ -3,7 +3,7 @@
// //
// Source: contracts/schema/** // Source: contracts/schema/**
// Generator: contracts/codegen/gen_ts.py // Generator: contracts/codegen/gen_ts.py
// Contract: v1.2.0 // Contract: v1.3.0
// //
// Hand-editing this file is a merge blocker. Fix the schema and regenerate: // Hand-editing this file is a merge blocker. Fix the schema and regenerate:
// python3 contracts/codegen/gen_ts.py // python3 contracts/codegen/gen_ts.py
@@ -70,7 +70,9 @@ export interface EventMap {
"event.task.removed": TaskRemovedEvent; "event.task.removed": TaskRemovedEvent;
/** /**
* A task changed lifecycle state. Carries the summary so the row can be repainted in full * A task changed lifecycle state. Carries the summary so the row can be repainted in full
* without a round trip, and error whenever the new state is failed or retry_wait. * without a round trip, and error whenever the daemon has something to say about why: on
* every failed or retry_wait transition, and on a paused transition the daemon entered
* unilaterally rather than at a user's or scheduler's request.
*/ */
"event.task.state": TaskStateEvent; "event.task.state": TaskStateEvent;
} }
+1 -1
View File
@@ -3,7 +3,7 @@
// //
// Source: contracts/schema/** // Source: contracts/schema/**
// Generator: contracts/codegen/gen_ts.py // Generator: contracts/codegen/gen_ts.py
// Contract: v1.2.0 // Contract: v1.3.0
// //
// Hand-editing this file is a merge blocker. Fix the schema and regenerate: // Hand-editing this file is a merge blocker. Fix the schema and regenerate:
// python3 contracts/codegen/gen_ts.py // python3 contracts/codegen/gen_ts.py
+1 -1
View File
@@ -3,7 +3,7 @@
// //
// Source: contracts/schema/** // Source: contracts/schema/**
// Generator: contracts/codegen/gen_ts.py // Generator: contracts/codegen/gen_ts.py
// Contract: v1.2.0 // Contract: v1.3.0
// //
// Hand-editing this file is a merge blocker. Fix the schema and regenerate: // Hand-editing this file is a merge blocker. Fix the schema and regenerate:
// python3 contracts/codegen/gen_ts.py // python3 contracts/codegen/gen_ts.py
+20 -3
View File
@@ -3,7 +3,7 @@
// //
// Source: contracts/schema/** // Source: contracts/schema/**
// Generator: contracts/codegen/gen_ts.py // Generator: contracts/codegen/gen_ts.py
// Contract: v1.2.0 // Contract: v1.3.0
// //
// Hand-editing this file is a merge blocker. Fix the schema and regenerate: // Hand-editing this file is a merge blocker. Fix the schema and regenerate:
// python3 contracts/codegen/gen_ts.py // python3 contracts/codegen/gen_ts.py
@@ -11,7 +11,7 @@
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
export const PROTOCOL_VERSION = "1.2.0"; export const PROTOCOL_VERSION = "1.3.0";
/** /**
* Every error code the daemon may return. Adding one is a minor bump; changing the meaning * Every error code the daemon may return. Adding one is a minor bump; changing the meaning
@@ -646,9 +646,13 @@ export const TASK_ERROR_CODE_VALUES = [
] as const satisfies readonly TaskErrorCode[]; ] as const satisfies readonly TaskErrorCode[];
/** /**
* Why a task is in the failed or retry_wait state. Distinct from the JSON-RPC Error, which * Why a task is in the failed, retry_wait, or (when the daemon paused it on its own
* initiative rather than the user) paused state. Distinct from the JSON-RPC Error, which
* describes a failed call rather than a failed download the two live in different code * describes a failed call rather than a failed download the two live in different code
* spaces on purpose, and `code` here is a TaskErrorCode string, never a JSON-RPC integer. * spaces on purpose, and `code` here is a TaskErrorCode string, never a JSON-RPC integer.
* A pause the user or the scheduler requested carries no error: this field only explains a
* paused state the daemon entered unilaterally (auth_required, server_file_changed,
* disk_full and the like), never a deliberate one.
*/ */
export interface TaskError { export interface TaskError {
code: TaskErrorCode; code: TaskErrorCode;
@@ -716,6 +720,11 @@ export interface TaskSummary {
createdAt: string; createdAt: string;
lastTryAt?: string | null; lastTryAt?: string | null;
completedAt?: string | null; completedAt?: string | null;
/**
* Set when state is failed or retry_wait, and also when state is paused and the daemon
* entered that state on its own initiative rather than at a user's or scheduler's request.
* null on every other state, including a deliberate pause.
*/
error?: TaskError | null; error?: TaskError | null;
} }
@@ -1463,6 +1472,14 @@ export interface TaskStateEvent {
state: TaskState; state: TaskState;
previousState?: TaskState | null; previousState?: TaskState | null;
summary?: TaskSummary | null; summary?: TaskSummary | null;
/**
* Set when the new state is failed or retry_wait, and also when it is paused and the
* daemon entered that state on its own initiative auth_required, server_file_changed,
* disk_full and the like rather than because of a user action, a schedule window
* closing, or an admission-control decision. null on every other transition, including
* every deliberately-requested pause. A client must not assume a paused task has no error
* just because it usually doesn't; check this field rather than the state name alone.
*/
error?: TaskError | null; error?: TaskError | null;
} }
+1 -1
View File
@@ -3,7 +3,7 @@
// //
// Source: contracts/schema/** // Source: contracts/schema/**
// Generator: contracts/codegen/gen_ts.py // Generator: contracts/codegen/gen_ts.py
// Contract: v1.2.0 // Contract: v1.3.0
// //
// Hand-editing this file is a merge blocker. Fix the schema and regenerate: // Hand-editing this file is a merge blocker. Fix the schema and regenerate:
// python3 contracts/codegen/gen_ts.py // python3 contracts/codegen/gen_ts.py
+1 -1
View File
@@ -3,7 +3,7 @@
// //
// Source: contracts/schema/** // Source: contracts/schema/**
// Generator: contracts/codegen/gen_cpp.py // Generator: contracts/codegen/gen_cpp.py
// Contract: v1.2.0 // Contract: v1.3.0
// //
// Hand-editing this file is a merge blocker. Fix the schema and regenerate: // Hand-editing this file is a merge blocker. Fix the schema and regenerate:
// python3 contracts/codegen/gen_cpp.py // python3 contracts/codegen/gen_cpp.py