Contribute

Contributing

How a fix found in one environment reaches every other consumer, and how to promote a sanitized shared learning through the review gate.

Read the full contributing guide

The canonical contribution guide lives in CONTRIBUTING.md at the repository root, where GitHub surfaces it in the new-issue and pull-request flows. This page is a short orientation; the root file is the source of truth.

How contributions reach the package

hve-squad ships through APM as one-directional package content: consumers pull the package, and the package never reads from consumer environments. The only route for a change to reach the published package is a fork and pull request against the repository.

  1. Fork the repository.
  2. Create a branch for your change.
  3. Add a change fragment with apm run change.
  4. Open a pull request against the default branch.
  5. A maintainer reviews, requests changes when needed, and merges.

Consumers receive the merged change the next time they run apm run sync-deps.

Recording your change

Do not edit CHANGELOG.md and do not bump version: in apm.yml. Both are release outputs, assembled on the default branch when a release is cut, and CI rejects a pull request that touches either.

The reason is mechanical. A version line is a single line and the newest changelog heading is a single position, so two pull requests that both touch them always conflict — and the second one to merge silently reuses a version number the first already claimed. Instead every pull request adds one new file under .changes/unreleased/. Two pull requests adding two differently named files never conflict.

apm run change

The script asks four things and writes the file for you:

Choosing the bump

ValueUse whenIn this repo
major A consumer must change something to keep working. Not used yet.
minor A genuinely new idea, or a change that materially changes how the package is used. 0.10.0 introduced federation. 0.11.0 reworked hve-core attachment.
patch Everything else, including new agents, skills, prompts, instructions, and roles that extend an idea that already shipped. A new squad role under federation. A new OWASP skill. A wording fix.

Adding an agent is not a minor. Adding the concept the agent belongs to is. Ten agents that all serve one idea that already ships are ten patches, not ten minors. When in doubt choose patch — the maintainer sees the resolved level on the pull request check and corrects the line before merging, and raising is cheap while an accidental minor is permanent.

You end up with a file like .changes/unreleased/20260804-roster-row-resolves-to-nothing.md:

---
bump: patch
type: Fixed
---

- **A roster Primary pointed at an agent hve-core no longer ships.** Repointed it to ...

Write the entry as markdown bullets starting with - , because the release step copies them verbatim. Lead with a bold sentence naming the problem, then say what changed, then cite the file paths in backticks. Commit the fragment with the rest of your change. One fragment per idea — a pull request doing two unrelated things adds two fragments.

Merging your pull request does not release it. The fragment waits in .changes/unreleased/ with everything else already merged, and a maintainer cuts a release when that batch is ready — the same hour for a quick fix, or later for something that needs time in testing. In the meantime the merge is published to the rolling pre-release, so your change is installable and testable within minutes:

apm install "Peter-N91/hve-squad#v0.15.0-pre" --target copilot

The exact tag is on the Releases page, marked as a pre-release. It is a channel rather than a fixed point: the tag moves on every merge, and it is renamed when a minor fragment lands. Pin a released version for anything you depend on. The full format reference lives in .changes/README.md.

Shipping a fix without shipping everything else

A release ships a commit, not a selection of fragments. The tag is cut from the branch head, so a release from the default branch contains everything merged into it, whatever the CHANGELOG happens to list. Choosing which fragments to consume changes the release notes, not the code. That leaves two cases, and only the second needs anything unusual.

The default branch is shippable. A maintainer dispatches Release Prep and your fix goes out with everything else pending, as one version. If a pending fragment asked for minor, that version is a minor — and it still contains your patch, so consumers get the fix. This is almost always the right answer.

The default branch holds something that must not ship yet. Then a release from it would carry that work out alongside the fix, so the fix has to come from somewhere that does not contain it: a hotfix branch cut off the last release tag.

git switch --detach v0.14.0
git switch -c hotfix/v0.14.1
# apply the fix, then record it
apm run change            # Type: Fixed, Bump: patch
git push -u origin hotfix/v0.14.1

A maintainer then dispatches Release Prep with ref set to the hotfix branch. It assembles the CHANGELOG from that branch's fragments only, bumps apm.yml to 0.14.1, and cuts the tag from that branch. The rolling pre-release on the default branch is left alone, because the batch it describes is still pending. The hotfix branch is then merged back with the release-merge-back label, which is what allows that pull request to carry the release state Release Prep already wrote.

A hotfix released after a higher version does not steal the Latest badge: the release workflow compares versions and declines it when the tag is lower than the current latest.

Proposing a shared learning

A shared learning is a durable, broadly applicable rule discovered while using the squad that should help every other consumer facing the same scenario. Live agent memory always stays local to each consumer and is never promoted automatically. Promotion is a deliberate, human-reviewed pull request, and that review is the defense against memory poisoning, data leakage, and context drift.

Sanitize every entry before you propose it:

Curated shared learnings travel as package content in squad-src/.github/skills/squad/learnings/shared-learnings.md. When a learning is specific to one organization's projects, promote it to a tenant-internal repository instead. The two paths, and the squad-learnings-tenant scaffold, are described in Shared learnings.