feat: enforce issue-linked branches + document versioning/tagging policy (#48)
Formalize the branch↔issue relationship and add a release/version-tagging policy. Branch/issue linkage: - scripts/worktree-start now validates branch names: implementation branches must match (fix|feat|docs|chore)/issue-<number>-<slug>; review branches review/pr-<number>-<slug>. Untraceable names are rejected with a clear error (exit 2). New --allow-unlinked override for genuine exceptions. --dry-run preserved. - Documented issue → branch → worktree → PR → cleanup traceability in the runbook and the portable SKILL, including the claim-comment convention and Closes #n / Refs #n PR-body usage. - Noted that Gitea exposes no native issue→branch API field (only a PR head branch), so linkage is enforced via branch name + claim comment + PR body + cleanup. Versioning / tagging policy (docs only; no release automation yet): - SemVer vMAJOR.MINOR.PATCH (v0.x.y while unstable) with PATCH/MINOR/MAJOR bump rules. - Annotated tags only, from the exact commit on remote master, only after the full suite passes, with release notes referencing merged PRs/issues. Never tag feature branches, dirty worktrees, unreviewed/self-authored work, or commits not on remote master. - Release runbook in the runbook + SKILL, plus a new skills/llm-project-workflow/templates/release-tag.md prompt template. Tests: worktree-start branch validation — accepts fix/feat/docs/chore/issue-* and review/pr-*, rejects fix/random-name / my-branch / non-numeric issue, honors --allow-unlinked, preserves --dry-run. Full suite 291 passed / 0 failures; bash -n clean; git diff --check clean; no secrets. Release-tag automation (a scripts/release-tag helper) intentionally deferred to a later issue to keep this diff narrow and testable. Closes #48. Refs #38, #39, #46. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -174,6 +174,24 @@ under `branches/`. The main repository checkout is an orchestration checkout:
|
||||
use it for status checks, issue creation/claiming, and creating worktrees, but
|
||||
do not edit tracked repository files there.
|
||||
|
||||
**Issue → branch → worktree → PR → cleanup.** Every implementation branch is
|
||||
tied to an issue number so the work is traceable end to end:
|
||||
|
||||
| Stage | Form |
|
||||
|-------|------|
|
||||
| Issue | `#123` (claimed with `status:in-progress`) |
|
||||
| Branch | `(fix\|feat\|docs\|chore)/issue-123-<slug>` (review: `review/pr-456-<slug>`) |
|
||||
| Worktree | `branches/fix-issue-123-<slug>` (slashes → hyphens) |
|
||||
| PR | body says `Closes #123` (closes) or `Refs #123` (related) |
|
||||
| Cleanup | remove remote+local branch + worktree folder; drop `status:in-progress` |
|
||||
|
||||
`scripts/worktree-start` **rejects** implementation branches that are not
|
||||
issue-linked (use `--allow-unlinked` only for genuine exceptions). When claiming,
|
||||
post a comment like
|
||||
`Claimed. Branch: fix/issue-123-<slug>. Worktree: branches/fix-issue-123-<slug>.`
|
||||
Gitea has no native issue→branch API field (only a PR's head branch), so this
|
||||
linkage is enforced by branch name + claim comment + PR body + cleanup.
|
||||
|
||||
Branch folders are ignored by git via `branches/`, so dirty work in one issue
|
||||
does not block starting an unrelated issue in a separate branch folder. No LLM
|
||||
may edit another issue's branch folder unless explicitly assigned to that issue.
|
||||
@@ -313,6 +331,32 @@ All mutating attempts — allowed, blocked, failed, or succeeded — are audit-l
|
||||
with the profile and authenticated user when `GITEA_AUDIT_LOG` is set (see
|
||||
[`safety-model.md`](safety-model.md)).
|
||||
|
||||
## Releases and version tags
|
||||
|
||||
Versions follow SemVer — **`vMAJOR.MINOR.PATCH`**, using **`v0.x.y`** while
|
||||
unstable. Pick the bump by the largest change since the last tag:
|
||||
|
||||
- **PATCH** — bug fixes, docs, tests, wrappers, non-breaking workflow polish.
|
||||
- **MINOR** — new MCP tools, new workflow helpers, new config features;
|
||||
backward-compatible behavior.
|
||||
- **MAJOR** — breaking config/schema/API behavior or a changed MCP contract.
|
||||
|
||||
Tags are **annotated** (`git tag -a`), created **only from the exact commit on
|
||||
remote `master`**, **only after the full suite passes**, and carry release notes
|
||||
referencing the merged PRs/issues. **Never tag** feature branches, dirty
|
||||
worktrees, unreviewed or self-authored work, or commits not on remote `master`.
|
||||
|
||||
Release runbook (see [`../skills/llm-project-workflow/templates/release-tag.md`](../skills/llm-project-workflow/templates/release-tag.md)):
|
||||
|
||||
1. `git fetch prgs --prune`.
|
||||
2. Confirm local `master` equals `prgs/master` (`0 0`) and the tree is clean.
|
||||
3. Run the full test suite; stop on failure.
|
||||
4. Review merged issues/PRs since the last tag
|
||||
(`git log --oneline <last-tag>..prgs/master`).
|
||||
5. Choose the version bump.
|
||||
6. `git tag -a <vX.Y.Z> prgs/master -m "<notes referencing #issues / PRs>"`.
|
||||
7. `git push prgs <vX.Y.Z>`; add release notes if the forge supports it.
|
||||
|
||||
## Safety notes
|
||||
|
||||
- Never place raw tokens or passwords in any LLM MCP config; reference secrets
|
||||
|
||||
Reference in New Issue
Block a user