How to contribute

Contributions are welcome. This project values clear, practical, well-sourced content that follows consistent editorial, technical, and licensing standards.

You can contribute through any of the following workflows:

Content guidelines

Licensing

All contributions must comply with the project license at ./license.html. If any content (code, images, or other assets) is not covered by this license, clearly declare the exception at the beginning of the file and include the applicable license or permission notice.

Suggested exception notice format:

EXCEPTIONS:
files/images/thirdparty.jpg — licensed under CC BY 4.0 (see LICENSE in images/)
some-code/snippet.c — used with permission from upstream (MIT)

Method 1: Contributing via GitHub (gh / git)

This workflow is for contributors with GitHub accounts who prefer to collaborate online through pull requests (PRs).

  1. Fork the repository on GitHub.
  2. Clone your fork locally.
  3. Create a dedicated branch for your changes.
  4. Commit your work with a clear, descriptive commit message.
  5. Open a pull request that summarizes your contribution.

Recommended workflow using GitHub CLI:

gh repo fork daviduhden/cypherpunk-handbook --clone=true
cd cypherpunk-handbook
git switch -c my-article
git add articles/my-article.html data/articles.json
git commit -m "Add article: My Article"
git push --set-upstream origin my-article
gh pr create --fill

Alternative workflow using plain Git:

git clone https://github.com/daviduhden/cypherpunk-handbook.git
cd cypherpunk-handbook
git switch -c my-article
git add articles/my-article.html data/articles.json
git commit -m "Add article: My Article"
git push origin my-article

Method 2: Contributing via files and patches

This workflow is for contributors who prefer anonymous collaboration or do not use GitHub accounts.

Submitting individual files

Submitting Git patches (preferred)

git clone https://github.com/daviduhden/cypherpunk-handbook.git
cd cypherpunk-handbook
git switch -c my-contribution
git add articles/my-article.html data/articles.json
git commit -m "Add article: My Article"
git format-patch -1 HEAD

Send the generated .patch file(s) and other attachments uncompressed to the SimpleX group.

Method 3: Contributing via got (Game of Trees)

This workflow is for contributors on OpenBSD who prefer a patch-based process without relying on GitHub accounts.

Submitting Git-compatible patches using got (preferred)

got clone https://github.com/daviduhden/cypherpunk-handbook.git cypherpunk-handbook.git
got checkout cypherpunk-handbook.git cypherpunk-handbook
cd cypherpunk-handbook
got branch -c main my-contribution
got update -b my-contribution
got add articles/my-article.html
got add data/articles.json
got commit -m "Add article: My Article"
got diff main my-contribution > 0001-Add-article-My-Article.patch

Before committing, make sure GOT_AUTHOR is set or configured in got.conf / Git configuration, otherwise got commit will refuse to run.

Send the generated .patch file(s) and other attachments uncompressed to the administrator of this website via email.

The resulting patch is a standard unified diff, compatible with patch(1) and Git-based workflows.

Method 4: Contributing via archive snapshots

This workflow lets contributors work directly from the signed archive instead of the Git repository. It is useful for offline or anonymous contributions.

Steps:

  1. Download the latest signed archive and its checksum/signature from archive/cypherpunk-handbook.tar.gz.
  2. Verify the archive checksum and signature before extracting.
  3. Extract the archive into a temporary working directory:
    mkdir -p ~/cypherpunk-handbook-work
    tar -xzf cypherpunk-handbook.tar.gz -C ~/cypherpunk-handbook-work
    cd ~/cypherpunk-handbook-work
    
  4. Edit or add files as needed, following the site’s article templates and metadata requirements.
  5. Generate patch files based on the changes relative to the extracted archive:
    diff -Naur original/ modified/ > 0001-my-contribution.patch
    

    Tip: Use the extracted archive as original/ and your working directory as modified/.

  6. Send the generated .patch file(s) and other attachments uncompressed to the site's administrator or submission point (email or SimpleX group).

Submitting Articles

To publish a new article, create an HTML file in articles/ and include a header with the following elements:

<article>
  <header id="article-header">
    <p class="kicker">CATEGORY OR TAG</p>

    <h2>Article Title</h2>

    <p class="meta">By AUTHOR - Updated
      <time datetime="2025-01-01">DATE</time>
    </p>

    <p class="lede">One or two sentences that set reader expectations
    and highlight the value of the article.</p>

    <section>
      <h2>TL;DR</h2>
      <ul>
        <li>Primary takeaway or recommendation.</li>
        <li>Another concise outcome or decision.</li>
        <li>Links to supporting resources if helpful.</li>
      </ul>
    </section>
  </header>

Use the provided article template and update the following files:

data/articles.json Structure

The site uses data/articles.json as an index for articles and feeds. Each top-level key is an article ID (slug). Example:

{
  "my-article-slug": {
    "en": "articles/my-article.html",
    "pubdate": "2025-12-18",
    "title_en": "My Article Title"
  }
}

