1# tangled contributing guide
2
3## commit guidelines
4
5We follow a commit style similar to the Go project. Please keep commits:
6
7* **atomic**: each commit should represent one logical change
8* **descriptive**: the commit message should clearly describe what the
9change does and why it's needed
10
11### message format
12
13```
14<service/top-level directory>: <affected package/directory>: <short summary of change>
15
16
17Optional longer description can go here, if necessary. Explain what the
18change does and why, especially if not obvious. Reference relevant
19issues or PRs when applicable. These can be links for now since we don't
20auto-link issues/PRs yet.
21```
22
23Here are some examples:
24
25```
26appview: state: fix token expiry check in middleware
27
28The previous check did not account for clock drift, leading to premature
29token invalidation.
30```
31
32```
33knotserver: git/service: improve error checking in upload-pack
34```
35
36
37### general notes
38
39- PRs get merged "as-is" (fast-forward) -- like applying a patch-series
40using `git am`. At present, there is no squashing -- so please author
41your commits as they would appear on `master`, following the above
42guidelines.
43- If there is a lot of nesting, for example "appview:
44pages/templates/repo/fragments: ...", these can be truncated down to
45just "appview: repo/fragments: ...". If the change affects a lot of
46subdirectories, you may abbreviate to just the top-level names, e.g.
47"appview: ..." or "knotserver: ...".
48- Keep commits lowercased with no trailing period.
49- Use the imperative mood in the summary line (e.g., "fix bug" not
50"fixed bug" or "fixes bug").
51- Try to keep the summary line under 72 characters, but we aren't too
52fussed about this.
53- Follow the same formatting for PR titles if filled manually.
54- Don't include unrelated changes in the same commit.
55- Avoid noisy commit messages like "wip" or "final fix"—rewrite history
56before submitting if necessary.
57
58## proposals for bigger changes
59
60Small fixes like typos, minor bugs, or trivial refactors can be
61submitted directly as PRs.
62
63For larger changes—especially those introducing new features, significant
64refactoring, or altering system behavior—please open a proposal first. This
65helps us evaluate the scope, design, and potential impact before implementation.
66
67### proposal format
68
69Create a new issue titled:
70
71```
72proposal: <affected scope>: <summary of change>
73```
74
75In the description, explain:
76
77- What the change is
78- Why it's needed
79- How you plan to implement it (roughly)
80- Any open questions or tradeoffs
81
82We'll use the issue thread to discuss and refine the idea before moving
83forward.
84
85## developer certificate of origin (DCO)
86
87We require all contributors to certify that they have the right to
88submit the code they're contributing. To do this, we follow the
89[Developer Certificate of Origin
90(DCO)](https://developercertificate.org/).
91
92By signing your commits, you're stating that the contribution is your
93own work, or that you have the right to submit it under the project's
94license. This helps us keep things clean and legally sound.
95
96To sign your commit, just add the `-s` flag when committing:
97
98```sh
99git commit -s -m "your commit message"
100```
101
102This appends a line like:
103
104```
105Signed-off-by: Your Name <your.email@example.com>
106```
107
108We won't merge commits if they aren't signed off. If you forget, you can
109amend the last commit like this:
110
111```sh
112git commit --amend -s
113```
114
115If you're submitting a PR with multiple commits, make sure each one is
116signed.
117
118For [jj](https://jj-vcs.github.io/jj/latest/) users, you can add this to
119your jj config:
120
121```
122ui.should-sign-off = true
123```
124
125and to your `templates.draft_commit_description`, add the following `if`
126block:
127
128```
129 if(
130 config("ui.should-sign-off").as_boolean() && !description.contains("Signed-off-by: " ++ author.name()),
131 "\nSigned-off-by: " ++ author.name() ++ " <" ++ author.email() ++ ">",
132 ),
133```
134
135Refer to the [jj
136documentation](https://jj-vcs.github.io/jj/latest/config/#default-description)
137for more information.