Contributing to Dinit's development
===================================

This is a guide to contributing to Dinit. It should be read from start to finish before attempting
to make a contribution to the Dinit codebase or documentation.

Note:  Yes, this is a lot of text (especially since it refers to information contained in other
       files). Having a proper process for contribution is important for quality, and also to
       avoid maintainer burn-out.


Before making a contribution
----------------------------

Many open-source project have limited resources, in particular people-power. While this might seem
to make any outside contribution desirable, that's not always the case. Before making a
contribution, you should consider:
 - whether or not the contribution is generally useful (is it just scratching a personal itch?).
 - whether the contribution being accepted will create a maintenance/development burden going
   forward, and whether you are prepared to assist with that burden (or whether the benefit
   outweighs the cost generally).
 - whether the change fits in with the philosophy and design direction of the project. For
   contribution of new features, the only way for sure is often to ask the maintainers - preferably
   before you've done the work, since it isn't so nice to put work into someone else's project only
   to be told it's not wanted!
 - whether the change will be convenient for users and other developers. Introducing build-time
   dependencies, for example, may cause inconvenience. Does the benefit of the change really
   outweigh this?
 
Documentation contributions are often appreciated, though you should be careful to ensure that the
style and conventions used match those of the existing documentation.

Bugfixes, likewise, are usually appreciated. However, it's important to understand whether what you
are fixing really is a bug, or whether it's intended behaviour - if there's any doubt at all, you
should ask the maintainers. Also, if the proposed fix is not completely straight-forward or is
"hacky", you should consider discussing it with maintainers first.

New features, on the other hand, should *always* be discussed with maintainers and an agreement
reached *before* beginning implementation. The feature might not be wanted, and if it is, there
might be requirements for how it should be implemented.

Remember:
 - submitting a merge request is an act that, by itself, creates work for the maintainer(s)!
 - always talk to the maintainers before doing a significant amount of work on a project, and
   consider doing so before commencing even minor work.
 - if you disagree with a maintainer, you need to consider who has invested more in the project.
   Maintainers will often have a good "feel" for how their software should work, and they may have
   a philosophy that doesn't align with your own. Arguing over subjective issues may frustrate both
   parties. It may be better to let it go!

Importantly: you should not rely on the maintainers to ensure your changes/additions are suitable
and correct. That is your job! If you are not capable (do not have the necessary technical
expertise, or are not willing or able to spend the time to properly adhere to contribution
requirements), then please do not try to contribute. Maintainers do not have the resources to
instruct you or guide you through the process. (You are welcome to request mentoring, before
attempting to make a contribution, in a discussion; please accept however that you may not get a
response).

Dinit is critical system software. If you are not aware of how that affects the way that it should
be designed and coded, then you probably do not have the expertise required to contribute.

As the maintainer and original author, I maintain the right to reject or request modification to
contributions, for failure to comply with the points listed above or elsewhere in the
documentation, for failure to adhere to a reasonable standard of conduct (see Contributor Conduct
below), or because I deem that the contribution includes features outside the intended scope. I
encourage anyone who is considering making a contribution to contact me to sound out whether I
would be likely to accept a submission for a particular feature or behavioural change.
 
I will endeavour to respond to all offered contributions with civility and respect, even if I
choose not to accept them.


General rules for contribution
------------------------------

Contributions must be clearly the work of the contributor (any other individuals involved must
clearly be identified) and the contributor must have the legal right to contribute the work to
the project and have it distributed as part of the project under the terms of the project's
licence.

Contributors must completely understand the contribution, its function, and its impact on the
software's function overall (if applicable).

(In general, these requirements do not permit the contribution of AI/LLM-produced code or
documentation; nor do they allow copying code from other projects with incompatible licences).


Using code/documentation from elsewhere
---------------------------------------

In general you should not use code (including comments) or documentation from any other project or
external source. This is true even for small snippets, and even if you make modifications. It is
preferable to write new code and documentation from scratch. The only exception is if the code is
identically licensed or is available under permissive terms that allow it to be distributed under
the same license as Dinit.

If you do use anything from another project in a contribution, you must make the reviewer
(maintainer) aware of what you have used, where it is from, and why you believe it is reasonable
to use it, and why you believe that using it does not infringe copyright.


Code contributions
------------------

In general, code contributions:
 - should follow existing style and conventions (also: read and follow CODE-STYLE)
 - should be appropriately* commented in accordance with existing style
 - should keep the design considerations in mind (read the DESIGN document)
 - should be accompanied by appropriate documentation additions/updates
 - should include tests where practical

[*] There is a little lee-way for comments, "truly obvious" code does not need to be and should
    not be commented.

For comments in code:
 - To document classes, functions and variables, see notes in CODE-STYLE. Function comments should
   describe what the function does, and anything that someone writing code that called the
   function would need to know in order to use it properly (as if they couldn't read the code of
   the function itself).
 - Use comments to explain anything in the code that is not apparent or any aspect that has
   significance beyond what is apparently just be reading the code. Be specific.
 - Do not simply state what the code does in code terms.

