├── policy ├── haskell │ ├── README.md │ ├── packaging │ │ ├── README.md │ │ ├── distribution.md │ │ └── versioning.md │ └── ghc-version-policy.md ├── build.md ├── ci │ └── README.md ├── platforms.md ├── vcs.md ├── legal │ └── README.md ├── security │ └── README.md └── project │ └── README.md ├── .gitignore ├── practices ├── haskell │ ├── README.md │ ├── code-formatting.md │ ├── coding-style.md │ └── testing.md ├── ci │ └── README.md └── project │ └── README.md ├── book.toml ├── SECURITY.md ├── flake.nix ├── SUMMARY.md ├── flake.lock ├── .github └── workflows │ └── pages.yml ├── README.md ├── CONTRIBUTING.md ├── introduction.md └── CODE-OF-CONDUCT.md /policy/haskell/README.md: -------------------------------------------------------------------------------- 1 | # Haskell 2 | 3 | This section contains specific policies for projects written in Haskell. 4 | -------------------------------------------------------------------------------- /policy/build.md: -------------------------------------------------------------------------------- 1 | # Build, CI and Deployment 2 | 3 | This section contains policies on building code, CI, and deployment. 4 | -------------------------------------------------------------------------------- /policy/haskell/packaging/README.md: -------------------------------------------------------------------------------- 1 | # Packaging 2 | 3 | This section contains policies about packaging our Haskell software. 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # mdbook output folder 2 | book 3 | 4 | # direnv 5 | .direnv 6 | .envrc 7 | 8 | # nix 9 | result 10 | *~ 11 | -------------------------------------------------------------------------------- /practices/haskell/README.md: -------------------------------------------------------------------------------- 1 | # Haskell 2 | 3 | This section contains descriptions of common practices in writing Haskell code. 4 | -------------------------------------------------------------------------------- /book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["The Cardano Engineering Team"] 3 | language = "en" 4 | multilingual = false 5 | src = "." 6 | title = "Cardano Engineering Handbook" 7 | -------------------------------------------------------------------------------- /policy/ci/README.md: -------------------------------------------------------------------------------- 1 | # CI 2 | 3 | ## Exercise supported platforms and build methods 4 | 5 | If your project claims to support platform X then it SHOULD build on platform X in CI. 6 | Otherwise it is very easy for support to be lost without noticing, which may only be discovered much later, perhaps by a user. 7 | 8 | Similarly, if you claim to support a particular build method (e.g. bare `cabal` on Linux), then you should also exercise this in your CI. 9 | 10 | -------------------------------------------------------------------------------- /policy/platforms.md: -------------------------------------------------------------------------------- 1 | # Platform support 2 | 3 | Projects which are dependencies of the Cardano node MUST support all of: 4 | - Linux 5 | - MacOS 6 | - Windows (cross-compilation is acceptable, even recommended) 7 | 8 | This means that the project must compiled _and_ tested on those platforms. 9 | 10 | ## Rationale 11 | 12 | The Cardano node supports all of these platforms, so all of its upstream dependencies must do so also, otherwise that will block the node. 13 | -------------------------------------------------------------------------------- /practices/haskell/code-formatting.md: -------------------------------------------------------------------------------- 1 | # Code formatting 2 | 3 | It's generally a good idea to have an automatic code formatter, since it reduces arguments about stylistic matters (sometimes replacing them with arguments about the choice of formatter!). 4 | 5 | Different projects use different formatters, but the common ones are: 6 | - [`ormolu`](https://hackage.haskell.org/package/ormolu): a very opinionated formatter with no configuration that formats everything 7 | - Used by: `cardano-ledger` 8 | - [`stylish-haskell`](https://hackage.haskell.org/package/stylish-haskell): a less opinionated and less complete formatter 9 | - Used by: `plutus`, `ouroboros-network`, `cardano-node` 10 | 11 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | Please report (suspected) security vulnerabilities to security@iohk.io. You will receive a 6 | response from us within 48 hours. If the issue is confirmed, we will release a patch as soon 7 | as possible. 8 | 9 | Please provide a clear and concise description of the vulnerability, including: 10 | 11 | * the affected component(s) and version(s), 12 | * steps that can be followed to exercise the vulnerability, 13 | * any workarounds or mitigations 14 | 15 | If you have developed any code or utilities that can help demonstrate the suspected 16 | vulnerability, please mention them in your email but ***DO NOT*** attempt to include them as 17 | attachments as this may cause your Email to be blocked by spam filters. 18 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "A very basic flake"; 3 | 4 | inputs = { 5 | nixpkgs = { 6 | type = "github"; 7 | owner = "NixOS"; 8 | repo = "nixpkgs"; 9 | ref = "nixos-unstable"; 10 | flake = false; 11 | }; 12 | flake-utils.url = "github:numtide/flake-utils"; 13 | }; 14 | 15 | outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: 16 | let 17 | pkgs = import nixpkgs { inherit system; }; 18 | handbook = pkgs.runCommand "handbook" { nativeBuildInputs = [pkgs.mdbook]; } '' 19 | mdbook build --dest-dir "$out" ${self} 20 | ''; 21 | in { 22 | packages = { 23 | inherit handbook; 24 | }; 25 | devShell = pkgs.mkShell { 26 | buildInputs = [ pkgs.mdbook ]; 27 | }; 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /policy/vcs.md: -------------------------------------------------------------------------------- 1 | # Version Control System 2 | 3 | Projects MUST use a _Version Control System_ to ensure changes to the code source are properly tracked and individual changes can be identified and referred to easily. 4 | [git](https://git-scm.com) is the most widespread tool in use those days but there are many good tools to choose from. 5 | 6 | When releasing a new version of a software package, projects MUST use _tags_ or any similar mechanism -- symbolic reference -- to identify in the VCS the revision that corresponds to the newly released package. 7 | This tag MUST match the version number of the released package such that it's straightforward to link both. 8 | 9 | Projects SHOULD document their tagging convention. 10 | 11 | * Version `1.2.3` of a package `X` could be tagged as `1.2.3` or `v1.2.3` or `X-1.2.3`, etc. 12 | * Project `P` releasing two packages `X` and `Y` respectively with version `1.2.3` and `2.3.4` could tag the same revision with `X-1.2.3` and `Y-2.3.4` 13 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # The Cardano Engineering Handbook - Policies 2 | 3 | [Introduction](./introduction.md) 4 | 5 | # Policies 6 | 7 | - [Project management](./policy/project/README.md) 8 | 9 | - [Legal]() 10 | - [Security & Responsible Disclosure](./policy/security/README.md) 11 | - [Build, CI and Deployment](./policy/build.md) 12 | - [Platform support](./policy/platforms.md) 13 | - [CI](./policy/ci/README.md) 14 | - [Version Control](./policy/vcs.md) 15 | - [Haskell](./policy/haskell/README.md) 16 | - [GHC version policy](./policy/haskell/ghc-version-policy.md) 17 | - [Packaging](./policy/haskell/packaging/README.md) 18 | - [Distribution](./policy/haskell/packaging/distribution.md) 19 | - [Versioning](./policy/haskell/packaging/versioning.md) 20 | 21 | # Practices 22 | 23 | - [Project management](./practices/project/README.md) 24 | - [Haskell](./practices/haskell/README.md) 25 | - [Testing](./practices/haskell/testing.md) 26 | - [Code formatting](./practices/haskell/code-formatting.md) 27 | - [Coding style](./practices/haskell/coding-style.md) 28 | - [CI](./practices/ci/README.md) 29 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "locked": { 5 | "lastModified": 1659877975, 6 | "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", 7 | "owner": "numtide", 8 | "repo": "flake-utils", 9 | "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "owner": "numtide", 14 | "repo": "flake-utils", 15 | "type": "github" 16 | } 17 | }, 18 | "nixpkgs": { 19 | "flake": false, 20 | "locked": { 21 | "lastModified": 1662019588, 22 | "narHash": "sha256-oPEjHKGGVbBXqwwL+UjsveJzghWiWV0n9ogo1X6l4cw=", 23 | "owner": "NixOS", 24 | "repo": "nixpkgs", 25 | "rev": "2da64a81275b68fdad38af669afeda43d401e94b", 26 | "type": "github" 27 | }, 28 | "original": { 29 | "owner": "NixOS", 30 | "ref": "nixos-unstable", 31 | "repo": "nixpkgs", 32 | "type": "github" 33 | } 34 | }, 35 | "root": { 36 | "inputs": { 37 | "flake-utils": "flake-utils", 38 | "nixpkgs": "nixpkgs" 39 | } 40 | } 41 | }, 42 | "root": "root", 43 | "version": 7 44 | } 45 | -------------------------------------------------------------------------------- /practices/haskell/coding-style.md: -------------------------------------------------------------------------------- 1 | # Coding style 2 | 3 | Most project teams develop some opinions on how they want to write code. 4 | It can be helpful to write these down, to help with onboarding new people and to provide a place to explain such decisions. 5 | 6 | Here are some style guides written by Cardano teams: 7 | - [`plutus`](https://github.com/input-output-hk/plutus/blob/master/STYLEGUIDE.adoc) 8 | - [Adrestia](https://input-output-hk.github.io/adrestia/code) 9 | - [`hydra`](https://github.com/input-output-hk/hydra-poc/wiki/Coding-Standards) 10 | - [Consensus team in `ouroboros-network`](https://github.com/input-output-hk/ouroboros-network/blob/master/ouroboros-consensus/docs/StyleGuide.md) 11 | - [Network team in `ouroboros-network`](https://github.com/input-output-hk/ouroboros-network/blob/master/docs/StyleGuide.md) 12 | 13 | And here are some public style guides: 14 | - [Johann Tibell](https://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md) 15 | - [Kowainik](https://kowainik.github.io/posts/2019-02-06-style-guide) 16 | - [Enso](https://enso.org/docs/developer/enso/style-guide/haskell.html) 17 | - [CMS](http://courses.cms.caltech.edu/cs11/material/haskell/misc/haskell_style_guide.html) 18 | - [ANU](https://comp.anu.edu.au/courses/comp1100/resources/04-style/) 19 | -------------------------------------------------------------------------------- /.github/workflows/pages.yml: -------------------------------------------------------------------------------- 1 | name: Build and publish 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | # allows you to run this manually 9 | workflow_dispatch: 10 | 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.ref }} 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | 21 | - name: Setup mdBook 22 | uses: peaceiris/actions-mdbook@v1 23 | with: 24 | mdbook-version: '0.4.10' 25 | # mdbook-version: 'latest' 26 | 27 | - run: mdbook build 28 | 29 | - name: Upload artifact 30 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' 31 | uses: actions/upload-pages-artifact@v1 32 | with: 33 | path: ./book 34 | 35 | deploy: 36 | runs-on: ubuntu-latest 37 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' 38 | needs: build 39 | 40 | concurrency: 41 | group: "pages" 42 | cancel-in-progress: true 43 | 44 | # Grant GITHUB_TOKEN the permissions required to make a Pages deployment 45 | permissions: 46 | contents: write 47 | id-token: write 48 | pages: write 49 | 50 | # Deploy to the github-pages environment 51 | environment: 52 | name: github-pages 53 | url: ${{ steps.deployment.outputs.page_url }} 54 | 55 | steps: 56 | - name: Deploy to GitHub Pages 57 | id: deployment 58 | uses: actions/deploy-pages@v1 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Cardano Engineering Handbook 2 | 3 | This is the source repository for the [Cardano Engineering Handbook](https://input-output-hk.github.io/cardano-engineering-handbook/), which contains _cross-project_ policies and information that relate to all the projects in the Cardano Open Source Consortium. 4 | 5 | ## History 6 | 7 | In September 2022, right before the Vasil hard fork, _Input Output Global_ held a workshop in Lisbon with the Core engineering team in order to reflect on the development process of Cardano and identify areas for improvement, especially in the light of the increasing move towards open development. 8 | This handbook is one of the initiatives that came out of that workshop, since in order to truly have open development we need a place to record and discuss cross-project engineering matters which is open to _all_ contributors to the project. 9 | 10 | # Building the book 11 | 12 | The book can be built with the [`mdbook`](https://rust-lang.github.io/mdBook/) executable. 13 | 14 | ## Setup 15 | 16 | * If you use Nix, you can get a shell with `mdbook` using `nix develop`. 17 | * If you don't use nix, please follow the [Installation instructions](https://rust-lang.github.io/mdBook/guide/installation.html) on the _mdbook_ website. 18 | 19 | ## Building 20 | 21 | Simply run the following command at the toplevel directory: 22 | 23 | ``` 24 | $ mdbook build 25 | 2022-09-09 09:40:08 [INFO] (mdbook::book): Book building has started 26 | 2022-09-09 09:40:08 [INFO] (mdbook::book): Running the html backend 27 | ``` 28 | 29 | This will create a `book/` directory with the formatted book as an 30 | HTML website. Opening the `book/index.html` should display it in your 31 | current browser. 32 | -------------------------------------------------------------------------------- /practices/haskell/testing.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | 3 | This describes various testing practices which are in use in the Cardano project, along with examples for reference and links to commonly used libraries. 4 | 5 | ## Unit testing 6 | 7 | Unit testing is standard practice in the industry and Cardano is no exception. 8 | 9 | ### Libraries 10 | 11 | - [`tasty`](https://hackage.haskell.org/package/tasty): a straightforward testing framework, with many libraries that provide additional functionality 12 | - [`hspec`](https://hackage.haskell.org/package/tasty): another testing framework, with a BDD-style specification style 13 | 14 | ## Property-based testing 15 | 16 | Cardano makes extensive use of property-based testing. 17 | We believe it to be an excellent technique that allows us to get much higher testing assurance that we would be able to otherwise. 18 | 19 | ### Examples 20 | 21 | - [`cardano-ledger`](https://github.com/input-output-hk/cardano-ledger) uses QuickCheck to generate both transactions and "traces", in order to test the ledger rules. 22 | 23 | ### Libraries 24 | 25 | - [`QuickCheck`](https://hackage.haskell.org/package/QuickCheck): the original property-based testing library 26 | - [`hedgehog`](https://hackage.haskell.org/package/hedgehog): a more recent property-based testing library 27 | - [`quickcheck-dynamic`](https://hackage.haskell.org/package/quickcheck-dynamic): a library for testing stateful systems using QuickCheck 28 | 29 | ## Conformance testing 30 | 31 | Often our projects have specifications or research documents as well as an implementation. 32 | It is useful to test whether the specification conforms to the implementation. 33 | This sort of test suite is also useful if there are multiple implementations, as they can all share the use of the conformance test suite. 34 | 35 | ### Examples 36 | 37 | - [plutus](https://github.com/input-output-hk/plutus) has a hand-written conformance test suite. 38 | -------------------------------------------------------------------------------- /practices/ci/README.md: -------------------------------------------------------------------------------- 1 | ## GitHub Actions 2 | 3 | If you are using GitHub Actions it SHOULD be configured so that pull requests from forks will trigger it. 4 | This is especially important if the maintainer set up branch protection rules which prevent merging PRs which did not pass CI. 5 | This can be also confusing when there are no branch protection rules, in which case it could lead to accepting a PR which silently breaks the code. 6 | For these reasons we recommend being permissive on `pull_request` event and explicit on which branches trigger CI on `push` event, e.g. 7 | 8 | ```yaml 9 | on: 10 | pull_request: 11 | push: 12 | branches: 13 | - main 14 | ``` 15 | which will trigger only `pull_request` event for pull requests, but not `push` event when a PR is created. 16 | 17 | ## Merge Trains 18 | 19 | Merge trains allow to merge multiple outstanding pull request and check if all the changes are compatible. 20 | They usualy merge into a temporary branch which SHOULD be used to run CI on, as a side effect the CI infrastructure is triggered less often as PRs are batched. Examples of merge trains include: [`bors`], [`mergify`] or GitHub's own [`merge queue`]s. 21 | 22 | Specific configuration depends on the application one is using, for example when using [`bors`] one it's a good idea to configure GitHub Actions with: 23 | 24 | ```yaml 25 | on: 26 | pull_request: 27 | push: 28 | branches: 29 | - 'bors/*' 30 | ``` 31 | 32 | ## Running GitHub Actions for external contributors 33 | 34 | GitHub allows to configure which actions can run automatically from public forks. 35 | The maintainer ought to decide what level of security is required, please see the [GitHub documentation][workflows-from-public-forks]. 36 | 37 | 38 | [`bors`]: https://github.com/bors-ng/bors-ng 39 | [`mergify`]: https://mergify.com/ 40 | [`merge queue`]: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue 41 | [workflows-from-public-forks]: https://docs.github.com/en/actions/managing-workflow-runs/approving-workflow-runs-from-public-forks 42 | 43 | 44 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Cardano Engineering Handbook 2 | 3 | :construction: 4 | 5 | ## Communication channels 6 | 7 | Should you have any questions or need some help in getting set up, you can use 8 | these communication channels to reach the handbook team: 9 | 10 | * GitHub tools, mainly [Issues](https://github.com/input-output-hk/cardano-engineering-handbook/issues) and [Discussions](https://github.com/input-output-hk/cardano-engineering-handbook/discussions) 11 | * `#engineering` channel on IOG's slack 12 | 13 | ## Policies Acceptance Process 14 | 15 | * If you want to propose a new policy: 16 | * Do a PR changing the policy 17 | * Gather "rough" consensus -> Decider procedure 18 | * If it's accepted -> we should reach conformance into as many projects as possible 19 | * If it's rejected -> PR is closed 20 | * Exceptionally, the benevolent dictator(s) of the repository can step in to accept a propsal when there is a wide majority for acceptance and a tiny minority for rejection -> eg. we don't want good proposals to be blocked by the whims or opinions of 1 person 21 | * This process should take a reasonable amount of time 22 | 23 | ## Policies Content 24 | 25 | Handbook policies are typically guidelines rather than prescriptions (although some might be prescriptive). 26 | We expect each project under the umbrella of Cardano Open Source Consortium to use their judgement in applying policies, and there is no enforcement mechanism for most of them. 27 | 28 | Policy recommendations SHOULD use [RFC2119-style](https://www.ietf.org/rfc/rfc2119.txt) keywords. 29 | This makes it obvious where recommendations are being made. 30 | Since most policies are not prescriptive, most policies SHOULD primarily use SHOULD, with occasional use of MUST. 31 | 32 | A policy SHOULD include the rationale for its guidelines. 33 | This can be included near the guideline, or in its own section. 34 | There are two reasons for including rationales: 35 | 36 | 1. People are more likely to follow policies if they understand what the point is, or what advantages they will be giving up by deviating from it, 37 | 2. The Handbook is a living document, and for people to engage with it and evolve it they need to be able to disagree with, update, or replace the underlying justifications. 38 | 39 | A policy SHOULD be minimally prescriptive, unless specificity is needed to gain coordination benefits. 40 | Generally, we want to let people use their judgement, and avoid putting people off by being pointlessly prescriptive. 41 | However, in some circumstances we don't actually gain the benefit of the policy unless everyone follows it quite closely! 42 | -------------------------------------------------------------------------------- /practices/project/README.md: -------------------------------------------------------------------------------- 1 | # Project management 2 | 3 | ## Contributing documentation 4 | 5 | Contributing documentation is [highly recommended](../../policy/project/index.html). 6 | Contributing documentation is how we record the knowledge of how to work on the project day-to-day, rather than relying on it being passed on by word-of-mouth. 7 | So having good, comprehensive contributing documentation is vital to having a wide group of contributors. 8 | 9 | In addition to the information required by the [policy](../../policy/project/index.html), this is a (non-exhaustive!) list of topics that you may want to cover in your contributing documentation: 10 | 11 | - How should a contributor build the project? Are there any special environment setup instructions? Are there any special tools that need to be used, e.g. code formatters? 12 | - How are common maintenance tasks performed, e.g. updating dependencies? 13 | - Does the project have any coding standards that should be followed? 14 | - How is the project documented? What are the expectations on contributors for updating or adding documentation based on their changes? 15 | - Under what circumstances does a change require a design discussion beforehand? Is a ticket sufficient? Does the design need to be signed off by someone before an implementation will be accepted? 16 | - Under what circumstances does a change require a security audit? Whatever is written here should be compatible with the [audit policy](../../policy/security/audits.md), for most projects it should be sufficient to link to that. 17 | - Are there any additional non-automated tests that need to be run for certain kinds of change, e.g. performance tests? 18 | - Does the project have any requirements for how the Git history of changes is constructed, e.g. squashing changes, conventional commit messages? 19 | - Are code reviews required? What are the contributors responsibilities in terms of soliciting and responding to such reviews? 20 | - How does the project's CI work? How should a contributor interpret and diagnose failures? 21 | - How are releases performed? 22 | - Are there any legal restrictions on the project? What are the contributors obligations with respect to those, e.g. signing CLAs? 23 | 24 | Many of our projects have contributing documentation that you can use for inspiration: 25 | - [`cardano-node`](https://github.com/input-output-hk/cardano-node/blob/master/CONTRIBUTING.rst) 26 | - [`ouroboros-network`](https://github.com/input-output-hk/ouroboros-network/blob/master/CONTRIBUTING.md) 27 | - [`cardano-ledger`](https://github.com/input-output-hk/cardano-ledger/blob/master/CONTRIBUTING.md) 28 | - [`plutus`](https://github.com/input-output-hk/plutus/blob/master/CONTRIBUTING.adoc) 29 | -------------------------------------------------------------------------------- /policy/legal/README.md: -------------------------------------------------------------------------------- 1 | # Legal 2 | 3 | This section contains policies relating to legal matters. 4 | 5 | ## Licenses 6 | 7 | Software MUST be licensed using the Apache 2.0 license. 8 | Text-based work such as documentation SHOULD be licensed under a Creative Commons license. 9 | 10 | ## Applying the Apache 2.0 license to work 11 | 12 | To apply the Apache 2.0 license to your work, two separate files need to be created in the root of the repository: 13 | 14 | (1) a “NOTICE” file containing the following boilerplate notice: 15 | 16 | ``` 17 | Copyright 2022 Input Output Global, Inc. (IOG) 18 | 19 | Licensed under the Apache License, Version 2.0 (the "License”). 20 | You may not use this file except in compliance with the License. 21 | You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.txt 22 | 23 | Unless required by applicable law or agreed to in writing, 24 | software distributed under the License is distributed on an 25 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 26 | either express or implied. See the License for the specific 27 | language governing permissions and limitations under the License. 28 | ``` 29 | 30 | (2) a “LICENSE” file containing the full license text which can be obtained from [here](http://www.apache.org/licenses/LICENSE-2.0.txt). 31 | 32 | ### Rationale 33 | 34 | Apache 2.0 is a permissive license that is widely deployed and backed by a strong community. 35 | Apache 2.0 allows users the freedom to use the software for any purpose, to distribute it, to modify it, and to distribute modified versions of it under the terms of the license, without any concern about royalties. 36 | 37 | A key advantage of the Apache 2.0 license is that it contains provisions that are absent from many other free and open source licenses (including the MIT license) and which provide more clarity to contributors and users alike. 38 | 39 | However, for text we can typically be much less restrictive. 40 | For this a permissive license like Creative Commons is much more appropriate. 41 | 42 | ## Copyright assignment 43 | 44 | Statements asserting copyright SHOULD NOT be made. 45 | 46 | ### Rationale 47 | 48 | The provisions of the software license are more than adequate for the needs of the project. 49 | We do not believe there are situations where it would be necessary to rely on copyright protections of the code. 50 | 51 | Furthermore, this prevents us from needing burdensome CLAs to re-assign copyright from contributors. 52 | 53 | ## Disclaimers 54 | 55 | Projects MAY use a Disclaimer like the one below. 56 | This depends on the content of the project, and is usually only necessary if the project contains community contributions which are unvetted, or for which the maintainers are not willing to take responsibility for some other reason. 57 | 58 | ``` 59 | This site is for the benefit of the Cardano community and is owned and 60 | maintained by the community under an open source philosophy. 61 | Input Output Global, Inc. (IOG) is not responsible for, and makes no 62 | representations or warranties regarding, the accuracy, reliability and 63 | completeness of the aggregated content found in this repo. Any use of 64 | the open source Apache 2.0 licensed software is done at your own risk 65 | and on a “AS IS” basis, without warranties or conditions of any kind. 66 | ``` 67 | 68 | -------------------------------------------------------------------------------- /introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This document forms the Cardano Engineering Handbook, which aims to provide documentation and policy that applies to all projects in the Cardano Open Source Consortium (COSC). 4 | To avoid confusion, projects should [explicitly subscribe](policy/project/index.html) to the Handbook. 5 | 6 | The target audience for the Handbook is everyone working on a project owned by the COSC. 7 | This is also the set of target contributors for the Handbook! 8 | Anyone can submit a change proposal as a PR, see `CONTRIBUTING` for the process. 9 | 10 | ## Purpose 11 | 12 | The purpose of this handbook is both descriptive and prescriptive: 13 | 14 | * Firstly, it _prescribes_ mandatory or optional policies that should be followed by _any_ software project that's part of the COSC in order to be a good citizen within the eco-system. 15 | * Secondly, it _describes_ practices, processes, tools, or techniques that are used across the various projects, in order to help us to learn from each other and grow towards greater consistency in how we work. 16 | 17 | As such, it is composed of two parts: 18 | 19 | * Part I is about _policies_ 20 | * Part II is about _practices_ 21 | 22 | ## Goals 23 | 24 | The goals of the Handbook are to: 25 | * Provide a place to record decisions on topics where coordination across the engineering organization is useful. 26 | * Explicitly record "the way things are done" in order to minimize tribal knowledge. 27 | * Encourage consistency across the organization in order to minimize cognitive overheads from unnecessary differences. 28 | * Be open to all contributors to the Cardano Open Source Project. 29 | 30 | These are aspirational goals: much knowledge will not be recorded here; many topics we would like to coordinate on will be difficult to get consensus on; and consistency is not always welcome or desirable. 31 | But it is important to have an open location to record this information when we do have it. 32 | 33 | ### Non-goals 34 | 35 | The following are explicitly _not_ goals of the Handbook: 36 | * Enforce the following of policies which do not have widespread support amongst the Cardano developers. 37 | * We believe this is a bad idea which is likely to simply cause such prescriptions to be ignored. Consequently, the Handbook should only include policies that either have widespread agreement, or are _essential_ for coordination. Even then, policies should tend towards guidelines rather than prescriptions. 38 | * Collect all information relating to Cardano engineering. 39 | * The larger the Handbook, the harder it is to maintain. For this reason we aim to keep the scope relatively tight, although we may increase it later. 40 | * Supersede per-project contributing guidelines. 41 | * All of our projects are different, and the primary documentation for the development practices of a project should be its own contributing documentation. For suitably cross-project matters, the contributing documentation may link back to this Handbook, but the Handbook will never supersede it. 42 | 43 | ## Status 44 | 45 | The Handbook is very new and will gradually acquire more content over time. 46 | The other major issue is that many policies have been adapted from IOG policies, and are therefore IOG-specific in a way that is inappropriate for the COSC as a whole. 47 | We hope to improve all of this over time! 48 | 49 | Please consult the [issue tracker](https://github.com/input-output-hk/cardano-engineering-handbook/issues) to see what we're working on, and feel free to open issues for any additional problems. 50 | -------------------------------------------------------------------------------- /policy/haskell/ghc-version-policy.md: -------------------------------------------------------------------------------- 1 | # GHC Version policy 2 | 3 | This policy explains which versions of GHC should be used in a project. 4 | 5 | ## Which version of GHC should my project be using? 6 | 7 | At any given time there will be a current major version of GHC, and there may be a next major version of GHC, recorded in this document. 8 | 9 | New projects should build with the current version. 10 | 11 | The choice of minor version is less important, but in general projects SHOULD move to later minor versions as they are released. 12 | In particular, when adding support for a new major version, projects should always use the latest minor version of that major version (unless it is blacklisted, see below). 13 | 14 | ## Are there any versions of GHC that should never be used? 15 | 16 | Some versions of GHC are known to be broken in a critical way and SHOULD NOT be used. 17 | This may mean that projectes need to stay on an older minor version if the newer ones are blacklisted. 18 | 19 | ## How do we upgrade to new versions? 20 | 21 | The DevX team will proactively work on making code compatible with new compilers, and add CI (allowed to fail) for new compilers, as ressources permit. There is low priority 22 | and no one should feel pressured to add compatibility into tight schedules. Due to the nature of dependencies (internal and external), this work is hard to predict, and DevX 23 | will slowly work away at it. Once all code is compatible with a new compiler developers will be able to use a new compier _during development_, however _production builds_ will 24 | still be built against our current compiler version, and the current compiler version _must_ be green in CI. 25 | 26 | We will stay on the current compiler version, until cardano-node has signoff from performance and tracing, as well as quality engineering to move to the next version. After a 27 | grace persiod or 3mo afterwards, we can drop the old compiler version. 28 | 29 | ## What is the current major version of GHC? 30 | 31 | 8.10. 32 | 33 | ## What is the next major version of GHC? 34 | 35 | The next major version of GHC is 9.2, after that GHC 9.6. 36 | 37 | ## Which versions of GHC are blacklisted? 38 | 39 | - 9.0.x: first minor had critical bugs. 9.0.2 was released just to avoid creating an “abandoned release” precedent, as 9.2 was released before it and should be preferred. 40 | 41 | ## How does the next major version change? 42 | 43 | Cardano technical leadership will decide when to adopt new versions of GHC. 44 | This decision may be made on the basis of: 45 | 46 | - Maturity of the release 47 | - Bugs which block upgrading 48 | - Bugs which will be resolved by upgrading 49 | - Whether we are at key points in product release cycles 50 | - Whether essential libraries have been upgraded to the new version 51 | - Whether our custom tooling (e.g. GHCJS) is updated to work with it 52 | 53 | ## GHC version confidence status 54 | 55 | | Version | Status | Comments | 56 | | -- | -- | -- | 57 | | 8.10.(4+) | Stable | Current preferred version | 58 | | 9.0.* | Unclear | Not widely deployed, avoid | 59 | | 9.2.(4+) | Stable | Next preferred version. | 60 | 61 | ## Rationale 62 | 63 | Different major versions of GHC can be substantially different. 64 | In particular, programs may not compile with newer versions of GHC, or may have additional warnings. 65 | Hence, it make it much harder to integrate projects if they are tested on different major versions of GHC. 66 | 67 | That means that everything is much smoother if all the Caradano Haskell projects use the same version of GHC. 68 | But that also means that when we change the major version, we need to change it for every project relatively synchronously. 69 | 70 | Additionally, many versions of GHC have significant problems, particularly on specific platforms like Windows, and it's useful to have a central place to record decisions to avoid. 71 | -------------------------------------------------------------------------------- /policy/security/README.md: -------------------------------------------------------------------------------- 1 | 2 | - TODO: Need a contributor from our security teams to help write these. 3 | - TODO: security team to consider adopting [ASF policy](https://www.apache.org/security/committers.html) 4 | - TODO: Adapt draft audit requirements doc into the handbook. 5 | - TODO: Write a policy on foreign libraries. 6 | - DRAFTED: Write a policy on responsible disclosure. 7 | 8 | # Security 9 | 10 | Maintaining the security of the Cardano blockchain is a paramount 11 | concern. In any open source project there is a tension between maximising security and maintaining openness/transparency. Resolving this tension is especially important where some upgrades can only be carried out simultaneously (via a "hard fork" in Cardano), requiring a balance between the need for security and the desire for clear and precise communication/explanation of code changes. 12 | Consistent with other blockchain projects (e.g. [Ethereum](https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities)), we have therefore adopted a 13 | policy of responsible notification, responsible development, and responsible disclosure of 14 | security patches that prioritises security, but aims to provide clarity. Given the open nature of Cardano development, this requires particular 15 | care over how security issues are handled by code maintainers. 16 | 17 | 18 | ## Security Issues 19 | 20 | Standard IOG security procedures MUST be followed when a security concern is identified. 21 | In particular, possible security concerns MUST be notified via email to `security@iohk.io` or via IOG internal slack to `@charles.morgan`. 22 | 23 | All security concerns WILL be evaluated. If a vulnerability is deemed 24 | to exist, then a fix WILL be developed and released. All care WILL be 25 | taken not to expose the nature of the vulnerability, both during 26 | code development and as part of the release. This may include using a private 27 | fork for the development of the fix, including the fix as part of another code commit, 28 | taking appropriate care when writing code comments/descriptions, silent fixes, or other techniques. 29 | 30 | 31 | ## Responsible Disclosure 32 | 33 | 34 | In order to avoid calling attention to a vulnerability that may lead to a possible security exploit before the fix is fully deployed, it will usually be necessary to "silently" fix the vulnerability. This is particularly important in Cardano, compared to e.g. an operating system or application, since such fixes may only be enacted at (relatively infrequent) hard forks, nodes must connect to public network infrastructure, and all nodes will remain vulnerable until they are patched (the usual approach of a gradual security upgrade will not generally be possible). 35 | 36 | ### Silent Fixes 37 | 38 | Attention MUST NOT be called to security vulnerabilities before the vulnerability is fixed and deployed. **Silent fixes** MUST be used when necessary. That is: 39 | 40 | - the code SHOULD be obscured so that its purpose is not immediately clear; 41 | - comments, commit messages and documentation MUST not expose the security vulnerability; 42 | - a code patch SHOULD be included as part of a larger bundle of (possibly unrelated) changes; 43 | - the description of the fix SHOULD be intentionally vague, omitted or even misleading; 44 | - developers MUST refrain from commenting on discussions relating to the fix where this would call attention to the vulnerability. 45 | 46 | In all cases, security concerns override transparency considerations. 47 | 48 | ### Disclosure Procedures 49 | 50 | If we silently fix a vulnerability and a hard fork is needed to enable the fix then: 51 | 52 | - we SHOULD publish the details about the vulnerability 4-8 weeks after the hard fork 53 | 54 | If we silently fix a vulnerability and a hard fork is not needed to enable the fix then: 55 | 56 | - After 4-8 weeks, we SHOULD disclose that the release contained a security-fix; 57 | - After an additional 4-8 weeks, we SHOULD publish the details about the vulnerability 58 | -------------------------------------------------------------------------------- /policy/haskell/packaging/distribution.md: -------------------------------------------------------------------------------- 1 | # Distributing Haskell packages 2 | 3 | ## Distribution via CHaP 4 | 5 | Cardano packages which are not [released to Hackage](#distribution-via-hackage) MUST be released to [Cardano Haskell Packages (CHaP)](https://github.com/input-output-hk/cardano-haskell-packages) as part of their release process. 6 | The process for doing this is described in the CHaP README, any additional requirements described there MUST be followed. 7 | 8 | Cardano packages which depend on other Cardano packages SHOULD acquire them from CHaP and not through the use of `source-repository-package`s ([exceptions](#use-of-source-repository-packages)). 9 | The process for doing this is also described in the CHaP README. 10 | 11 | ### Rationale 12 | 13 | CHaP offers us a clear distribution method with proper versioning based on actual releases, without requiring us to actually publish to Hackage. 14 | This means we can be more relaxed in various ways (e.g. renaming packages) and also that we can publish patched versions of broken upstream dependencies unilaterally. 15 | 16 | In the past we used `source-repository-package` stanzas exclusively for distribution. 17 | This had all the problems discussed below, but also meant that downstream projects had to cobble together enormous lists of such stanzas in order to get a working build, which was very painful for `cardano-node`, and even worse for anything downstream of it. 18 | 19 | ## Distribution via Hackage 20 | 21 | A Cardano package which: 22 | 1. Is stable 23 | - Vague, but implies that it is unlikely to be significantly re-worked, renamed, etc. 24 | 2. Has broad value to the community 25 | - A test question is: would any non-Cardano package actually use it? 26 | 3. Has clear maintainership, ideally including individuals from multiple organizations 27 | 4. Reaches a high standard of documentation, testing, and open-source infrastructure 28 | - In particular, it should have high-quality examples of all the [recommended documents](../../project/README.html) 29 | 5. Is in full compliance with all [legal](../../legal/index.html) policies 30 | 6. Is developed in its own, standalone repository 31 | 32 | MAY be released to Hackage. 33 | The process for doing this is the normal process for releasing to Hackage. 34 | 35 | A package which is released to Hackage that was previously released to CHaP MUST be released to Hackage with a higher version number than any version number under which it appears in CHaP. 36 | 37 | The Hackage user [iogospo](https://hackage.haskell.org/user/iogospo) MUST be included as a maintainer of the package on Hackage. 38 | 39 | ### Rationale 40 | 41 | Publishing to Hackage is desirable because it makes it easier for the wider community to benefit from our work. 42 | We should do this, but only when we think they actually will benefit: when we have a stable, high-quality, useful packge to contribute. 43 | Much of the list of criteria is designed to make the package look like a "normal" open-source Haskell package repository (of high quality). 44 | 45 | ## Use of `source-repository-package`s 46 | 47 | A package which relies on `source-repository-package` stanzas to build MUST NOT be released to CHaP _or_ Hackage until they are removed. 48 | 49 | Use of `source-repository-package` stanzas is acceptable (or even recommended) in the following circumstances: 50 | - To experiment with a pre-release version of a Cardano package. 51 | - To pull in a fixed version of a dependency (not necessarily a Cardano one) where the fix has not been released yet. 52 | 53 | In the latter situation a long-lived or permanent fork can become unavoidable (e.g. if the upstream maintainer is unresponsive). 54 | In this case, a patched version SHOULD be released to CHaP (and must be in order to allow a release of the package which depends on it), see the CHaP README for more details. 55 | For packages which are released to Hackage, it may be necessary to request a Hackage takeover of the problematic dependency since we cannot unilaterally release a fixed version in that case. 56 | 57 | ### Rationale 58 | 59 | `source-repository-package`s do not interact well with package repositories like CHaP or Hackage. 60 | They implicitly assume that the `.cabal` file is a sufficient build recipe, but this is not true if the package relies on `source-repository-packge` stanzas. 61 | Therefore, uploading such a package to CHaP or Hackage simply means it probably won't work for downstream users. 62 | 63 | Additionally, `source-repository-package`s interact problematically with `cabal`, which always wants to rebuild them even if our tooling has ensured that a prebuilt version has been provided. 64 | In the past this seriously interfered with our ability to provide developers with pre-cached development environments, since `cabal` would insist on rebuilding many of the dependencies. 65 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, caste, color, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | [code-of-conduct@iohk.io](mailto:code-of-conduct@iohk.io). 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.1, available at 119 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 120 | 121 | Community Impact Guidelines were inspired by 122 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 123 | 124 | For answers to common questions about this code of conduct, see the FAQ at 125 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available 126 | at [https://www.contributor-covenant.org/translations][translations]. 127 | 128 | [homepage]: https://www.contributor-covenant.org 129 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 130 | [Mozilla CoC]: https://github.com/mozilla/diversity 131 | [FAQ]: https://www.contributor-covenant.org/faq 132 | [translations]: https://www.contributor-covenant.org/translations 133 | -------------------------------------------------------------------------------- /policy/project/README.md: -------------------------------------------------------------------------------- 1 | # Project management 2 | 3 | ## Subscribing to the Cardano Engineering Handbook 4 | 5 | A project SHOULD explicitly indicate that they follow the Cardano Engineering Handbook in their README. 6 | Projects MAY do this by using a badge. 7 | 8 | Consult [`shields.io`](https://shields.io/) for more information about how to embed this badge in your README. 9 | - Base badge URL: `https://img.shields.io/badge/policy-Cardano%20Engineering%20Handbook-informational` 10 | - Badge URL with link: `https://img.shields.io/badge/policy-Cardano%20Engineering%20Handbook-informational?link=https://input-output-hk.github.io/cardano-engineering-handbook` 11 | - Markdown fragment: `[![handbook](https://img.shields.io/badge/policy-Cardano%20Engineering%20Handbook-informational)](https://input-output-hk.github.io/cardano-engineering-handbook)` 12 | 13 | Projects which subscribe to the Cardano Engineering Handbook SHOULD track any deviations from policy in some appropriate public location, such as their issue tracker. 14 | 15 | ## Recommended documents 16 | 17 | A project SHOULD contain the following documents: 18 | - `README` 19 | - `CONTRIBUTING` 20 | - `SECURITY` 21 | - `CODE_OF_CONDUCT` 22 | - A `CHANGELOG` (if the project includes multiple packages or similar, then one `CHANGELOG` per package may be more appropriate) 23 | 24 | The documents SHOULD be easily accessible and discoverable, ideally by being put in standard locations. 25 | 26 | The content of these documents is largely up to the project contributors. 27 | The most important thing is that they exist, we believe that if they exist, people will mostly want to make them good. 28 | 29 | In the following, when we say that a document should include information, this can either mean it includes it directly, or that it clearly links to where it can be found. 30 | 31 | ### CONTRIBUTING 32 | 33 | A `CONTRIBUTING` document SHOULD include the following information: 34 | - [Roles and responsibilities](#roles-and-responsibilities) for the project. 35 | - The fact that the project follows this Handbook. 36 | 37 | See [the practices section](../../practices/project/index.html) for a broader discussion of what things are good to include in contributing documentation. 38 | 39 | ### SECURITY 40 | 41 | A `SECURITY` document MUST provide security@iohk.io as the contact email for security issues. 42 | 43 | Individual projects SHOULD use the [default security file in this repository](https://github.com/input-output-hk/cardano-engineering-handbook/blob/main/SECURITY.md), either by copying it or by creating a `SECURITY` document that just links to it. 44 | 45 | ### CODE OF CONDUCT 46 | 47 | Individual projects SHOULD use the [default Code of Conduct in this repository](https://github.com/input-output-hk/cardano-engineering-handbook/blob/main/CODE-OF-CONDUCT.md), either by copying it or creating a `CODE_OF_CONDUCT` document that just links to it. 48 | 49 | ## Roles and responsibilities 50 | 51 | A project SHOULD clearly identify any people who perform key functional roles. 52 | For example, most projects will have people in the following functional roles: 53 | - People who can merge PRs 54 | - People who can do any code review that the project requires 55 | - People who can adjudicate technical (or other) disputes 56 | - People who can release the software 57 | - People who can resolve issues with CI 58 | 59 | This is not an exhaustive list! 60 | Projects should list the roles that make sense for them. 61 | 62 | A project MAY identify some individual or individuals as the "maintainers". 63 | The meaning of this is not specified, as it is a common term in usage throughout the open-source world with various meanings, but it typically indicates that they are a "default" holder of functional roles. 64 | 65 | A project SHOULD also ensure that key functional roles have succession plans. 66 | In the simplest case this can just consist of ensuring that multiple maintainers are listed or that a backup maintainer is listed. 67 | 68 | ### Examples 69 | 70 | Projects can present this information however makes sense for them. 71 | For example, the following would be an acceptable presentation of this information for a moderately complex project: 72 | 73 | > The key maintainer for this project is Alice, who has final technical authority and handles releases. 74 | > The exception is component C where Bob is the authority. 75 | > Bob is also the backup maintainer in case Alice becomes unavailable. 76 | > 77 | > The rest of the regular contributors are Dave, Edna, and Fahran, all of whom can merge PRs and be asked to review them. 78 | > In addition, the CODEOWNERS file identifies specific reviewers who are required for PRs that affect specific components. 79 | > 80 | > The CI runs on Github Actions, so any contributor with write permissions can restart workflows. 81 | > Edna wrote the workflow specifications, so is the best person to help with problems, otherwise ask Dave. 82 | 83 | For a small project it would also be sufficient to write this: 84 | 85 | > This project is maintained by Gareth. 86 | > Hannah is the backup maintainer. 87 | 88 | ### Rationale 89 | 90 | Having clear roles and responsibilities is very useful for contributors. 91 | As they progress through the contribution workflow, it is important that they be able to identify people who can help them when they hit typical roadblocks, such as getting code reviews, merging PRs or adjudicating technical disputes. 92 | 93 | It's also important for the health of a project that for important roles there is some kind of plan for what to do in case the people who currently occupy them stop being able to do so. 94 | Otherwise it can be the case that nobody is maintaining a project, and nobody even notices! 95 | 96 | However, most of the details are project-specific. 97 | Exactly what roles make sense; who performs them; whether or not that descends from them having some other official role or not; what kind of backup plans make sense; all of these things can vary. 98 | For example, all of the following are reasonable project organization structures that we do not want to preclude: 99 | - A small group of co-maintainers who do everything. 100 | - A larger but very egalitarian team that attempts to share all responsibilities equally. 101 | - A very formalised team with explicit team roles and leadership positions. 102 | - A project which has multiple sub-components which have very different organization structures (e.g. a big project with a formal methods component that has a single maintainer) 103 | 104 | The main goals are just for projects to: 105 | 1. Identify the state of their roles and responsibilities explicitly, rather than relying on people just picking it up; and 106 | 2. Make some effort to ensure that key roles don't go unfilled. 107 | 108 | -------------------------------------------------------------------------------- /policy/haskell/packaging/versioning.md: -------------------------------------------------------------------------------- 1 | # Versioning Haskell packages 2 | 3 | TODO: need to decide on a versioning policy 4 | 5 | ## Version bounds 6 | 7 | ### Scope 8 | 9 | Library components of packages which are intended to be [distributed via a package repository](./distribution.md) MUST follow this policy. 10 | Non-library components of such packages MUST also do so if it is anticipated that they will be used downstream. 11 | 12 | (Inversely: components of packages which are not intended to be distributed, or non-library components of packages which are not intended to be used downstream do NOT need to follow this policy). 13 | 14 | #### Examples 15 | 16 | Package `pkg-a` contains a test suite and also an executable that is used to inspect binary blobs that can be produced by using `pkg-a`. 17 | The test suite is not intended to be used downstream, but the executable is, since it can be helpful for users to diagnose the products of `pkg-a`. 18 | Hence the test suite does not need bounds, but the executable does. 19 | 20 | #### Rationale 21 | 22 | Non-library components are much less critical, because they cannot be depended upon, and it is rarer that someone will want to e.g. run the tests or benchmarks for an upstream package. 23 | However, it can still be the case that this happens, especially for executables, which are sometimes explicitly intended to be used by downstream users. 24 | For this reason we tie the choice over whether to include bounds to the decision of the maintainer over whether the component is intended to be used downstream. 25 | 26 | ### Known-bad bounds 27 | 28 | Version bounds (both upper and lower) MUST be included when they exclude versions of dependencies that the package is known not to work with. 29 | In addition, if it is discovered that a version of a dependency does not work with a version of the package that has been released to a package repository, then the package maintainer SHOULD [publish](./distribution.md) a revision of the released version to include the new bound. 30 | 31 | #### Examples 32 | 33 | **Discovering an incompatible version** 34 | 35 | The developer of package `pkg-a`, which depends on library `pkg-b`, tries to build with `pkg-b-N`. 36 | This fails, so the developer should: 37 | 38 | 1. Add an upper bound of `pkg-b < N`, since `pkg-b-N` is known not to work; or 39 | 2. Fix `pkg-a` to work with `pkg-b-N`, and if this means that `pkg-a` will now no longer work with earlier versions of `pkg-b`, add a lower bound of `pkg-b >= N`. 40 | 41 | And then optionally publish a revision of some released versions of `pkg-a` to add upper bounds on `pkg-b-N` 42 | 43 | **Discovering an incompatible version for an upstream dependency** 44 | 45 | The developer of package `pkg-c`, which depends on `pkg-a-M`, tries to build with `pkg-b-N`. 46 | This fails when building `pkg-a`, so the developer of `pkg-c` notifies the developer of `pkg-a`. 47 | One of them should then: 48 | 1. Publish a revision `pkg-a-M` to have a bound of `pkg-b < N`; and 49 | 2. Add a bound of `pkg-b < N` to the development branch of `pkg-a` if it still applies. 50 | 51 | #### Rationale 52 | 53 | Excluding dependency versions which are *known* not to work is a cheap way to convey information to downstream users. 54 | It means that if they try to use the non-working version then they will get a solver error from cabal, instead of a compilation error. 55 | It is common to discover this kind of version incompatibility information during development, and so this policy primarily insists that such information be recorded mechanically so that other people benefit from it. 56 | 57 | ### Speculative upper bounds 58 | 59 | A package MAY include an upper bound that excludes the next major version of a dependency, even if it is not known whether the next major version will break the package (e.g. because it has not been released yet). 60 | 61 | #### Examples 62 | 63 | The package `pkg-b` depends on `pkg-a`. 64 | `pkg-a` tends to have breaking changes in releases, so the developer of `pkg-b` decides to pin their dependency on `pkg-a` using a caret bound, which implies a (speculative) upper bound of the next major version. 65 | 66 | The package `pkg-c` depends on `pkg-b`. 67 | The developer of `pkg-c` really doesn't want to have to deal with bumping the upper bound on `pkg-b`, so they just leave it off. 68 | Note that due to the above policy about discovering incompatible versions, when a version of `pkg-b` is released that _does_ break `pkg-c`, one of the developers should publish revisions to exclude the breaking version of `pkg-b` from the released versions of `pkg-c`. 69 | 70 | #### Rationale 71 | 72 | Speculative upper bounds are controversial. 73 | They have advantages (ensure that users get a working (if old) build plan; robustness against future changes), and disadvantages (often overly cautious; require large amounts of bound-relaxing to allow even "safe" new major versions). 74 | There is no consensus amongst the Cardano engineering community about which is preferable, so we simply note that either approach is acceptable. 75 | 76 | The cost of speculative upper bounds is somewhat lower for Cardano packages, since they are typically well-maintained and released frequently, so bounds relaxations can be made and released in a fairly timely fashion. 77 | Nonetheless, they still impose costs, in particular requiring that downstream packages be released in order for new versions to be used. 78 | 79 | ### Intra-repository dependencies 80 | 81 | A set of packages defined in the same source repository MUST include version bounds which are as tight as necessary to ensure that they function correctly when [distributed](./distribution.md) via a package repository. 82 | It is not possible to give a fully-general rule for what bounds to use, but assuming that the packages are following something like PVP, typically pinning the major version is the right thing to do. 83 | 84 | #### Examples 85 | 86 | Packages `pkg-a` and `pkg-b` are defined in the same source repository, and `pkg-a` depends on `pkg-b`. 87 | `pkg-a` is at version 1.1.2, `pkg-b` is at version 2.4.3, and they both follow the PVP. 88 | Then `pkg-a` should bound its dependency on `pkg-b` to `pkg-b == 2.4.*` 89 | 90 | #### Rationale 91 | 92 | Within a single source repository, packages are usually built with all the packages taken from a single commit of the source repository. 93 | When the packages are built from a package repository, then cabal may try to build them with _different_ versions, so long as the bounds are satisfied. 94 | For this reason it is important to have tight enough bounds on packages which are defined in the same source repository. 95 | Typically it should be enough to pin the major version. 96 | 97 | ### Implied bounds 98 | 99 | A component MAY omit bounds that it is otherwise required to have if those bounds are strictly implied by other dependencies that the package has within the _same_ source repository. 100 | 101 | ### Examples 102 | 103 | Package `pkg-a` has both a library component and an executable component, both of which are used downstream. 104 | Both components depend on `pkg-b-N`, and do not work with `pkg-b-(N+1)`, and the executable depends on the library. 105 | In this case it is acceptable to only put a `pkg-b < N+1` bound on the library, because the executable component strictly depends on the library component of the same version, and the library component has the bound. 106 | 107 | #### Rationale 108 | 109 | It is common to have a repository which has many components/packages depending on some other package P. 110 | It is tedious to require _every_ use of P to be well-bounded, especially since the components/packages in a repository should have tight bounds on each other, such that in practice bounding a single use of P should be enough to fix it for every package in the repository. 111 | Some care should be taken, however: it is easy to _think_ that all packages in the repository are constrained, when in fact there may be a few that don't depend on the one that bounds P. 112 | --------------------------------------------------------------------------------