···11+# tangled contributing guide
22+33+## commit guidelines
44+55+We follow a commit style similar to the Go project. Please keep commits:
66+77+* **atomic**: each commit should represent one logical change
88+* **descriptive**: the commit message should clearly describe what the
99+change does and why it's needed
1010+1111+### message format
1212+1313+```
1414+<service/top-level directory>: <package/path>: <short summary of change>
1515+1616+1717+Optional longer description, if needed. Explain what the change does and
1818+why, especially if not obvious. Reference relevant issues or PRs when
1919+applicable. These can be links for now since we don't auto-link
2020+issues/PRs yet.
2121+```
2222+2323+Here are some examples:
2424+2525+```
2626+appview: state: fix token expiry check in middleware
2727+2828+The previous check did not account for clock drift, leading to premature
2929+token invalidation.
3030+```
3131+3232+```
3333+knotserver: git/service: improve error checking in upload-pack
3434+```
3535+3636+### general notes
3737+3838+- PRs get merged as a single commit, so keep PRs small and focused. Use
3939+the above guidelines for the PR title and description.
4040+- Use the imperative mood in the summary line (e.g., "fix bug" not
4141+"fixed bug" or "fixes bug").
4242+- Try to keep the summary line under 72 characters, but we aren't too
4343+fussed about this.
4444+- Don't include unrelated changes in the same commit.
4545+- Avoid noisy commit messages like "wip" or "final fix"—rewrite history
4646+before submitting if necessary.
4747+4848+## proposals for bigger changes
4949+5050+Small fixes like typos, minor bugs, or trivial refactors can be
5151+submitted directly as PRs.
5252+5353+For larger changes—especially those introducing new features,
5454+significant refactoring, or altering system behavior—please open a
5555+proposal first. This helps us evaluate the scope, design, and potential
5656+impact before implementation.
5757+5858+### proposal format
5959+6060+Create a new issue titled:
6161+6262+```
6363+proposal: <affected scope>: <summary of change>
6464+```
6565+6666+In the description, explain:
6767+6868+- What the change is
6969+- Why it's needed
7070+- How you plan to implement it (roughly)
7171+- Any open questions or tradeoffs
7272+7373+We'll use the issue thread to discuss and refine the idea before moving
7474+forward.
+108
docs/knot-hosting.md
···11+# knot self-hosting guide
22+33+So you want to run your own knot server? Great! Here are a few prerequisites:
44+55+1. A server of some kind (a VPS, a Raspberry Pi, etc.). Preferably running a Linux of some kind.
66+2. A (sub)domain name. People generally use `knot.example.com`.
77+3. A valid SSL certificate for your domain.
88+99+There's a couple of ways to get started:
1010+* NixOS: refer to [flake.nix](https://tangled.sh/@tangled.sh/core/blob/master/flake.nix)
1111+* Docker: Documented below.
1212+* Manual: Documented below.
1313+1414+## docker setup
1515+1616+Clone this repository:
1717+1818+```
1919+git clone https://tangled.sh/@tangled.sh/core
2020+```
2121+2222+Modify the `docker/docker-compose.yml`, specifically the
2323+`KNOT_SERVER_SECRET` and `KNOT_SERVER_HOSTNAME` env vars. Then run:
2424+2525+```
2626+docker compose -f docker/docker-compose.yml up
2727+```
2828+2929+### manual setup
3030+3131+First, clone this repository:
3232+3333+```
3434+git clone https://tangled.sh/@tangled.sh/core
3535+```
3636+3737+Then, build our binaries (you need to have Go installed):
3838+* `knotserver`: the main server program
3939+* `keyfetch`: utility to fetch ssh pubkeys
4040+* `repoguard`: enforces repository access control
4141+4242+```
4343+cd core
4444+export CGO_ENABLED=1
4545+go build -o knot ./cmd/knotserver
4646+go build -o keyfetch ./cmd/keyfetch
4747+go build -o repoguard ./cmd/repoguard
4848+```
4949+5050+Next, move the `keyfetch` binary to a location owned by `root` --
5151+`/usr/local/libexec/tangled-keyfetch` is a good choice:
5252+5353+```
5454+sudo mv keyfetch /usr/local/libexec/tangled-keyfetch
5555+sudo chown root:root /usr/local/libexec/tangled-keyfetch
5656+sudo chmod 755 /usr/local/libexec/tangled-keyfetch
5757+```
5858+5959+This is necessary because SSH `AuthorizedKeysCommand` requires [really specific
6060+permissions](https://stackoverflow.com/a/27638306). Let's set that up:
6161+6262+```
6363+sudo tee /etc/ssh/sshd_config.d/authorized_keys_command.conf <<EOF
6464+Match User git
6565+ AuthorizedKeysCommand /usr/local/libexec/tangled-keyfetch
6666+ AuthorizedKeysCommandUser nobody
6767+EOF
6868+```
6969+7070+Next, create the `git` user:
7171+7272+```
7373+sudo adduser git
7474+```
7575+7676+Copy the `repoguard` binary to the `git` user's home directory:
7777+7878+```
7979+sudo cp repoguard /home/git
8080+sudo chown git:git /home/git/repoguard
8181+```
8282+8383+Now, let's set up the server. Copy the `knot` binary to
8484+`/usr/local/bin/knotserver`. Then, create `/home/git/.knot.env` with the
8585+following, updating the values as necessary. The `KNOT_SERVER_SECRET` can be
8686+obtaind from the [/knots](/knots) page on Tangled.
8787+8888+```
8989+KNOT_REPO_SCAN_PATH=/home/git
9090+KNOT_SERVER_HOSTNAME=knot.example.com
9191+APPVIEW_ENDPOINT=https://tangled.sh
9292+KNOT_SERVER_SECRET=secret
9393+KNOT_SERVER_INTERNAL_LISTEN_ADDR=127.0.0.1:5444
9494+KNOT_SERVER_LISTEN_ADDR=127.0.0.1:5555
9595+```
9696+9797+If you run a Linux distribution that uses systemd, you can use the provided
9898+service file to run the server. Copy
9999+[`knotserver.service`](https://tangled.sh/did:plc:wshs7t2adsemcrrd4snkeqli/core/blob/master/systemd/knotserver.service)
100100+to `/etc/systemd/system/`. Then, run:
101101+102102+```
103103+systemctl enable knotserver
104104+systemctl start knotserver
105105+```
106106+107107+You should now have a running knot server! You can finalize your registration by hitting the
108108+`initialize` button on the [/knots](/knots) page.