From 6db1689e7ea9d1bf14c4162b59a55c6fbccf8e6f Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 30 Nov 2022 22:39:18 -0800 Subject: [PATCH 01/14] v0.1 draft --- README.md | 507 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 506 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 739ceb8..d61dff1 100644 --- a/README.md +++ b/README.md @@ -1 +1,506 @@ -# IPVM Workflow Specification +# IPVM Workflow Specification v0.1.0 + +## Editors + +* [Brooklyn Zelenka](https://github.com/expede), [Fission](https://fission.codes) + +## Authors + +* [Brooklyn Zelenka](https://github.com/expede), [Fission](https://fission.codes) +* [Simon Worthington](https://github.com/simonwo), [Bacalhau Project](https://www.bacalhau.org/) + +## Language + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119](https://datatracker.ietf.org/doc/html/rfc2119). + +## Dependencies + +* [DAG-CBOR](https://ipld.io/specs/codecs/dag-cbor/spec/) +* [UCAN Invocation](https://github.com/ucan-wg/invocation/) +* [VarSig](https://github.com/ChainAgnostic/varsig/) + +# 0 Abstract + +An IPVM Workflow is a declarative cofiguration that extends a [UCAN Invocation](https://github.com/ucan-wg/invocation). A Workflow provides everything required to execute one or more tasks: defaults, tasks and their dependencies, authorization, metadata, signatures, and so on. + +# 1 Introduction + +> In late 1970 or early ’71 I approached IBM Canada’s Intellectual Property department to see if we could take out a patent on the basic idea [of dataflow]. Their recommendation, which I feel was prescient, was that this concept seemed to them more like a law of nature, which is not patentable. +> +> J. Paul Morrison, [Flow-Based Programming](https://jpaulm.github.io/fbp/book.html) + +The potential complexity of a fully distributed execution by untrusted peers is very high. IPVM Workflows reduce the number of possible states by forcing explicit handling of any dangerous effects. The IPVM Workflow spec is a declarative document that MAY be inspected, transmitted, logged, and negotiated. Unlike s systems like WASI, there is a strict separation of effects from pure data, an emphasis on verifiability, and [promise pipelining](http://erights.org/elib/distrib/pipeline.html). + +IPVM Workflows MUST be suitable for the proposal of workflows and negotiation with providers on a discovery layer (ahead of credential delegation), execution on untrusted peer machines, and verification. Workflows SHOULD provide a sufficiently expressive base to build more complex models such as actors, event-driven systems, map-reduce, and so on. + +## 1.1 Design Philosophy + +While IPVM in aggregate is capable of executing arbitrary programs, individual IPVM Workflows are specified declaratively, and tasks workflows MUST be acyclic. Invocation in the declarative style liberates the programmer from worrying about explicit sequencing, parallelism, memoization, distribution, and nontermination in a trustless settings. Such constraints also grants the runtime control and flexibility to schedule tasks in an efficient and safe manner. + +These constraints impose specific practices. There is no first-class concept of persistent objects or loops. Loops, actors, vats, concurrent objects, and so on MAY be implemented on top of IPVM Workflows by enqueuing new workflows with the effect system (much like a [mailbox receive loop](https://www.erlang.org/doc/efficiency_guide/processes.html)). + +## 1.2 Foundational Authority + +IPVM workflows are built on top of cryptographic capabilities, providing a strong basis for distributed computation in trustless networks. This even provides a clear basis for crossing Web 2.0 and Web3 systems, other computation networks, local operation (in full or part). + +The IPVM Workflow spec extends on several other specs that have been developed to provide this basis: + +``` +┌───────────────────────────────────────────────┬───────────────────────────┐ +│ │ │ +│ Human Configuration: │ │ +│ Defaults, Exception Handling, Comments, Tags │ │ +│ (IPVM Workflow) │ │ +│ │ Multi-Request Pipelining │ +├───────────────────────────────────────────────┤ (UCAN Invocation) │ +│ │ │ +│ IPVM Config, Verification Level, etc │ │ +│ (IPVM Task) │ │ +│ │ │ +├───────────────────────────────────────────────┴───────────────────────────┤ +│ │ +│ Call Graph │ +│ (UCAN Invocation) │ +│ │ +├───────────────────────────────────────────────────────────────────────────┤ +│ │ +│ Authority │ +│ (UCAN Core) │ +│ │ +└───────────────────────────────────────────────────────────────────────────┘ +``` + +# 2 Envelope + +The outer wrapper of a workflow MUST contain the following fields: + +| Field | Type | Description | Required | +|-----------------|------------|-------------------------------------------------------------------------|----------| +| `ipvm/workflow` | `Workflow` | IPVM Workflow | Yes | +| `signature` | `VarSig` | [VarSig](https://github.com/ChainAgnostic/varsig/) of serialized fields | Yes | + +| Field | Type | Description | Required | Default | +|------------|------------------------------|------------------------------------------------------------------------|----------|---------| +| `v` | `"0.1.0"` | IPVM workflow version | Yes | | +| `meta` | `{String : Any}` | User-defined object (tags, comments, etc) | No | `{}` | +| `parent` | `[&Workflow, Label] or Null` | The workflow & task label that initiated the current workflow (if any) | No | `Null` | +| `config` | `Config` | Global configuration (e.g. timeout for the entire workflow) | No | `{}` | +| `defaults` | `Config` | Individual task config defaults | No | `{}` | +| `tasks` | `UCAN.Invocation` | UCAN Invocation | Yes | | +| `catch` | `&WasmTask` | Deterministic Wasm that fires on exceptions | No | `{}` | + +## 2.1 Fields + +## 2.1.1 Version + +The `v` field MUST contain the IPVM Workflow version. + +## 2.1.2 Metadata + +The OPTIONAL `meta` field contains a user-definable JSON object. This is useful for including things like tags, comments, and so on. + +## 2.1.3 Parent + +The OPTIONAL `parent` field contains the CID of the IPVM Task that initiated it (if any). + +## 2.1.4 Config + +The OPTIONAL global [`config` object](#3-configuration) sets the configuration for the workflow itself, and defaults for tasks. + +## 2.1.5 Defaults + +The OPTIONAL `defaults` field configures default [configs](#3-configuration) for tasks. + +## 2.1.6 Tasks + +The `tasks` field contains all of the IPVM [Tasks](#4-task-configuration) set to run in this Workflow, each labelled by a human-readable key. + +## 2.1.7 Exception Handler + +The OPTIONAL `catch` field contains a Task with predefined inputs. See the [Exception Handling](#7-exception-handling) section for more deatil. + +## 2.2 IPLD Schema + +``` ipldsch +type SignedWorkflow struct { + work Workflow (rename "ipvm/workflow") + sig VarSig +} + +type Workflow struct { + v SemVer + meta {String : Any} (implicit {}) + parent nullable TaskRef (implicit Null) + global Config (implicit {}) + defauts Config (implicit {}) + tasks UCAN.Invocation + catch nullable &Wasm (implicit Null) +} + +type TaskRef struct { + inv &Invocation + task String -- Label for the task +} representation tuple +``` + +## 2.3 JSON Exmaples + +``` json +{ + "ipvm/workflow": { + "v": "0.1.0", + "meta": { + "tags": ["fission", "bacalhau", "dag-house"] + }, + "global": { + "time": [10, "minutes"], + }, + "defaults": { + "gas": 1000, + "memory": [10, "mega", "bytes"] + }, + "catch": "bafkreifsaaztjgknuha7tju6sugvrlbiwbyx5jf2pky2yxx5ifrpjscyhe", + "tasks": "ucan/invoke": { + "v": "0.1.0", + "nnc": "02468", + "prf": [ + {"/": "bafkreie2cyfsaqv5jjy2gadr7mmupmearkvcg7llybfdd7b6fvzzmhazuy"}, + {"/": "bafkreibbz5pksvfjyima4x4mduqpmvql2l4gh5afaj4ktmw6rwompxynx4"} + ], + "run": { + "notify-bob": { + "with": "mailto://alice@example.com", + "do": "msg/send", + "inputs": [ + { + "to": "bob@example.com", + "subject": "DNSLink for example.com", + "body": "Hello Bob!" + } + ], + "meta": { + "ipvm/config": { + "time": {"minutes": "30"}, + "secret": true + } + } + }, + "log-as-done": { + "with": "https://example.com/report" + "do": "crud/update" + "inputs": { + "from": "mailto://alice@exmaple.com", + "to": ["bob@exmaple.com"], + "event": "email-notification", + "value": {"ucan/promise": ["/", "notify-bob"]} // Pipelined promise + } + } + } + } + }, + "sig": {"/": {"bytes:": "5vNn4--uTeGk_vayyPuNTYJ71Yr2nWkc6AkTv1QPWSgetpsu8SHegWoDakPVTdxkWb6nhVKAz6JdpgnjABppC7"}} +} +``` + +# 3 Configuation + +The IPVM configuration struct defines secrecy, quotas, and verification strategy: + +| Field | Type | Description | Required | Default | +|----------|-------------------|-----------------------------------------|----------|--------------------------| +| `secret` | `Boolean or null` | Whether the output is unsafe to publish | No | `null` | +| `check` | `Verification` | Verification strategy | No | `"attestation"` | +| `time` | `TimeInterval` | Timeout | No | `[5, "minutes"]` | +| `memory` | `InfoSize` | Memory limit | No | `[100, "kilo", "bytes"]` | +| `disk` | `InfoSize` | Disk limit | No | `[10, "mega", "bytes"]` | +| `gas` | `Integer` | Gas limit | No | `1000` | + +This MAY be set globally or configured on [individual Tasks](#4-task-configuration). + +## 3.1 Fields + +### 3.1.1 Secret Flag + +The `secret` flag marks a task as being unsuitable for publication. + +If the `sceret` field is explicitely set, the task MUST be treated per that setting. If not set, the `secret` field defaults to `null`, which behaves as a soft `false`. If such a task consumes input from a `secret` source, it is also marked as `secret`. + +Note: there is no way to enforce secrecy at the task-level, so such tasks SHOULD only be negotiated with runners that are trusted. If secrecy must be inviolable, consider with [multi-party computation (MPC)](https://en.wikipedia.org/wiki/Secure_multi-party_computation) or [fully homomorphic encryption (FHE)](https://en.wikipedia.org/wiki/Homomorphic_encryption#Fully_homomorphic_encryption) inside the task. + +### 3.1.2 Verification Strategy + +The OPTIONAL `check` field MUST supply a verification strategy if present. If omitted, it MUST default to `"attestation"`. + +### 3.1.4 Time Quota + +The OPTIONAL `time` field configures the upper limit in wall-clock time that the executor SHOULD allow. + +### 3.1.5 Memory Quota + +The OPTIONAL `memory` field configures the upper limit in system memory that the executor SHOULD allow. + +### 3.1.6 Disk Quota + +The OPTIONAL `disk` field configures the upper limit in system memory that the executor SHOULD allow. + +### 3.1.7 Gas Quota + +The OPTIONAL `disk` field configures the upper limit in Wasm gas that the executor SHOULD allow. + +## 3.2 IPLD Schema + +``` ipldsch +type SystemConfig struct { + secret Boolean (implicit False) + check Verification (implicit Attestation) + gas Integer (implicit 0) + time optional TimeInterval + memory optional InfoSize + disk optional InfoSize +} +``` + +## 3.3 JSON Examples + +``` json +{ + "secret": true, + "check": {"optimistic": {"confirmations": 2, "referee": "did:key:zStEZpzSMtTt9k2vszgvCwF4fLQQSyA15W5AQ4z3AR6Bx4eFJ5crJFbuGxKmbma4"}}, + "gas": 5000, + "time": [45, "minutes"], + "memory": [500, "kilo", "bytes"], + "disk": [20, "mega", "bytes"] +} +``` + +# 4 Task Configuration + +> With hands of iron, there's not a task we couldn't do +> +> — [The Protomen](https://en.wikipedia.org/wiki/The_Protomen), The Good Doctor + +Tasks are the smallest level of work granularity a workflow. Tasks describe everything required to the negotate and execute all of the of work. IPVM Tasks are defined as a subtype of [UCAN Tasks](https://github.com/ucan-wg/invocation/blob/main/README.md#32-ipld-schema). Task types MAY require specific fields in the `inputs` field. Timeouts, gas, credits, transactional guarantees, result visibility, and so on MAY be separately confifured in the `ipvm/config` field. + +Tasks MAY be configured in aggragate in the [global defaults](#215-defaults). Individual Task configuration MUST be embedded inside of a [UCAN Action](https://github.com/ucan-wg/invocation)'s `meta['ipvm/confg']` field. + +## 4.1 Fields + +Recall UCAN Invocation Tasks: + +| Field | Type | Description | Required | Default | +|----------|------------------|------------------------------------------------|----------|---------| +| `with` | `URI` | | Yes | | +| `do` | `Ability` | | Yes | | +| `inputs` | `Any` | | Yes | | +| `meta` | `{String : Any}` | Fields that will be ignored during memoization | No | `{}` | + +An OPTIONAL IPVM `Config` MAY be included at the `meta['ipvm/config']` path. The `meta` field SHOULD not captured as part of task memoization, so this informtaion will be omitted from the distributed invocation table. If included, the `Config` MUST set the IPVM configuration for this Task, overwriting any of the fields on the envelope's top-level `defaults` field, or system-wide defaults. + +## 4.3 JSON Examples + +``` json +{ + "simple": { + "with": "dns://example.com?TYPE=TXT", + "do": "crud/update", + "inputs": { + "value": "hello world" + }, + "meta": { + "ipvm/config": { + "secret": false + "timeout": [500, "milli", "seconds"], + "verification": "attestation" + } + } + } +} +``` + +``` js +{ + "some-wasm": { + "with": "wasm:1:Qm12345", // Or something... wasm:Qm12345? + "do": "ipvm/run", + "inputs": { + "func": "calculate", + "args": [ + 1, + "hello world", + {"c": {"ucan/promise": ["/", "some-other-action"]}}, + {"a": 1, "b": 2, "c": 3} + ] + }, + "ipvm/config": { + "v": "0.1.0", + "secret": false, + "check": { + "optimistic": 17, + "referee": "did:key:zStEZpzSMtTt9k2vszgvCwF4fLQQSyA15W5AQ4z3AR6Bx4eFJ5crJFbuGxKmbma4" + } + } + } +} +``` + +``` json +{ + "with": "ipfs://bafkreidvq3uqoxcxr44q5qhgdk5zk6jvziipyxguirqa6tkh5z5wtpesva", + "do": "docker/run", + "inputs": { + "func": "calculate", + "args": [ + 1, + "hello world", + {"c": {"ucan/promise": ["/", "some-other-action"]}}, + {"a": 1, "b": 2, "c": 3} + ], + "container": { + "entry": "/", + "workdir": "/", + }, + "env": { + "$FOO": "bar" + } + }, + "meta": { + "ipvm/config": { + "v": "0.1.0", + "secret": false, + "check": { + "optimistic": 2, + "referee": "did:key:zStEZpzSMtTt9k2vszgvCwF4fLQQSyA15W5AQ4z3AR6Bx4eFJ5crJFbuGxKmbma4" + } + } + } +} +``` + +# 5 Exception Handler + +If present, the OPTIONAL `catch` field MUST be run in response to a `Task` returning on the `Failure` branch. The determinitsic & pure Wasm module MUST take a `Failure` object as input, and MUST return data in the following shape: + +``` ipldsch +type Handle union { + | Success "ok" -- End task with Success object + | String "rewire" -- Task name inside the current Workflow + | String "msg" -- Format the error message and panic +} respresentation keyed +``` + +If the `msg` branch is returned, the invocation MUST immedietly rethrow with the update message. + +Note that while IPVM MUST treat the pure tasks together as transactional. It is not possible to roll back any destructive effects that have already been run. As such, it is RECOMMENDED to have few (if any) tasks depend on the output of a destructive effect, so they can be scheduled at the end of the workflow. + +# 6 Receipt Output + +| Field | Type | Description | Required | Default | +|--------|-----------------|-----------------------------------------------------------------------|----------|---------| +| `inv` | `&Invocation` | CID of the Invocation that generated this response | Yes | | +| `out` | `{String: Any}` | The results of each call, the task's label. MAY contain sub-receipts. | Yes | | +| `meta` | `Any` | Non-normative extended fields | No | `null` | + +If the `catch` field is set on the outer `Workflow`, The `out` field MAY include the output under the `ipvm/catch` key + +# 7 Appendix + +## 7.1 Support Types + +``` ipldsch +type TimeUnit enum { + | Seconds + | Minutes + | Days + | Weeks + | Years +} + +type InfoUnit enum { + | Bits + | Nibble + | Bytes +} + +type Unit union { + | TimeUnit + | InfoUnit +} + +type SubPrefix enum { + | Pico "p" + | Nano "n" + | Micro "u" + | Milli "m" + | Centi "c" + | Deci "d" +} + +type SuperPrefix enum { + | Deca "da" + | Hecto "ha" + | Kilo "k" + | Mega "M" + | Giga "G" + | Tera "T" + | Peta "P" + | Exa "E" +} + +type SIPrefix union { + | SubPrefix + | SuperPrefix +} + +type TimeInterval struct { + magnitude Integer + prefix optional SIPrefix + unit TimeUnit +} representation tuple + +type InfoSize struct { + magnitude Integer + prefix optional SubPrefix + unit InfoUnit +} representation tuple + +type Measure union { + | TimeInterval + | InfoSize +} +``` + +## 7.1.1 JSON Examples + +``` json +[400, "nano", "seconds"] +[5, "seconds"] +[378, "exa", "bytes"] +``` + +# 8 Related Work and Prior Art + +The [Bacalhau Job (Alpha)](https://github.com/filecoin-project/bacalhau/blob/8568239299b5881bc90e3d6be2c9aa06c0cb3936/pkg/model/job.go#L113-L126) spec is a complete runner spec for Docker, Wasm, and Python source. At time of writing, it runs on a volunteer network, and has plans to integrate an authority layer. + +BucketVM and [`w3-machines`](https://github.com/web3-storage) are two approaches from [DAG House](https://dag.house) to extend UCAN to invocations and workflows. At time of writing, both approaches are focused on invocation inside a cloud microservice deployment. Configuration is not required, as jobs are not negotiated. + +[Cloud Native Builpacks](https://buildpacks.io/) are descriptions of an environment that stack together. They output an [OCI](https://opencontainers.org/) container. + +[GitHub Workflows](https://docs.github.com/en/actions/using-workflows) is a configuration to run one or more jobs, hooked into events on their platform. Workflows can be composed out of discrete actions or from other workflows. + +[Lambda Workflows](https://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dg-create-workflow.html) are a serverless workflow layer built on top of AWS, and thus integrates with their other offerings like IAM, S3, payments, and so on. + +[Project Naiad](https://www.microsoft.com/en-us/research/video/introducing-project-naiad-and-differential-dataflow/) and its lineage (e.g. [Timely Dataflow](https://timelydataflow.github.io/timely-dataflow/), [Differential Dataflow](https://timelydataflow.github.io/differential-dataflow/)) offer an extremely powerful dataflow model, including differential updates, control flow cycles, long running processes, but in a trusted environment. Such features could be supported for a subset of task types in IPVM in the future. + +[WarpForge Formulas](https://github.com/warptools/warpforge/blob/master/examples/100-formula-parse/example-formulas.md) describe how to reproducably build and cache packages. The functionality is a specialization of IPVM workflows, and may be configurable with IPVM in the future. + +# 9 Acknowledgments + +[Luke Marsden](https://github.com/lukemarsden) for a long fateful discussion while [stuck on a tarmac](https://www.theguardian.com/world/2022/nov/04/spanish-airspace-partially-closed-as-chinese-rocket-debris-falls-to-earth) about how to make IPVM and Bacalhau work more closely together. + +Thanks to [James Walker](https://github.com/walkah) for helping draw parallels between CIDs, IPLD, and raw bytes for promises in support of complex data pipelines. + +Many thanks to [Quinn Wilton](https://github.com/QuinnWilton) for her review of the spec, suggesting terms that would be most familiar to developers, talking through how to make the exception handling useful-but-safe in a static workflow, and suggesting further work involving fixed point computation. + +Many thanks to [Irakli Gozalishvili](https://github.com/Gozala) for the long discussions about invocation needs at [DAG House](https://dag.house), keeping the conversation grounded in a capabilities worldview, and for the many, many comments on various iterations of this spec across two repos. + +Thanks to [Blaine Cook](https://github.com/blaine) for several conversations about developer expectations and effect systems. From 789e3d5573f39c75dbdebbd5f193a5a40310b344 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 30 Nov 2022 22:45:42 -0800 Subject: [PATCH 02/14] Add actions --- .github/CODEOWNERS | 5 + .github/workflows/spellcheck.yml | 15 +++ .github/workflows/words-to-ignore.txt | 137 ++++++++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/workflows/spellcheck.yml create mode 100644 .github/workflows/words-to-ignore.txt diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..e6b25f6 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,5 @@ +# These owners will be the default owners for everything in +# the repo. Unless a later match takes precedence, +# @global-owner1 and @global-owner2 will be requested for +# review when someone opens a pull request. +* @expede diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml new file mode 100644 index 0000000..654a75f --- /dev/null +++ b/.github/workflows/spellcheck.yml @@ -0,0 +1,15 @@ +name: Spellcheck Action +on: push + +jobs: + build: + name: Spellcheck + runs-on: ubuntu-latest + steps: + # The checkout step + - uses: actions/checkout@master + - uses: matheus23/md-spellcheck-action@v3.0.0 + name: Spellcheck + with: + files-to-check: "**/*.md" + words-to-ignore-file: ./.github/workflows/words-to-ignore.txt diff --git a/.github/workflows/words-to-ignore.txt b/.github/workflows/words-to-ignore.txt new file mode 100644 index 0000000..17513f5 --- /dev/null +++ b/.github/workflows/words-to-ignore.txt @@ -0,0 +1,137 @@ +ABI +ACM +Agoric +Antigoals +AquaVM +Atomics +Auth +Autocodec +BYOL +Bacalhau +Berkley +BucketVM +CHa +CIDs +CLA +CapTP +Config +DNS +DSLs +Ericsson +FHE +FS +FVM +Filecoin +Frans +HydroLogic +IAM +IPC +IPFS +IPFS-FAN +IPLD +IPLI +IPNS +IPVM +JIT +JSON +Kaashoek +Lampson +Lemmer-Webber +Lifecycle +Linearizability +MERCHANTABILITY +Memoized +Memoizing +OCAP +OCaml +OCapN +Perlis +Plotkin +PoPs +Pre-Draft +Prenegotiated +README +Requestor +Riise +Roadmap +SPDX-License-Identifier +SPKI +STM +Saltzer +SemVer +Spiritely +TTL +Transactionality +UC +UCAN +UI +URI +VM +WASI +Wasm +Wasm-on-IPFS +WebAssembly +Zelenka +acceptor +acyclic +behaviours +codec +codecs +codename +cron +dataflow +de +decrypt +decrypted +defunctionalization +dereference +dereferencing +effectful +effectfulness +enqueuing +expede +facto +hardcoded +idempotence +individuals' +inspectable +low-ish +md +memoization +merchantability +micropayment +microservice +middleware +modelled +namespace +no_good_woman +non-effectful +non-sublicensable +nontermination +ocap +others' +patentable +pipelining +pre-resolved +preimage +prenegotiated +repos +requestor +runtimes +serverless +sexualized +signalling +socio-economic +spiral_calendar +struct +subjobs +subtype +tradeoff +transferee +trustless +ucan-chan +untrusted +v0 +wasm-ipfs +woman_scientist +world_map From a42bcc7fb5edd82d931ba73cc0916fe9cb0524ab Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 30 Nov 2022 22:49:29 -0800 Subject: [PATCH 03/14] Set up CLA bot & spellcheck config --- .spellcheck.yaml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .spellcheck.yaml diff --git a/.spellcheck.yaml b/.spellcheck.yaml new file mode 100644 index 0000000..80589fc --- /dev/null +++ b/.spellcheck.yaml @@ -0,0 +1,26 @@ +matrix: +- name: Markdown + aspell: + lang: en + d: en_US + dictionary: + encoding: utf-8 + wordlists: [".github/workflows/words-to-ignore.txt"] + pipeline: + - pyspelling.filters.markdown: + - pyspelling.filters.html: + comments: false + ignores: + - code + - pre + - pyspelling.filters.context: + context_visible_first: true + escapes: \\[\\`~] + delimiters: + - open: '(?s)^(?P *`{3,})$' + close: '^(?P=open)$' + - open: '(?P`+)' + close: '(?P=open)' + sources: + - 'README.md' + default_encoding: utf-8 From 0c6ec4456ee323308bb23c3661ceafeb400de7c5 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 30 Nov 2022 22:54:26 -0800 Subject: [PATCH 04/14] Fix much spelling --- .github/workflows/words-to-ignore.txt | 7 +++++++ README.md | 18 +++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/workflows/words-to-ignore.txt b/.github/workflows/words-to-ignore.txt index 17513f5..511dfb2 100644 --- a/.github/workflows/words-to-ignore.txt +++ b/.github/workflows/words-to-ignore.txt @@ -54,6 +54,7 @@ README Requestor Riise Roadmap +S3 SPDX-License-Identifier SPKI STM @@ -70,15 +71,18 @@ VM WASI Wasm Wasm-on-IPFS +Web3 WebAssembly Zelenka acceptor acyclic +aggragate behaviours codec codecs codename cron +cryptographic dataflow de decrypt @@ -95,6 +99,7 @@ hardcoded idempotence individuals' inspectable +labelled low-ish md memoization @@ -117,6 +122,7 @@ preimage prenegotiated repos requestor +rethrow runtimes serverless sexualized @@ -132,6 +138,7 @@ trustless ucan-chan untrusted v0 +verifiability wasm-ipfs woman_scientist world_map diff --git a/README.md b/README.md index d61dff1..fa933b6 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S # 0 Abstract -An IPVM Workflow is a declarative cofiguration that extends a [UCAN Invocation](https://github.com/ucan-wg/invocation). A Workflow provides everything required to execute one or more tasks: defaults, tasks and their dependencies, authorization, metadata, signatures, and so on. +An IPVM Workflow is a declarative configuration that extends a [UCAN Invocation](https://github.com/ucan-wg/invocation). A Workflow provides everything required to execute one or more tasks: defaults, tasks and their dependencies, authorization, metadata, signatures, and so on. # 1 Introduction @@ -117,7 +117,7 @@ The `tasks` field contains all of the IPVM [Tasks](#4-task-configuration) set to ## 2.1.7 Exception Handler -The OPTIONAL `catch` field contains a Task with predefined inputs. See the [Exception Handling](#7-exception-handling) section for more deatil. +The OPTIONAL `catch` field contains a Task with predefined inputs. See the [Exception Handling](#7-exception-handling) section for more detail. ## 2.2 IPLD Schema @@ -143,7 +143,7 @@ type TaskRef struct { } representation tuple ``` -## 2.3 JSON Exmaples +## 2.3 JSON Examples ``` json { @@ -202,7 +202,7 @@ type TaskRef struct { } ``` -# 3 Configuation +# 3 Configuration The IPVM configuration struct defines secrecy, quotas, and verification strategy: @@ -223,7 +223,7 @@ This MAY be set globally or configured on [individual Tasks](#4-task-configurati The `secret` flag marks a task as being unsuitable for publication. -If the `sceret` field is explicitely set, the task MUST be treated per that setting. If not set, the `secret` field defaults to `null`, which behaves as a soft `false`. If such a task consumes input from a `secret` source, it is also marked as `secret`. +If the `sceret` field is explicitly set, the task MUST be treated per that setting. If not set, the `secret` field defaults to `null`, which behaves as a soft `false`. If such a task consumes input from a `secret` source, it is also marked as `secret`. Note: there is no way to enforce secrecy at the task-level, so such tasks SHOULD only be negotiated with runners that are trusted. If secrecy must be inviolable, consider with [multi-party computation (MPC)](https://en.wikipedia.org/wiki/Secure_multi-party_computation) or [fully homomorphic encryption (FHE)](https://en.wikipedia.org/wiki/Homomorphic_encryption#Fully_homomorphic_encryption) inside the task. @@ -279,7 +279,7 @@ type SystemConfig struct { > > — [The Protomen](https://en.wikipedia.org/wiki/The_Protomen), The Good Doctor -Tasks are the smallest level of work granularity a workflow. Tasks describe everything required to the negotate and execute all of the of work. IPVM Tasks are defined as a subtype of [UCAN Tasks](https://github.com/ucan-wg/invocation/blob/main/README.md#32-ipld-schema). Task types MAY require specific fields in the `inputs` field. Timeouts, gas, credits, transactional guarantees, result visibility, and so on MAY be separately confifured in the `ipvm/config` field. +Tasks are the smallest level of work granularity a workflow. Tasks describe everything required to the negotiate and execute all of the of work. IPVM Tasks are defined as a subtype of [UCAN Tasks](https://github.com/ucan-wg/invocation/blob/main/README.md#32-ipld-schema). Task types MAY require specific fields in the `inputs` field. Timeouts, gas, credits, transactional guarantees, result visibility, and so on MAY be separately confifured in the `ipvm/config` field. Tasks MAY be configured in aggragate in the [global defaults](#215-defaults). Individual Task configuration MUST be embedded inside of a [UCAN Action](https://github.com/ucan-wg/invocation)'s `meta['ipvm/confg']` field. @@ -294,7 +294,7 @@ Recall UCAN Invocation Tasks: | `inputs` | `Any` | | Yes | | | `meta` | `{String : Any}` | Fields that will be ignored during memoization | No | `{}` | -An OPTIONAL IPVM `Config` MAY be included at the `meta['ipvm/config']` path. The `meta` field SHOULD not captured as part of task memoization, so this informtaion will be omitted from the distributed invocation table. If included, the `Config` MUST set the IPVM configuration for this Task, overwriting any of the fields on the envelope's top-level `defaults` field, or system-wide defaults. +An OPTIONAL IPVM `Config` MAY be included at the `meta['ipvm/config']` path. The `meta` field SHOULD not captured as part of task memoization, so this information will be omitted from the distributed invocation table. If included, the `Config` MUST set the IPVM configuration for this Task, overwriting any of the fields on the envelope's top-level `defaults` field, or system-wide defaults. ## 4.3 JSON Examples @@ -378,7 +378,7 @@ An OPTIONAL IPVM `Config` MAY be included at the `meta['ipvm/config']` path. The # 5 Exception Handler -If present, the OPTIONAL `catch` field MUST be run in response to a `Task` returning on the `Failure` branch. The determinitsic & pure Wasm module MUST take a `Failure` object as input, and MUST return data in the following shape: +If present, the OPTIONAL `catch` field MUST be run in response to a `Task` returning on the `Failure` branch. The deterministic & pure Wasm module MUST take a `Failure` object as input, and MUST return data in the following shape: ``` ipldsch type Handle union { @@ -388,7 +388,7 @@ type Handle union { } respresentation keyed ``` -If the `msg` branch is returned, the invocation MUST immedietly rethrow with the update message. +If the `msg` branch is returned, the invocation MUST immediately rethrow with the update message. Note that while IPVM MUST treat the pure tasks together as transactional. It is not possible to roll back any destructive effects that have already been run. As such, it is RECOMMENDED to have few (if any) tasks depend on the output of a destructive effect, so they can be scheduled at the end of the workflow. From d17f842cfbc3aa22cec40273b1c055610ce88e34 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 30 Nov 2022 22:56:37 -0800 Subject: [PATCH 05/14] Spelling --- .github/workflows/words-to-ignore.txt | 1 + README.md | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/words-to-ignore.txt b/.github/workflows/words-to-ignore.txt index 511dfb2..2f4e62a 100644 --- a/.github/workflows/words-to-ignore.txt +++ b/.github/workflows/words-to-ignore.txt @@ -85,6 +85,7 @@ cron cryptographic dataflow de +declaratively decrypt decrypted defunctionalization diff --git a/README.md b/README.md index fa933b6..894ad0e 100644 --- a/README.md +++ b/README.md @@ -279,9 +279,9 @@ type SystemConfig struct { > > — [The Protomen](https://en.wikipedia.org/wiki/The_Protomen), The Good Doctor -Tasks are the smallest level of work granularity a workflow. Tasks describe everything required to the negotiate and execute all of the of work. IPVM Tasks are defined as a subtype of [UCAN Tasks](https://github.com/ucan-wg/invocation/blob/main/README.md#32-ipld-schema). Task types MAY require specific fields in the `inputs` field. Timeouts, gas, credits, transactional guarantees, result visibility, and so on MAY be separately confifured in the `ipvm/config` field. +Tasks are the smallest level of work granularity a workflow. Tasks describe everything required to the negotiate and execute all of the of work. IPVM Tasks are defined as a subtype of [UCAN Tasks](https://github.com/ucan-wg/invocation/blob/main/README.md#32-ipld-schema). Task types MAY require specific fields in the `inputs` field. Timeouts, gas, credits, transactional guarantees, result visibility, and so on MAY be separately configured in the `ipvm/config` field. -Tasks MAY be configured in aggragate in the [global defaults](#215-defaults). Individual Task configuration MUST be embedded inside of a [UCAN Action](https://github.com/ucan-wg/invocation)'s `meta['ipvm/confg']` field. +Tasks MAY be configured in aggragate in the [global defaults](#215-defaults). Individual Task configuration MUST be embedded inside of a [UCAN Action's](https://github.com/ucan-wg/invocation) `meta['ipvm/confg']` field. ## 4.1 Fields @@ -491,7 +491,7 @@ BucketVM and [`w3-machines`](https://github.com/web3-storage) are two approaches [Project Naiad](https://www.microsoft.com/en-us/research/video/introducing-project-naiad-and-differential-dataflow/) and its lineage (e.g. [Timely Dataflow](https://timelydataflow.github.io/timely-dataflow/), [Differential Dataflow](https://timelydataflow.github.io/differential-dataflow/)) offer an extremely powerful dataflow model, including differential updates, control flow cycles, long running processes, but in a trusted environment. Such features could be supported for a subset of task types in IPVM in the future. -[WarpForge Formulas](https://github.com/warptools/warpforge/blob/master/examples/100-formula-parse/example-formulas.md) describe how to reproducably build and cache packages. The functionality is a specialization of IPVM workflows, and may be configurable with IPVM in the future. +[WarpForge Formulas](https://github.com/warptools/warpforge/blob/master/examples/100-formula-parse/example-formulas.md) describe how to reproducibly build and cache packages. The functionality is a specialization of IPVM workflows, and may be configurable with IPVM in the future. # 9 Acknowledgments From 151ea7e96374463373f31a8b4b2d1a23c8bac66a Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 30 Nov 2022 22:57:35 -0800 Subject: [PATCH 06/14] Remove JSON comment --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 894ad0e..fb4b265 100644 --- a/README.md +++ b/README.md @@ -192,7 +192,7 @@ type TaskRef struct { "from": "mailto://alice@exmaple.com", "to": ["bob@exmaple.com"], "event": "email-notification", - "value": {"ucan/promise": ["/", "notify-bob"]} // Pipelined promise + "value": {"ucan/promise": ["/", "notify-bob"]} } } } From c5e7ea0dd4d899a08e98300f5395a0997520ac32 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 30 Nov 2022 23:04:01 -0800 Subject: [PATCH 07/14] Update Docker exmaple --- README.md | 83 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index fb4b265..9250ff2 100644 --- a/README.md +++ b/README.md @@ -298,30 +298,11 @@ An OPTIONAL IPVM `Config` MAY be included at the `meta['ipvm/config']` path. The ## 4.3 JSON Examples -``` json -{ - "simple": { - "with": "dns://example.com?TYPE=TXT", - "do": "crud/update", - "inputs": { - "value": "hello world" - }, - "meta": { - "ipvm/config": { - "secret": false - "timeout": [500, "milli", "seconds"], - "verification": "attestation" - } - } - } -} -``` - ``` js { "some-wasm": { - "with": "wasm:1:Qm12345", // Or something... wasm:Qm12345? - "do": "ipvm/run", + "with": "ipfs://bafkreicgincymfzzumcqcrpmquyildzqppa3s2gv3scfy2csaqpgqpp7ke", + "do": "wasm/run", "inputs": { "func": "calculate", "args": [ @@ -345,27 +326,36 @@ An OPTIONAL IPVM `Config` MAY be included at the `meta['ipvm/config']` path. The ``` json { - "with": "ipfs://bafkreidvq3uqoxcxr44q5qhgdk5zk6jvziipyxguirqa6tkh5z5wtpesva", - "do": "docker/run", - "inputs": { - "func": "calculate", - "args": [ - 1, - "hello world", - {"c": {"ucan/promise": ["/", "some-other-action"]}}, - {"a": 1, "b": 2, "c": 3} - ], - "container": { - "entry": "/", - "workdir": "/", + "set-dns": { + "with": "dns://example.com?TYPE=TXT", + "do": "crud/update", + "inputs": { + "value": "hello world" }, - "env": { - "$FOO": "bar" + "meta": { + "ipvm/config": { + "secret": false + "timeout": [500, "milli", "seconds"], + "verification": "attestation" + } } + } +} +``` + +``` json +{ + "with": "ipfs://bafkreidvq3uqoxcxr44q5qhgdk5zk6jvziipyxguirqa6tkh5z5wtpesva", + "can": "docker/run", + "inputs": { + "entrypoint": ["/", "home"], + "mounts": {"mnt": "/"}, + "outputs": {"tmp": "/tmp"}, + "env": {"$HELLO": "world"}, + "workdir": "/work" }, "meta": { "ipvm/config": { - "v": "0.1.0", "secret": false, "check": { "optimistic": 2, @@ -376,6 +366,25 @@ An OPTIONAL IPVM `Config` MAY be included at the `meta['ipvm/config']` path. The } ``` +``` json +{ + "with": {"ucan/promise": ["/", "previous_action"]}, + "can": "docker/run", + "inputs": { + "entrypoint": ["/", "home"], + "mounts": {"mnt": "/"}, + "outputs": {"tmp": "/tmp"}, + "env": {"$HELLO": "world"}, + "workdir": "/work" + }, + "meta": { + "ipvm/config": { + "disk": "200GB" + } + } +} +``` + # 5 Exception Handler If present, the OPTIONAL `catch` field MUST be run in response to a `Task` returning on the `Failure` branch. The deterministic & pure Wasm module MUST take a `Failure` object as input, and MUST return data in the following shape: From 3d7ddfd26e357522c1d954c1327a40113dd7ddd3 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 30 Nov 2022 23:06:40 -0800 Subject: [PATCH 08/14] Add to dict --- .github/workflows/words-to-ignore.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/words-to-ignore.txt b/.github/workflows/words-to-ignore.txt index 2f4e62a..e50d112 100644 --- a/.github/workflows/words-to-ignore.txt +++ b/.github/workflows/words-to-ignore.txt @@ -1,5 +1,4 @@ -ABI -ACM +ABACM Agoric Antigoals AquaVM @@ -24,6 +23,7 @@ FVM Filecoin Frans HydroLogic +I IAM IPC IPFS @@ -122,6 +122,7 @@ pre-resolved preimage prenegotiated repos +reproducibly requestor rethrow runtimes From 67aefef2b11c45654b20634056cb89b6ed06791d Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 30 Nov 2022 23:08:35 -0800 Subject: [PATCH 09/14] Consisstency in examples --- README.md | 59 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 9250ff2..1e647f7 100644 --- a/README.md +++ b/README.md @@ -313,7 +313,6 @@ An OPTIONAL IPVM `Config` MAY be included at the `meta['ipvm/config']` path. The ] }, "ipvm/config": { - "v": "0.1.0", "secret": false, "check": { "optimistic": 17, @@ -345,21 +344,23 @@ An OPTIONAL IPVM `Config` MAY be included at the `meta['ipvm/config']` path. The ``` json { - "with": "ipfs://bafkreidvq3uqoxcxr44q5qhgdk5zk6jvziipyxguirqa6tkh5z5wtpesva", - "can": "docker/run", - "inputs": { - "entrypoint": ["/", "home"], - "mounts": {"mnt": "/"}, - "outputs": {"tmp": "/tmp"}, - "env": {"$HELLO": "world"}, - "workdir": "/work" - }, - "meta": { - "ipvm/config": { - "secret": false, - "check": { - "optimistic": 2, - "referee": "did:key:zStEZpzSMtTt9k2vszgvCwF4fLQQSyA15W5AQ4z3AR6Bx4eFJ5crJFbuGxKmbma4" + "run-docker": { + "with": "ipfs://bafkreidvq3uqoxcxr44q5qhgdk5zk6jvziipyxguirqa6tkh5z5wtpesva", + "do": "docker/run", + "inputs": { + "entrypoint": ["/", "home"], + "mounts": {"mnt": "/"}, + "outputs": {"tmp": "/tmp"}, + "env": {"$HELLO": "world"}, + "workdir": "/work" + }, + "meta": { + "ipvm/config": { + "secret": false, + "check": { + "optimistic": 2, + "referee": "did:key:zStEZpzSMtTt9k2vszgvCwF4fLQQSyA15W5AQ4z3AR6Bx4eFJ5crJFbuGxKmbma4" + } } } } @@ -368,18 +369,20 @@ An OPTIONAL IPVM `Config` MAY be included at the `meta['ipvm/config']` path. The ``` json { - "with": {"ucan/promise": ["/", "previous_action"]}, - "can": "docker/run", - "inputs": { - "entrypoint": ["/", "home"], - "mounts": {"mnt": "/"}, - "outputs": {"tmp": "/tmp"}, - "env": {"$HELLO": "world"}, - "workdir": "/work" - }, - "meta": { - "ipvm/config": { - "disk": "200GB" + "pipelined-docker-promise": { + "with": {"ucan/promise": ["/", "previous_action"]}, + "do": "docker/run", + "inputs": { + "entrypoint": ["/", "home"], + "mounts": {"mnt": "/"}, + "outputs": {"tmp": "/tmp"}, + "env": {"$HELLO": "world"}, + "workdir": "/work" + }, + "meta": { + "ipvm/config": { + "disk": "200GB" + } } } } From 5e56970e203d4fd7c92252b2de995dbd6a2f0370 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 30 Nov 2022 23:12:41 -0800 Subject: [PATCH 10/14] JSON typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1e647f7..52c0251 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ type TaskRef struct { "memory": [10, "mega", "bytes"] }, "catch": "bafkreifsaaztjgknuha7tju6sugvrlbiwbyx5jf2pky2yxx5ifrpjscyhe", - "tasks": "ucan/invoke": { + "tasks": { "v": "0.1.0", "nnc": "02468", "prf": [ From 4a8a14c098a980c19c6ced87cd4c49222285edf9 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 30 Nov 2022 23:14:34 -0800 Subject: [PATCH 11/14] Better layout for a couple JSON examples --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 52c0251..9caa98c 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,7 @@ type TaskRef struct { ], "meta": { "ipvm/config": { - "time": {"minutes": "30"}, + "time": [30, "minutes"], "secret": true } } @@ -265,7 +265,12 @@ type SystemConfig struct { ``` json { "secret": true, - "check": {"optimistic": {"confirmations": 2, "referee": "did:key:zStEZpzSMtTt9k2vszgvCwF4fLQQSyA15W5AQ4z3AR6Bx4eFJ5crJFbuGxKmbma4"}}, + "check": { + "optimistic": { + "confirmations": 2, + "referee": "did:key:zStEZpzSMtTt9k2vszgvCwF4fLQQSyA15W5AQ4z3AR6Bx4eFJ5crJFbuGxKmbma4" + } + }, "gas": 5000, "time": [45, "minutes"], "memory": [500, "kilo", "bytes"], From 6d564309d3ef9a2c9ccc0b2db0244a3ab5eb7fa2 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Fri, 2 Dec 2022 00:45:30 +0000 Subject: [PATCH 12/14] Update README.md Co-authored-by: Zeeshan Lakhani --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9caa98c..1e80211 100644 --- a/README.md +++ b/README.md @@ -245,7 +245,7 @@ The OPTIONAL `disk` field configures the upper limit in system memory that the e ### 3.1.7 Gas Quota -The OPTIONAL `disk` field configures the upper limit in Wasm gas that the executor SHOULD allow. +The OPTIONAL `gas` field configures the upper limit in Wasm gas that the executor SHOULD allow. ## 3.2 IPLD Schema From 7e8e0e020ead68408ecf1f7f05bf69a3659f9ab4 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Thu, 1 Dec 2022 17:05:12 -0800 Subject: [PATCH 13/14] Fix numbering --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1e80211..1c8395d 100644 --- a/README.md +++ b/README.md @@ -301,7 +301,7 @@ Recall UCAN Invocation Tasks: An OPTIONAL IPVM `Config` MAY be included at the `meta['ipvm/config']` path. The `meta` field SHOULD not captured as part of task memoization, so this information will be omitted from the distributed invocation table. If included, the `Config` MUST set the IPVM configuration for this Task, overwriting any of the fields on the envelope's top-level `defaults` field, or system-wide defaults. -## 4.3 JSON Examples +## 4.2 JSON Examples ``` js { From 993447c9a28430afe736c92f449c07fdeea6876f Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Fri, 2 Dec 2022 13:21:46 -0800 Subject: [PATCH 14/14] Update varsig spelling --- .github/workflows/words-to-ignore.txt | 1 + README.md | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/words-to-ignore.txt b/.github/workflows/words-to-ignore.txt index e50d112..2fce9c8 100644 --- a/.github/workflows/words-to-ignore.txt +++ b/.github/workflows/words-to-ignore.txt @@ -68,6 +68,7 @@ UCAN UI URI VM +Varsig WASI Wasm Wasm-on-IPFS diff --git a/README.md b/README.md index 1c8395d..0a68074 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S * [DAG-CBOR](https://ipld.io/specs/codecs/dag-cbor/spec/) * [UCAN Invocation](https://github.com/ucan-wg/invocation/) -* [VarSig](https://github.com/ChainAgnostic/varsig/) +* [Varsig](https://github.com/ChainAgnostic/varsig/) # 0 Abstract @@ -77,7 +77,7 @@ The outer wrapper of a workflow MUST contain the following fields: | Field | Type | Description | Required | |-----------------|------------|-------------------------------------------------------------------------|----------| | `ipvm/workflow` | `Workflow` | IPVM Workflow | Yes | -| `signature` | `VarSig` | [VarSig](https://github.com/ChainAgnostic/varsig/) of serialized fields | Yes | +| `signature` | `Varsig` | [Varsig](https://github.com/ChainAgnostic/varsig/) of serialized fields | Yes | | Field | Type | Description | Required | Default | |------------|------------------------------|------------------------------------------------------------------------|----------|---------| @@ -124,7 +124,7 @@ The OPTIONAL `catch` field contains a Task with predefined inputs. See the [Exce ``` ipldsch type SignedWorkflow struct { work Workflow (rename "ipvm/workflow") - sig VarSig + sig Varsig } type Workflow struct {