Issue titles MUST be descriptive natural-language titles.
Do NOT use Conventional Commit syntax for issue titles.
Prefer:
Map should preserve null values
Add pairwise function
Reduce allocations when mapping arrays
Avoid:
fix: preserve null values when mapping arrays
feat: add pairwise function
perf: reduce allocations when mapping arrays
Every issue MUST have exactly one change-type label:
bugfor a defectnew-featurefor new functionalityenhancementfor an improvement or refactoring of existing functionality
The label is determined by the nature of the issue.
Every coding task MUST be performed in its own dedicated worktree and task branch.
For a new task:
- Fetch the latest remote state.
- Create the task branch from the latest
origin/main. - Create or use a dedicated worktree for that branch.
Branch names MUST describe the nature of the change:
fix/<name>for bug fixes and issues that correct defective behavior (i.e. when issue is labelledbug)feat/<name>for new functionality (i.e. when issue is labellednew-featureorenhancement)refactor/<name>for internal restructuring without changing intended behaviorperf/<name>for performance improvementsdocs/<name>for documentation-only changes (i.e. when issue is labelleddocs)test/<name>for test-only changeschore/<name>for maintenance work that does not fit another category
When asked to fix a bug, defect, regression, or issue describing incorrect behavior, the branch MUST use the fix/ prefix.
For example:
fix/predicate-parameter-parsing
fix/coalesce-record-input
feat/max-by
refactor/function-builders
Do NOT use tooling-specific prefixes such as:
codex/
chatgpt/
The fact that Codex, ChatGPT, or another agent performs the work MUST NOT affect the branch name. Branch names describe the change, not the tool performing it.
The name of the branch should not reference the id of the issue but should be in plain text based on the name of the issue (i.e fix/predicate-parameter-parsing).
Repository-specific workflows are defined under .github/skills/.
When a task matches an existing skill, read and follow that skill before making changes.
In particular:
- Use
/scaffoldwhen introducing a new function, predicate, or accumulator definition, including documentation metadata and conformance cases. - Use
/implementwhen implementing an operator for which documentation metadata and conformance cases already exist.
For a new operator that requires both steps, run /scaffold before /implement.
Skills define task-specific procedures. AGENTS.md defines repository-wide rules and takes precedence if a skill contains conflicting Git, worktree, branch, issue, commit, or pull-request instructions.
Treat every user-approved version target or version sequence as an invariant. This applies to tasks involving GitVersion, release numbering, staged integrations, package publication, GitHub releases, or commits containing +semver directives.
Do NOT predict GitVersion results from Conventional Commit prefixes, branch names, previous experience, or memory. Do NOT assume that multiple feat commits collapse into one increment, that +semver: none prevents the branch's default increment, or that a result on a feature branch will equal the result when the same commit is the tip of main.
Before rewriting, pushing, merging, or fast-forwarding any version-sensitive stack:
- Write down the exact sequence of commits that are expected to become tips of
main. - Write down the exact version expected at every one of those tips.
- Treat that SHA-to-version table as the approved integration contract.
- If the user has supplied only the final version, derive the intermediate expectations and present them before integration.
- If any expectation is ambiguous, stop and ask the user. Do not select a version interpretation on the user's behalf.
An agreed version does not become optional merely because a later GitVersion calculation returns a different value. A different calculation is a divergence from the plan, not permission to revise the plan.
Before publishing rewritten branches or changing main, create an isolated clone and simulate the proposed integration history using the repository's installed GitVersion and configuration.
For every proposed integration tip:
- Check out the exact commit as a local branch named
main. - Run GitVersion against that checkout.
- Record the full commit SHA and calculated version.
- Compare the result mechanically with the approved SHA-to-version table.
The simulation MUST use the actual main branch name. Calculating on a feature branch, detached HEAD, pull-request merge ref, or inferred future graph is not an acceptable substitute.
Recreate and rerun the complete simulation after any operation that changes commit messages, parents, ordering, ancestry, or hashes, including:
- amend;
- interactive rebase;
- cherry-pick;
- squash;
- adding, removing, or changing a
+semverdirective; - moving commits between stacked pull requests;
- changing a pull request base;
- inserting documentation, maintenance, or release commits into the stack.
After a rewrite, record an old-to-new SHA mapping. Update the integration contract with replacement SHAs only after confirming that every calculated version still matches the previously agreed version sequence.
If any simulated version differs from the agreed plan, stop before pushing rewritten branches. Report the exact expected and actual versions and wait for explicit user instructions. Do NOT reinterpret the user's intended version, continue because the result appears internally consistent, or describe the new result as intended.
For every pull-request or main pipeline in a version-sensitive integration, actively monitor the version-calculation job as soon as the pipeline starts. Do not merely wait for the complete workflow and inspect the version afterward.
- Confirm that the workflow is running for the exact expected SHA.
- Locate the
calculate-versionjob, or the repository's equivalent GitVersion job. - Monitor that job until it completes.
- Read the calculated version from its outputs or logs.
- Compare it immediately with the approved version for that exact SHA, accounting for the pipeline context as described below.
A successful job conclusion is not enough. In a main pipeline, the calculated version MUST equal the approved version exactly. In a pull-request pipeline, GitVersion may append its normal PullRequest prerelease label and counter to the approved main-tip version. This is not a version mismatch when the version that was simulated with the same commit as an actual main tip is the exact base version of the pull-request result. For example, these results agree:
- simulated as an actual
maintip:2.33.0; - pull-request CI:
2.33.0-PullRequest913.3.
Do not require the pull-request suffix to appear in the approved SHA-to-version table. Compare the pull-request result's base version with the approved main-tip version, and treat any other difference as a mismatch.
If the CI-calculated version differs from the expected version:
- stop the integration immediately;
- cancel every still-running workflow for that SHA when cancellation is available;
- do not wait for build, packaging, publication, or deployment jobs;
- do not merge the pull request;
- do not advance
mainto the next planned tip; - do not create or move tags;
- do not publish packages or releases;
- report the exact SHA, expected version, actual version, and workflows cancelled;
- wait for explicit user instructions.
If the mismatch is detected after a commit has already reached main, leave main at that exact commit unless the user explicitly authorizes another action. Cancel downstream workflows immediately to prevent publication, and do not attempt an unapproved revert, force-push, compensating release, or version bump.
Do not advance main from one planned tip to the next until all of the following are true for the current stage:
mainpoints to the exact approved SHA;- CI ran against that exact SHA;
- the CI version-calculation output equals the approved version, or, for pull-request CI, differs only by the permitted
PullRequestprerelease suffix described above; - the associated pull request is marked
MERGEDwhen a pull request is part of the plan; - all required non-version checks have completed according to the user's approved exception list;
- no branch, pull-request head, base, tag, or remote tip has diverged from the approved graph.
Immediately before every push to main, fetch the remote and repeat the ancestry, SHA, and version checks. The push MUST be a strict fast-forward unless the user explicitly authorizes a different operation.
Version publication is irreversible. Immediately before any push that can publish a package, tag, or GitHub release, rerun the exact-tip simulation and compare it with the approved integration contract. Any mismatch is a hard stop.
Do NOT replace an agreed target with the version that GitVersion happened to calculate. Do NOT claim that a different version is correct because of newly discovered +semver behavior. Do NOT proceed on the basis that a later feature can repair an unintended release.
When the calculated result and the approved target disagree, the only successful action is to stop before publication and ask the user how to change the history or version directives.
Repository hooks are stored in .githooks/. Enable them after cloning the repository:
git config core.hooksPath .githooks
On Windows, the hooks run with the Bash bundled in Git for Windows. On all platforms, they require commitlint and the .NET SDK to be available on PATH. Restore .NET dependencies before pushing because the StyleCop check runs with --no-restore.
The commit-msg hook validates every commit message against commitlint.config.cjs. Commit messages MUST use an allowed Conventional Commit type and satisfy the configured header and line-length limits.
The pre-push hook runs StyleCop analyzers for every branch. The push is rejected when dotnet format Expressif.sln analyzers --verify-no-changes --no-restore finds analyzer violations.
Do NOT bypass these hooks. Resolve validation failures before committing or pushing.
For every completed implementation:
- Push the task branch.
- Create a GitHub pull request targeting
main. - Use a Conventional Commit-style PR title.
- Include a concise description of the change.
- Include the relevant tests or validation performed.
- Link the pull request to the corresponding issue when one exists (use wording
close).
Do NOT use bug, new-feature, or enhancement labels on the pull request unless explicitly requested.
A coding task is complete only when:
- implementation was performed in the task's dedicated worktree;
- for a new task, the branch was created from the latest
origin/main; - the branch name follows the repository branch naming rules;
- the solution build successfully;
- the relevant tests have been run;
- all intended changes are committed;
- commit messages follow Conventional Commits;
- the branch has been pushed;
- a pull request targeting
mainhas been created; - the PR title follows Conventional Commits;
- the corresponding issue has the appropriate
bug,new-feature, orenhancementlabel; - the pull request is linked to the issue when one exists;
- the worktree is clean.