Contributing to nucleus¶
Authoritative contributor guidelines, quality gates, and pull request workflows for
cordanaLLM/nucleus.
1. Core Operating Principles¶
Thank you for contributing to cordanaLLM/nucleus! We welcome contributions ranging from new hardware driver fragments and curated patch queues to cross-compilation enhancements and security hardening.
All contributions must honor the repository's foundational invariants:
- Trunk-Based Development: Direct commits to
mainare strictly prohibited. Always branch frommainusing short-lived branches (feat/*,fix/*,chore/*,docs/*). - Single Source of Truth (
versions.json): Upstream tarball URLs, release tags, and supported architectures must originate exclusively fromversions.json. - NASA/JPL Power of 10: All shell build and automation functions must be $\le 60$ lines, enforce
set -euo pipefail, check return codes, and passshellcheckwith zero warnings. - Docs & Code Synchrony: Every user-discoverable change (new stream, configuration variable, or build script modification) must be reflected in documentation in the exact same commit.
- Zero-Leak Invariant: Never commit RFC 1918 private IP addresses (
10.x,192.168.x,172.16-31.x) or local workstation home paths. Use standard placeholders (192.0.2.x,kernel.example.com,/opt/lusoris/...). - English Register: All commits, documentation, and PR discussions are conducted in neutral, professional English.
2. Development & Pull Request Workflow¶
sequenceDiagram
autonumber
participant Contributor as Contributor Workstation
participant Local as Local Quality Gates (Makefile)
participant Origin as GitHub Fork / Branch
participant CI as GitHub Actions CI Matrix
participant Main as Protected main Branch
Contributor->>Origin: Create branch (feat/intel-xe2-bmg)
Contributor->>Contributor: Edit kconfig fragments or build scripts
Contributor->>Local: make lint && make test
Note over Local: ShellCheck, Yamllint, JSON Schema, pytest
Local-->>Contributor: All gates pass (0 warnings, 0 failures)
Contributor->>Origin: git push -u origin feat/intel-xe2-bmg
Contributor->>Origin: gh pr create --fill
Origin->>CI: Trigger ci.yml & security-scans.yml
CI-->>Main: required checks pass, maintainer merges
Main->>Main: Squash and merge to main
Step-by-Step Instructions¶
- Create a topic branch:
- Implement changes:
- Keep changes minimal, coherent, and isolated.
- Do not reformat nearby files for aesthetic reasons alone.
- Run local verification gates: Install the test and documentation dependencies from the lock file, as CI does (Python 3.12):
requirements-test.in names the direct dependencies; requirements-test.txt is compiled
from it and pins every package by version and hash. Renovate keeps the lock current by
rerunning the command in its header, so change a dependency in the .in file and compile
with exactly this command (tests/test_workflows.py refuses a header Renovate cannot parse):
uv pip compile --generate-hashes --universal --python-version=3.12 --output-file=requirements-test.txt requirements-test.in
Then run the gates:
make lint includes make fmt-check: shfmt and ruff format must report no change and
ruff check no finding (make fmt applies the formatting). Both tools come from the lock
file. make lint also runs make lint-spelling: codespell, pinned in the same lock file, over
every tracked file with the one configuration in .codespellrc, which names each word it
ignores and why, and skips only the files .config/lint-exceptions.yaml names as dated
exceptions (a minified bundle, an upstream patch and the base64 praetor source chunks). make audit runs scripts/audit-repository-health.sh. Each of them fails, naming the
tool, when a tool it needs is missing. make docs-build runs mkdocs build --strict, which
fails on a broken link or any other warning. ci.yml runs all four on every pull request.
When you add or bump an action pin under .github/workflows/, also run make lint-pins.
It asks GitHub whether each # <tag> comment points to the pinned commit, so it needs
network access and an authenticated gh; ci.yml runs it on every pull request.
4. Commit with Conventional Commits:
Allowed types: feat, fix, docs, style, refactor, perf, test, chore, ci.
5. Push and open a Pull Request:
Pull Request Metadata Gate¶
pr-project-gate.yml is a hard gate. A pull request is refused unless it carries all three:
| Requirement | Detail |
|---|---|
| Milestone | An active milestone must be assigned. |
| Issue reference | The title or body must match fixes, closes, resolves, relates to or ref followed by #123, owner/repo#123, or EPIC-01. |
| Label | At least one tier/* or area/* label. |
The gate reports as Validate PR Milestone & Metadata. It is one of the eleven status checks the
repository ruleset (.github/rulesets/main.json, applied to main) requires, and it also feeds
the required-checks aggregate; see
Repository Governance.
The gate also runs on every push to main. There it looks up the merged pull request whose merge
commit the push is (GET /repos/{owner}/{repo}/commits/{sha}/pulls) and runs the same three
checks on that pull request, so the head of main carries the check the ruleset requires. A
commit that no merged pull request landed fails it. tests/test_workflows.py covers the lookup
with a stubbed gh.
No skip markers. The gate also refuses a title or body that contains a marker GitHub
honours to skip workflows: the bracketed forms skip ci, ci skip, no ci, skip actions
and actions skip, in any letter case, and a skip-checks: true trailer. A squash merge
turns the title and body into the commit message on main, and a marker there starts no
workflow for that commit, which is how #34's merge landed unverified (#39). To discuss a
marker, name it without its brackets. This check applies to release pull requests too.
Two waivers exist. A release pull request is authored by github-actions[bot] from a
generated changelog on a release-please--branches--* branch. It cannot satisfy any of the
three — release-please has no API to assign a milestone, a changelog references no single
issue, and it applies only the autorelease: pending label — so the metadata gates are
waived for it, and only for it. Both the author and the branch prefix must match; a label
alone does not waive anything, since a contributor can label their own pull request. The
code gates (ci, codeql, security-scans) are never waived. tests/test_workflows.py runs
the gate's own script on release-please's pull request, which passes and says the waiver applied,
and refuses a human author on that branch with the label, the bot on another branch, a branch
that only contains the prefix, and an author that is not the bot account.
A dependency update pull request is authored by renovate[bot] from Renovate's template on a
renovate/* branch, with no milestone, no issue it fixes, and only the dependencies label;
the same three gates are waived for it when both the author and the branch prefix match.
GitHub reserves the [bot] suffix for apps, so no person can take that login, and a branch
named renovate/* by anyone else is not waived. The tests pass Renovate's pull request and
refuse a human, the login without [bot] and another bot on a Renovate branch, the bot on
another branch, an unanchored prefix, and a skip marker in a Renovate title.
Keeping a branch up to date. main requires signed commits and an up-to-date branch. Do not
use GitHub's rebase-mode Update branch button: it rewrites the commits without a signature and
the pull request is then blocked. Rebase locally with signing enabled and push with a lease; see
Repository Governance.
Release Tags¶
Merging the release pull request tags the repository's release nucleus-v<X.Y.Z> and
writes that version into VERSION. A kernel is released by a different tag,
v<version>-<stream>-lusoris<N>, whose <version> must equal the stream's version in
versions.json, and whose N is the forge revision, 1 to 9999 without leading zeros: a
second revision releases the same upstream version again with a new kernel release. Only
the kernel tag starts publish-release.yml, a manual run must start from that tag
(--ref), and the downstream dispatch needs the KERNEL_FORGE_TOKEN secret, checked
before anything is built. Packaging sections 5.4 and 5.5 describe both.
Agent Context and praetor Governance¶
AGENTS.md is the only hand-edited agent instruction file. CLAUDE.md, .codex/rules.md,
.cursor/rules/hiss-invariants.mdc, .gemini/GEMINI.md, .github/copilot-instructions.md
and .windsurfrules are compiled from it: after every change to AGENTS.md, run
make context and commit the regenerated files in the same commit. The Praetor Governance
CI job fails when they differ from AGENTS.md.
The praetor commit this repository is governed by is pinned in one place, PRAETOR_REF in
.github/workflows/ci.yml. versions.json pins kernel streams, not tools. To move the pin,
follow Moving the pin: copy the catalog files
from the new commit when they changed, regenerate .standards.lock in a scratch clone, set
PRAETOR_REF to the full SHA, and run make governance-check, make context,
make ruleset, make lint and make test.
A change that adds, removes or renames a job in a workflow that runs on pull requests also
runs make ruleset, because .github/rulesets/main.json lists those jobs as required checks.
3. Developer Certificate of Origin (DCO)¶
By contributing to this repository, you certify that you have the right to submit the code under the project's licence (EUPL-1.2; see the licence section of the README for documentation and patches):
Developer Certificate of Origin
Version 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications.