02-git-workflow.md)Priority Level: P0 (Critical System Invariant) Direct pushes and force pushes to
developor to a release line (X.Y.x) are strictly forbidden. This rule is the single source for branching, commits, pull requests, versioning, releases and issue handling. Other documents reference it.
The process follows widely used conventions:
Semantic Versioning 2.0.0,
Conventional Commits 1.0.0,
Keep a Changelog 1.1.0 and the
develop plus release-line model of PrestaShop (owner decision 2026-10-10):
a permanent integration branch, one branch per maintained X.Y line, releases as
tags on those branches, and squash-merged pull requests.
Every commit on develop and on a line is a squash commit that GitHub created
from one pull request: <PR title> (#N), signed by GitHub and therefore shown as
Verified. Nothing reaches these branches any other way. Every change -
features, fixes, releases, backports - travels as its own pushed branch and PR.
| Action | Agent | Owner |
|---|---|---|
| Topic branch, commits, local checks, changelog regeneration | Yes | Yes |
| Push a topic branch, open or update a PR | Only after the owner's explicit go-ahead in the session | Yes |
| Independent review (03-author-reviewer) | Yes (Reviewer role) | Yes |
| Merge a PR, create a release line, push a tag | Never | Yes |
Publish a GitHub Release, approve the npm environment, publish or deprecate on npm, publish on the VS Code Marketplace, change repository settings |
Never | Yes |
An agent prepares release PRs, release notes and evidence (section 5) and stops. It never states or implies that a push, merge, tag or publication happened unless it observed it.
| Branch | Purpose | Created from | Merges into | Lifetime |
|---|---|---|---|---|
develop |
Default branch. Integration of the next version; betas are tagged here | - | - | Permanent |
X.Y.x (for example 1.0.x) |
Release line of version X.Y: its release candidates (for 1.0 the previews after feature freeze, such as 0.8.0 and 0.9.0), the final X.Y.0 and patches X.Y.Z |
develop at feature freeze (the release commit of the first release candidate) |
- (receives backports) | Until the line's end of support |
| Topic branch | One change | develop (a backport branch: the line) |
Its source branch | Until merged |
main branch (owner decision 2026-10-10). The repository's
front page is develop; released states are tags and GitHub Releases.vX.Y.Z after the version
(section 4): betas v0.6.0 -> v0.7.0 (on develop) -> release candidates
v0.8.0 -> v0.9.0 -> v1.0.0 -> v1.0.1 (on 1.0.x). How many betas and
release candidates there are follows the roadmap's release acceptance; each
preview takes the next minor. A tag freezes the exact state of a stage forever.v0.6.0 (prepared as 1.0.0-beta.2), the first squash
commit of that work on develop. The npm name placeholder 1.0.0-beta.1 holds
the place of 0.5.0: the owner withdraws it from npm, and it has no tag, GitHub
Release or changelog entry (owner decision 2026-10-11, REPO-003).X.Y.x from develop
at the release commit of its first release candidate (for 1.0: the first
preview tagged on 1.0.x). From then on develop carries the next version's
features and X.Y.x takes only release-blocking fixes and, after X.Y.0,
patch fixes.develop first. A fix that a maintained line
also needs is then backported: a branch backport/<N>-<desc> from the line
with git cherry-pick -x <develop-sha>, and a PR into the line titled like the
original with the suffix (backport #N), squash-merged. Only a fix that does
not apply to develop (code already gone there) targets the line directly.develop and the lines have linear history of squash
commits only. A line is never merged into develop; the changelog of each
branch is generated on that branch (section 6).X.Y.x, tags are vX.Y.Z....Format: <type>/<short-kebab-description>, optionally with the issue number:
fix/123-windows-teardown-identity, feat/session-mode-none, docs/release-process.
| Prefix | Use |
|---|---|
feat/ |
New user-visible capability |
fix/ |
Bug fix |
perf/ |
Performance improvement without behavior change |
refactor/ |
Internal restructuring without behavior change |
docs/ |
Documentation and contributor rules only |
test/ |
Tests only |
build/, ci/ |
Build system, packaging or CI workflow |
chore/ |
Maintenance that fits no other type (dependency bumps, tooling) |
release/ |
A release PR (section 5): release/v0.7.0 |
backport/ |
A cherry-pick of a merged develop fix into a line (above) |
Keep a topic branch focused on one concern. Rebase it onto its target to pick
up changes (git rebase origin/develop). The author may force-push their own
topic branch with --force-with-lease before merge; never force-push a branch
someone else is working on.
Every commit that lands on develop or a line - in practice, every
squash-merge commit - must follow Conventional Commits 1.0.0:
<type>(<scope>)!: <subject>
<body>
<footers>
feat, fix, perf, refactor, docs, test,
build, ci, chore, revert. feat and fix appear in release notes;
feat implies a minor version bump after 1.0.0, fix a patch bump.process, history, sessions, redaction, routing, adapters, server,
setup, vscode, rules, release, deps.! before the colon, together with a BREAKING CHANGE: footer, marks an
incompatible change to the MCP tool contract, configuration, stored data or CLI.Fixes #123 / Refs #123 - linked GitHub issue;Refs: AUD-P0-1 - audit finding or roadmap item;BREAKING CHANGE: <description and migration>;Co-Authored-By trailer for an AI (Claude, Codex, Gemini, Antigravity or any
other), a "Generated with" line or a similar note. AI tools are tools paid for
by the owner, who is the sole author and copyright holder. The Reviewer
rejects a commit or PR that contains AI attribution.Examples:
fix(process)!: identify Windows descendants by PID and creation time
The CIM sweep matched processes by ParentProcessId alone, so a reused PID
could select unrelated user processes. Tree selection now runs in a pure
function that rejects children created before their parent.
BREAKING CHANGE: terminateProcessTree no longer accepts extraPids.
Fixes #42
Refs: AUD-P0-1
docs(rules): define release lines, tags and PR process
Commits on topic branches disappear in the squash, but their headers must still be valid Conventional Commits: the changelog regeneration that runs before every push (section 6) rejects any other subject. The pull request title and description become the final commit, so they must meet this section.
develop; a backport targets its line (section 1). A release PR
targets the branch that will carry the tag (section 5). Push the branch only
after the owner's go-ahead (section 0); GitHub needs it to open the PR.Fixes #... / Refs #..., roadmap item and audit finding IDs.pending changelog entry from the title preview (section 6).CHANGELOG.md regenerated, never edited by hand
(section 6); the title preview passed;
no secrets, local paths or personal data in the diff.gh pr merge <number> --squash --delete-branch
Before confirming, edit the squash message so that it complies with section 2
(keep footers such as Fixes #... and BREAKING CHANGE:; remove any AI
attribution). There is no other merge method: the rulesets allow only squash.X.Y.Z, with no mapping between them. VS Code
accepts only a numeric extension version and offers Restart Extensions after an
update only when that number changes; the Marketplace refuses a repeated
version. scripts/build-vscode.cjs refuses any other version.0.5.0 is skipped (the withdrawn npm name
placeholder 1.0.0-beta.1 held it), then 0.6.0 (the first release,
prepared as 1.0.0-beta.2), 0.7.0, 0.8.0, 0.9.0; further previews would
continue with 0.10.0. A release of a preview that only fixes it raises the
patch instead (owner decision 2026-10-11): 0.6.1, 0.6.2; it ships as a
preview like its minor. The final release is 1.0.0. A preview is a VS Code
pre-release, a GitHub pre-release and npm next; isPreview in
scripts/build-vscode.cjs and the release workflows apply this rule. How a version after 1.0.0 is
previewed is an owner decision before the first such preview.package.json, package-lock.json, plugin.json, extensions/vscode/package.json
and CHANGELOG.md. Runtime constants read it from package.json.| npm dist-tag | Holds | Install |
|---|---|---|
next |
The newest preview (a version below 1.0.0) | npm install coagent8@next |
latest |
The newest final release | npm install coagent8 |
latest. npm always keeps a latest tag, so
while only previews exist it can point at one; the README install instructions
use @next until 1.0.0.beta dist-tag is retired; the owner removes it when publishing 0.6.0
(npm dist-tag rm coagent8 beta).Every release follows the same five phases. The owner performs every action marked (owner); an agent may prepare everything else.
develop; release candidates, X.Y.0
and patches target X.Y.x (for the first release candidate, the owner
creates X.Y.x from develop first).release/vX.Y.Z from the target. One commit
chore(release): vX.Y.Z that only:
CHANGELOG.md with npm run changelog -- --tag vX.Y.Z,
which writes the commits since the previous tag under the new version
heading with the release date (section 6).chore(release): vX.Y.Z; attach the local gate
evidence and the release notes preview (npm run release-notes -- --tag vX.Y.Z).
The independent review binds to that commit (03-author-reviewer).git fetch origin
git tag -a vX.Y.Z <verified-sha> -m "CoAgent8 vX.Y.Z"
git push origin vX.Y.Z
.github/workflows/release.yml. It checks that the tag is
a numeric vX.Y.Z and annotated, that package.json carries the same version
and that the tagged commit is on develop or an X.Y.x line; runs the full
gate on Ubuntu with Node 24; packs and smoke-tests the exact npm tarball,
packages the VSIX, writes SHA256SUMS, signs build provenance for the tarball and the VSIX
(GitHub artifact attestations), generates the release notes with git-cliff
and creates a draft GitHub Release (marked pre-release for a version
below 1.0.0) with these assets. It never publishes to npm and never
publishes the draft.gh release download vX.Y.Z)
and verify them: sha256sum --check --ignore-missing SHA256SUMS and
gh attestation verify <file> --repo oktawianwybieralski/coagent8 for the
tarball and the VSIX. Install both in clean profiles and run the stage's
native acceptance (roadmap). Add known issues and security notes to the
draft notes. Local gate digests can differ from CI builds (different machine,
archive timestamps); SHA256SUMS and the attestation are authoritative..github/workflows/docs.yml, which validates the TSDoc
comments, generates the TypeDoc site (source API plus the project documents:
README, Architecture, Roadmap, Handoff, Changelog, Git workflow) and deploys it
to GitHub Pages. Pages always shows the latest published release; versioned
documentation per line is planned with the first X.Y.x line (REPO-002)..github/workflows/npm-publish.yml: after the owner approves the npm
environment, it downloads the release's tarball, checks it against
SHA256SUMS and the provenance of release.yml, and runs
npm publish --provenance to next (a version below 1.0.0) or latest
(1.0.0 and later); the GitHub pre-release flag must agree with the version.
A failed job is re-run; npm never accepts the same version twice. Until it
is enabled, and for 0.6.0, the owner publishes the downloaded, verified
tarball by hand:npm publish ./coagent8-0.N.0.tgz --tag next # preview
npm publish ./coagent8-X.Y.Z.tgz # 1.0.0 and later: latest
Publish the verified VSIX from the release to the VS Code Marketplace under
the publisher okidev, as a pre-release for a preview:npx @vscode/vsce publish --pre-release --packagePath ./coagent8-mcp-0.N.0.vsix # preview
npx @vscode/vsce publish --packagePath ./coagent8-mcp-X.Y.Z.vsix # 1.0.0 and later
Any content change after Phase A's gate restarts it with a new commit; a pushed tag is never moved. A failed release workflow is fixed by a new release number when the tag was already pushed.
X.Y.0 follows the same phases on X.Y.x, with the additional
readiness gate: the roadmap's RC stage accepted with no open P0/P1 issue; six CI
jobs and the full local gate on a clean checkout; soak verification of the
exact artifact (concurrent sessions, process cancellation, EOF teardown, lock
contention, restart recovery, history pagination, bounded cache/memory); and
an independent review of the complete release diff against the previous
release tag, bound to base, candidate, tree and artifact hashes, with
COVERAGE: COMPLETE, VERDICT: READY and no unresolved P1/P2 finding.CHANGELOG.md at the repository root is generated from the Conventional
Commits history by git-cliff (cliff.toml, npm run changelog). It follows
Keep a Changelog 1.1.0 with one section per released version, newest first.--tag, in each release PR (section 5).(#N) suffix of a
squash subject becomes a link to the PR. On a topic branch the entries are the
branch commits. After the squash merge they are replaced by the PR title (one
entry per PR) at the next regeneration on the target branch.develop the versions tagged on
develop (betas), on a line the versions tagged on that line. Before the
first line exists (the first release candidate), the owner decides how
develop lists the line's releases; until then every release is tagged on
develop.cliff.toml footer, which names the command); generation after it starts at
tag v0.6.0.! or BREAKING CHANGE), Added (feat), Changed (perf,
refactor), Removed (revert), Fixed (fix). docs, chore, test, ci,
build and style are omitted. A breaking commit is listed under Breaking
only, not again under its type.Revert "..." title) fails the generation (require_conventional) instead of
silently losing its entry.npm run release-notes
(cliff.release-notes.toml) in the layout of the PrestaShop release pages.
#PR: description (by @author).The agent does this itself, without being asked.
git push (any branch), after the last change is
committed:
npm run changelog. It fails when any commit since v0.6.0 is
not a Conventional Commit. A failure blocks the push: reword the offending
commit; never push past it.CHANGELOG.md changed, commit it alone as chore(changelog): regenerate.
chore is omitted from the changelog, so this commit does not make the file
stale. Do not amend it into an earlier commit: that changes the SHA that
the file links.gh pr create and before every PR title change, run
npm run changelog:check -- --with-commit "<PR title>". It writes no file.
pending entry. It must sit in the right group and
describe the change for users.! in the title or a BREAKING CHANGE: footer in
the squash message. A ! on a branch commit alone is lost in the squash.pending entry into the PR description (section 3).CHANGELOG.md (for example after rebasing on
develop): never resolve it by hand. Take either side, run
npm run changelog and commit the result as in step 1.issue tool (a sanitized, prefilled report) and of doctor, the OS, Node
version, CoAgent8 version and backend CLI versions.bug, enhancement, question, docs;P0 (safety, data loss, tool unusable), P1
(incorrect result or contract violation), P2 (robustness or degraded
behavior), P3 (cosmetic);found-in:v0.6.0 (the version where the bug was observed);needs-repro, confirmed, wontfix, duplicate.Fixes #... in the PR).The owner maintains three branch and tag rulesets with no bypass actors except the tag-creation rule:
| Ruleset | Targets | Rules |
|---|---|---|
develop |
refs/heads/develop |
PR required; squash only; linear history; required checks below, up to date; conversation resolution; signed commits; no deletion; no force push |
release lines |
refs/heads/*.*.x |
PR required; squash only; linear history; required checks below, up to date; conversation resolution; signed commits; no deletion; no force push |
release tags |
refs/tags/v* |
No update, deletion or force push (immutable); creation restricted to maintainers |
ci.yml names them:
Test on {ubuntu-latest, macos-latest, windows-latest} (Node {24.x, 26.x}).
When the CI matrix changes, the ruleset changes in the same PR's follow-up;
a required check that no job reports blocks every merge.develop is the default branch. GitHub signs every squash commit it creates
(the "Verified" badge), which satisfies the signed-commit rule; a locally made,
unsigned commit can never reach a protected branch.github-pages environment allows
deployments from tags v* (a release event runs on the tag) and from
develop (manual runs). Site: https://oktawianwybieralski.github.io/coagent8/.coagent8 trusts publisher repository oktawianwybieralski/coagent8,
workflow npm-publish.yml, environment npm; the GitHub environment npm
requires the owner's review and allows tags v*; the repository variable
NPM_TRUSTED_PUBLISHING is true. The package then disallows token
publishing. Without the variable the publish job is skipped.git bundle create coagent8-backup.bundle --all).git push --atomic --force-with-lease=refs/heads/<branch>:<old_sha> --force-with-lease=refs/tags/<tag>:<old_tag_obj> origin <new_sha>:refs/heads/<branch> refs/tags/<tag>:refs/tags/<tag>
git merge-base --is-ancestor <bad_sha> origin/<branch> returns exit code 1).