Examples of good/bad code comments:
    "Call foo() now" - bad, just saying what is obvious from reading the code.
    "We need to account for the string terminator" - ok (explanatory), but could be better.
    "Some OSes require us to call frob() after sniggle()" - could be better (which OSes, why?).
    "We +1 here to account for the string terminator" - good, explanatory.
    "Not that since ziggle was set to true above, this call to frobnicate() is guaranteed to return
     without an error" - good, adds explanatory context.


Documentation contributions
---------------------------

Many code contributions require accompanying documentation contributions, and it is possible to
contribute appropriate documentation by itself if applicable.

Documentation (including comments in code) should be:
 - Consistent: in terminology, style and tone, with existing documentation and itself.
 - Clear, unambiguous, and correct.
 - Written for the audience. Do not use developer-centric terminology/language in end-user
   documentation.
 - Grammatically correct, and correctly spelled. Use a checker if you are not comfortable enough
   with English. Do not invent terms. Do not use unnecessary abbreviations unless they are very
   commonly used elsewhere. (We have some tolerance for mistakes, but the onus is still on you
   to make a best effort). 
 - No shorter, but also no longer, than it needs to be. If discussing other software, keep the
   discussion restricted to what is necessary for understanding Dinit's interaction or own
   behaviour.
 - Link/refer to other information (man pages, documentation) where appropriate. However, be aware
   of web impermanence: if linking to a web resource that may not be permanent, try (if practical)
   to replicate the necessary information in documentation, and/or explain what was linked to (so
   that a reader can perhaps find it even if it has moved).


Commits and Commit Messages
---------------------------

Individual unrelated changes should be represented in separate commits. Each commit should
encompass a complete self-contained change.

Commit messages should include a single line (up to 72 characters, preferably shorter) giving a
summary of the functional change, followed by a blank line and then (unless trivial) a more
comprehensive description of the change (the "message body"), with lines wrapping at or before 72
characters.

Summary lines (and message bodies) start with a capital unless lead with a noun that doesn't
capitalise (such as a function or file name). If a commit affects a particular component (a
function, program, or "tests", or "build") that component should specified, followed by a colon,
at the head of the commit summary (see examples below).

Read existing commit messages to get a sense for the expected style/tone. Messages should be
concise but not at the expense of necessary detail. Write in the imperative, i.e. the message body
should be able to follow "This change will ..." (background information can be provided before the
imperative statement, if really necessary, but ideally comes afterwards). 

Examples:

    -- example 1 --
    check_frobz: make sure to set gromit before return

    Fix the check_frobz function so that ... (etc)

    -- example 2 --
    Tests: add test for correct frobzing of gerschnicketts

    Add a test which catches the recently discovered issue (see #78) where
    gerschnicketts were not correctly frobzzed in certain corner cases,
    including ... (etc)

The message body should fully explain what has been changed and the reason for it (the "why" and
"how" of the change). Make sure that there is a complete explanation of the functional nature of
the change (i.e. how does it affect the behaviour of the software) - it is less important to say
what has specifically changed in the code (although some information on this can be good too).

Use dot-point lists if appropriate, as in this example:

    Handle fuzzits consistently

    - add function solve_fuzzit() to solve fuzzits
    - fix the foo function to correctly handle fuzzits (using solve_fuzzit)
    - in the bar and baz functions, defer fuzzit handling to foo

    This makes handling of fuzzits consistent, and resolves #42.

Always include a reference to any related issue in the issue tracker by number, with leading
hash, as in the examples above. Do not include URLs for issues/commits/PRs within the
project, they should always be referenced by number.

Do NOT include a so-called "conventional commit" tag ("fix:", "chore:" etc).

Do NOT include a "Signed-off-by:" line. 


Contributor Conduct
-------------------

There is no complete "code of conduct" for Dinit contributors, but contributions will only be
accepted from those who are civil and respectful towards others. Specific behaviours that won't
be tolerated from contributors include but are not limited to:

 - discrimination generally, and especially if based on race, gender or gender identity, sexual
   preference, etc
 - personal attacks, insults, or harassment, or incitement thereof, against others
 - unnecessarily drawing attention to another's private or personal details

If a person is deemed to have engaged in negative behaviour such as from the list above,
contributions from them will not be accepted and the perpetrator may be blocked from
communications related to Dinit development. Note that such negative behaviours need not have
occurred in a public forum, and need not be related to Dinit development.

In short: don't be nasty to others; arseholes won't be tolerated.

If you feel that a contributor has behaved inappropriately, please feel free to contact me to
discuss it; such communication will be kept confidential (unless and until otherwise agreed).


New contributors
----------------

New contributors should introduce themselves briefly when making a contribution. If this applies
to you, please briefly explain your interest in Dinit, and outline your relevant experience 
to software development (eg list one or two other projects you have worked on).

Finally, new contributors must acknowledge that they have read and understood this document, by
including this exact text in the introduction to the pull request (or patch email):

    I have read and understand the CONTRIBUTING guide in full.

Failure to include this will result in the PR being marked as a draft (or equivalent) with an
explanatory note.

Contributors should feel free to add themselves to the CONTRIBUTORS list as part of the patch/pull
request (or in a separate pull request afterwards).


Process for contributing
------------------------

The preferred way to contribute is via a pull request (PR). See PR-PROCESS for details of the
expectations on contributors and how the process operates.