Set "pubdate" to an ISO date (YYYY-MM-DD) to control the publication date in feeds.

Author Metadata and Pseudonyms

Include the author name in the article header following the template (see the <p class="meta"> line in templates/articles.html ). The author can use a real name or a pseudonym; real names are optional.

After updating the article file and data/articles.json, regenerate the feeds or open a pull request. The maintainer will run the site scripts in scripts/ if needed.

Stripping metadata from files

Before submitting articles, images, videos, audio, or other assets, we recommend removing potentially sensitive metadata. For most file types, including SVG and PDF, mat2 (Metadata Anonymisation Toolkit 2) is the preferred tool. Video and audio files can be cleaned with ffmpeg.

Always verify that metadata was removed from the new file and that the file remains intact before submission.

Automation

Perl scripts in scripts/ can be used to update and rebuild the site.

perl ./scripts/update-guides.pl
perl ./scripts/update-feeds.pl articles/my-article.html
perl ./scripts/rebuild-feeds.pl

Requires Perl with JSON::PP

Downloading Archives & Using Proxies

A signed archive of the repository is available at archive/cypherpunk-handbook.tar.gz and is updated every 24 hours. The archive comes with a SHA256 hash and a signify signature.

Downloading the archive using curl

Default HTTPS download:

curl -O https://handbook.uhden.dev/archive/cypherpunk-handbook.tar.gz
curl -O https://handbook.uhden.dev/archive/cypherpunk-handbook.tar.gz.sig
curl -O https://handbook.uhden.dev/archive/cypherpunk-handbook.tar.gz.sha256

SOCKS5 proxy via TOR [1]:

curl --socks5-hostname 127.0.0.1:9050 -O http://5u6pytvslmtzmlheqsno2wt3vpyd7nggxhdgn533spyy2euaqwvpfbid.onion/archive/cypherpunk-handbook.tar.gz
curl --socks5-hostname 127.0.0.1:9050 -O http://5u6pytvslmtzmlheqsno2wt3vpyd7nggxhdgn533spyy2euaqwvpfbid.onion/archive/cypherpunk-handbook.tar.gz.sig
curl --socks5-hostname 127.0.0.1:9050 -O http://5u6pytvslmtzmlheqsno2wt3vpyd7nggxhdgn533spyy2euaqwvpfbid.onion/archive/cypherpunk-handbook.tar.gz.sha256

HTTP proxy via I2P [2]:

curl -p -x 127.0.0.1:4444 -O http://poy7mv4bgjnjgxq73hck72x5lnspvev4pnsiea2gdyegt7xpeg3q.b32.i2p/archive/cypherpunk-handbook.tar.gz
curl -p -x 127.0.0.1:4444 -O http://poy7mv4bgjnjgxq73hck72x5lnspvev4pnsiea2gdyegt7xpeg3q.b32.i2p/archive/cypherpunk-handbook.tar.gz.sig
curl -p -x 127.0.0.1:4444 -O http://poy7mv4bgjnjgxq73hck72x5lnspvev4pnsiea2gdyegt7xpeg3q.b32.i2p/archive/cypherpunk-handbook.tar.gz.sha256

Verifying the archive

Verify checksum and signature before extracting the archive.

Linux

Verify using the SHA256 file.

sha256sum -c cypherpunk-handbook.tar.gz.sha256

BSD

Compute SHA256 and compare it manually with the value in the SHA256 file.

sha256 cypherpunk-handbook.tar.gz
cat cypherpunk-handbook.tar.gz.sha256

Verify the signed archive:

signify -V -p cypherpunk-handbook.pub -x cypherpunk-handbook.tar.gz.sig -m cypherpunk-handbook.tar.gz.sha256

Extract the archive:

tar -xzf cypherpunk-handbook.tar.gz

Using Git with a proxy

Default (no proxy):

git clone https://github.com/daviduhden/cypherpunk-handbook.git

SOCKS5 proxy via TOR (global configuration)

git config --global http.proxy socks5://127.0.0.1:9050

Then clone normally:

git clone https://github.com/daviduhden/cypherpunk-handbook.git

HTTP proxy via I2P (global configuration)

git config --global http.proxy http://127.0.0.1:4444

Then clone normally:

git clone https://github.com/daviduhden/cypherpunk-handbook.git

SOCKS5 proxy via TOR (temporary for this command only)

git -c http.proxy=socks5://127.0.0.1:9050 clone https://github.com/daviduhden/cypherpunk-handbook.git

HTTP proxy via I2P (temporary for this command only)

git -c http.proxy=http://127.0.0.1:4444 clone https://github.com/daviduhden/cypherpunk-handbook.git

Global configuration (~/.gitconfig) affects all subsequent git pull, git push, and other commands. Temporary -c settings apply only to the specific command.

Tools Used

This guide and the workflows described here use the following common tools and utilities: