From c46df8cd2fb76de9a06847fd9babd58613415ae7 Mon Sep 17 00:00:00 2001 From: Sebastien Taggart Date: Wed, 3 Jun 2026 17:38:36 -0400 Subject: [PATCH 1/2] Hard-reset integration branch after merge to prevent SHA divergence --- .agents/skills/deploy/SKILL.md | 6 +++--- .agents/skills/start/SKILL.md | 6 +++--- .claude/commands/deploy.md | 6 +++--- .claude/commands/start.md | 6 +++--- .cursor/rules/deploy.mdc | 6 +++--- .cursor/rules/start.mdc | 6 +++--- .gemini/skills/deploy/SKILL.md | 6 +++--- .gemini/skills/start/SKILL.md | 6 +++--- Makefile.agents.mk | 3 ++- skills/deploy.md | 4 ++-- skills/start.md | 8 ++++---- 11 files changed, 32 insertions(+), 31 deletions(-) diff --git a/.agents/skills/deploy/SKILL.md b/.agents/skills/deploy/SKILL.md index 4523b10..3f0c85a 100644 --- a/.agents/skills/deploy/SKILL.md +++ b/.agents/skills/deploy/SKILL.md @@ -24,9 +24,9 @@ Required branch: `dev` (two-branch mode). If not on the required branch, abort and say: "Switch to `` before running `/deploy`." -Pull the latest changes before proceeding: +Sync to the remote before proceeding (hard reset — the deploy branch is never edited locally, only fast-forwarded from CodeCannon's own merges): ```bash -git pull +git fetch && git reset --hard @{u} ``` --- @@ -265,4 +265,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.agents/skills/start/SKILL.md b/.agents/skills/start/SKILL.md index 8389046..830e2bf 100644 --- a/.agents/skills/start/SKILL.md +++ b/.agents/skills/start/SKILL.md @@ -198,7 +198,7 @@ gh issue comment --body-file /issue_comment.md Ensure the base branch is up-to-date before branching: ```bash -git checkout dev && git pull origin dev +git checkout dev && git fetch origin dev && git reset --hard origin/dev ``` Now create the feature branch: @@ -289,7 +289,7 @@ Present numbered findings: Ensure the base branch is up-to-date before branching: ```bash -git checkout dev && git pull origin dev +git checkout dev && git fetch origin dev && git reset --hard origin/dev ``` Find and check out the existing branch, or create a new one linked to the issue: @@ -324,4 +324,4 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. - + diff --git a/.claude/commands/deploy.md b/.claude/commands/deploy.md index 2217a29..9f445a9 100644 --- a/.claude/commands/deploy.md +++ b/.claude/commands/deploy.md @@ -19,9 +19,9 @@ Required branch: `dev` (two-branch mode). If not on the required branch, abort and say: "Switch to `` before running `/deploy`." -Pull the latest changes before proceeding: +Sync to the remote before proceeding (hard reset — the deploy branch is never edited locally, only fast-forwarded from CodeCannon's own merges): ```bash -git pull +git fetch && git reset --hard @{u} ``` --- @@ -260,4 +260,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.claude/commands/start.md b/.claude/commands/start.md index e538771..6a09ff8 100644 --- a/.claude/commands/start.md +++ b/.claude/commands/start.md @@ -193,7 +193,7 @@ gh issue comment --body-file /issue_comment.md Ensure the base branch is up-to-date before branching: ```bash -git checkout dev && git pull origin dev +git checkout dev && git fetch origin dev && git reset --hard origin/dev ``` Now create the feature branch: @@ -284,7 +284,7 @@ Present numbered findings: Ensure the base branch is up-to-date before branching: ```bash -git checkout dev && git pull origin dev +git checkout dev && git fetch origin dev && git reset --hard origin/dev ``` Find and check out the existing branch, or create a new one linked to the issue: @@ -319,4 +319,4 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. - + diff --git a/.cursor/rules/deploy.mdc b/.cursor/rules/deploy.mdc index a55d216..5ce73de 100644 --- a/.cursor/rules/deploy.mdc +++ b/.cursor/rules/deploy.mdc @@ -25,9 +25,9 @@ Required branch: `dev` (two-branch mode). If not on the required branch, abort and say: "Switch to `` before running `/deploy`." -Pull the latest changes before proceeding: +Sync to the remote before proceeding (hard reset — the deploy branch is never edited locally, only fast-forwarded from CodeCannon's own merges): ```bash -git pull +git fetch && git reset --hard @{u} ``` --- @@ -266,4 +266,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.cursor/rules/start.mdc b/.cursor/rules/start.mdc index afde6cf..d1fb74a 100644 --- a/.cursor/rules/start.mdc +++ b/.cursor/rules/start.mdc @@ -199,7 +199,7 @@ gh issue comment --body-file /issue_comment.md Ensure the base branch is up-to-date before branching: ```bash -git checkout dev && git pull origin dev +git checkout dev && git fetch origin dev && git reset --hard origin/dev ``` Now create the feature branch: @@ -290,7 +290,7 @@ Present numbered findings: Ensure the base branch is up-to-date before branching: ```bash -git checkout dev && git pull origin dev +git checkout dev && git fetch origin dev && git reset --hard origin/dev ``` Find and check out the existing branch, or create a new one linked to the issue: @@ -325,4 +325,4 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. - + diff --git a/.gemini/skills/deploy/SKILL.md b/.gemini/skills/deploy/SKILL.md index b24e427..b991dd2 100644 --- a/.gemini/skills/deploy/SKILL.md +++ b/.gemini/skills/deploy/SKILL.md @@ -24,9 +24,9 @@ Required branch: `dev` (two-branch mode). If not on the required branch, abort and say: "Switch to `` before running `/deploy`." -Pull the latest changes before proceeding: +Sync to the remote before proceeding (hard reset — the deploy branch is never edited locally, only fast-forwarded from CodeCannon's own merges): ```bash -git pull +git fetch && git reset --hard @{u} ``` --- @@ -265,4 +265,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.gemini/skills/start/SKILL.md b/.gemini/skills/start/SKILL.md index f792167..8c65c68 100644 --- a/.gemini/skills/start/SKILL.md +++ b/.gemini/skills/start/SKILL.md @@ -198,7 +198,7 @@ gh issue comment --body-file /issue_comment.md Ensure the base branch is up-to-date before branching: ```bash -git checkout dev && git pull origin dev +git checkout dev && git fetch origin dev && git reset --hard origin/dev ``` Now create the feature branch: @@ -289,7 +289,7 @@ Present numbered findings: Ensure the base branch is up-to-date before branching: ```bash -git checkout dev && git pull origin dev +git checkout dev && git fetch origin dev && git reset --hard origin/dev ``` Find and check out the existing branch, or create a new one linked to the issue: @@ -324,4 +324,4 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. - + diff --git a/Makefile.agents.mk b/Makefile.agents.mk index 35a3ea9..8f89365 100644 --- a/Makefile.agents.mk +++ b/Makefile.agents.mk @@ -83,7 +83,8 @@ merge: fi; \ gh pr merge --merge && \ git checkout $(INTEGRATION_BRANCH) && \ - git pull origin $(INTEGRATION_BRANCH) && \ + git fetch origin $(INTEGRATION_BRANCH) && \ + git reset --hard origin/$(INTEGRATION_BRANCH) && \ echo "PR merged into $(INTEGRATION_BRANCH)." # Promote integration branch to staging. Creates a PR: INTEGRATION_BRANCH → STAGING_BRANCH. diff --git a/skills/deploy.md b/skills/deploy.md index b584b13..d2943ce 100644 --- a/skills/deploy.md +++ b/skills/deploy.md @@ -32,9 +32,9 @@ Required branch: `{{BRANCH_PROD}}` (trunk mode). If not on the required branch, abort and say: "Switch to `` before running `/deploy`." -Pull the latest changes before proceeding: +Sync to the remote before proceeding (hard reset — the deploy branch is never edited locally, only fast-forwarded from CodeCannon's own merges): ```bash -git pull +git fetch && git reset --hard @{u} ``` --- diff --git a/skills/start.md b/skills/start.md index 5fe8fcd..2c964f6 100644 --- a/skills/start.md +++ b/skills/start.md @@ -242,12 +242,12 @@ Ensure the base branch is up-to-date before branching: {{#if BRANCH_DEV}} ```bash -git checkout {{BRANCH_DEV}} && git pull origin {{BRANCH_DEV}} +git checkout {{BRANCH_DEV}} && git fetch origin {{BRANCH_DEV}} && git reset --hard origin/{{BRANCH_DEV}} ``` {{/if}} {{#if !BRANCH_DEV}} ```bash -git checkout {{BRANCH_PROD}} && git pull origin {{BRANCH_PROD}} +git checkout {{BRANCH_PROD}} && git fetch origin {{BRANCH_PROD}} && git reset --hard origin/{{BRANCH_PROD}} ``` {{/if}} @@ -349,12 +349,12 @@ Ensure the base branch is up-to-date before branching: {{#if BRANCH_DEV}} ```bash -git checkout {{BRANCH_DEV}} && git pull origin {{BRANCH_DEV}} +git checkout {{BRANCH_DEV}} && git fetch origin {{BRANCH_DEV}} && git reset --hard origin/{{BRANCH_DEV}} ``` {{/if}} {{#if !BRANCH_DEV}} ```bash -git checkout {{BRANCH_PROD}} && git pull origin {{BRANCH_PROD}} +git checkout {{BRANCH_PROD}} && git fetch origin {{BRANCH_PROD}} && git reset --hard origin/{{BRANCH_PROD}} ``` {{/if}} From 34c1f16ee430d570a014c3f63f3b1e83a140c93f Mon Sep 17 00:00:00 2001 From: Sebastien Taggart Date: Wed, 3 Jun 2026 18:20:22 -0400 Subject: [PATCH 2/2] Guard hard reset behind dirty-tree check and name branches explicitly --- .agents/skills/deploy/SKILL.md | 8 +++++--- .agents/skills/start/SKILL.md | 14 +++++++++----- .claude/commands/deploy.md | 8 +++++--- .claude/commands/start.md | 14 +++++++++----- .cursor/rules/deploy.mdc | 8 +++++--- .cursor/rules/start.mdc | 14 +++++++++----- .gemini/skills/deploy/SKILL.md | 8 +++++--- .gemini/skills/start/SKILL.md | 14 +++++++++----- Makefile.agents.mk | 8 ++++++++ skills/deploy.md | 22 ++++++++++++++++++++-- skills/start.md | 20 ++++++++++++++------ 11 files changed, 98 insertions(+), 40 deletions(-) diff --git a/.agents/skills/deploy/SKILL.md b/.agents/skills/deploy/SKILL.md index 3f0c85a..1a4683d 100644 --- a/.agents/skills/deploy/SKILL.md +++ b/.agents/skills/deploy/SKILL.md @@ -24,9 +24,11 @@ Required branch: `dev` (two-branch mode). If not on the required branch, abort and say: "Switch to `` before running `/deploy`." -Sync to the remote before proceeding (hard reset — the deploy branch is never edited locally, only fast-forwarded from CodeCannon's own merges): +Sync to the remote before proceeding. The deploy branch is never edited locally under the CodeCannon workflow (only fast-forwarded from CodeCannon's own merges), so a hard reset to origin is the correct sync; the dirty-tree guard catches accidental local edits before they get silently discarded: + ```bash -git fetch && git reset --hard @{u} +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` --- @@ -265,4 +267,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.agents/skills/start/SKILL.md b/.agents/skills/start/SKILL.md index 830e2bf..6e4b2a0 100644 --- a/.agents/skills/start/SKILL.md +++ b/.agents/skills/start/SKILL.md @@ -195,10 +195,12 @@ gh issue comment --body-file /issue_comment.md ### Step 4 — Create feature branch -Ensure the base branch is up-to-date before branching: +Ensure the base branch is a perfect mirror of origin before branching. The hard reset below is safe under the CodeCannon workflow (the integration/production branch is never edited locally — all changes flow through PRs), but the dirty-tree guard catches accidental local edits before they get silently discarded: ```bash -git checkout dev && git fetch origin dev && git reset --hard origin/dev +git checkout dev +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` Now create the feature branch: @@ -286,10 +288,12 @@ Present numbered findings: ### Step 4 — Check out branch -Ensure the base branch is up-to-date before branching: +Ensure the base branch is a perfect mirror of origin before branching (same safety rationale as Case A Step 4): ```bash -git checkout dev && git fetch origin dev && git reset --hard origin/dev +git checkout dev +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` Find and check out the existing branch, or create a new one linked to the issue: @@ -324,4 +328,4 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. - + diff --git a/.claude/commands/deploy.md b/.claude/commands/deploy.md index 9f445a9..9c647c2 100644 --- a/.claude/commands/deploy.md +++ b/.claude/commands/deploy.md @@ -19,9 +19,11 @@ Required branch: `dev` (two-branch mode). If not on the required branch, abort and say: "Switch to `` before running `/deploy`." -Sync to the remote before proceeding (hard reset — the deploy branch is never edited locally, only fast-forwarded from CodeCannon's own merges): +Sync to the remote before proceeding. The deploy branch is never edited locally under the CodeCannon workflow (only fast-forwarded from CodeCannon's own merges), so a hard reset to origin is the correct sync; the dirty-tree guard catches accidental local edits before they get silently discarded: + ```bash -git fetch && git reset --hard @{u} +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` --- @@ -260,4 +262,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.claude/commands/start.md b/.claude/commands/start.md index 6a09ff8..0bf8fab 100644 --- a/.claude/commands/start.md +++ b/.claude/commands/start.md @@ -190,10 +190,12 @@ gh issue comment --body-file /issue_comment.md ### Step 4 — Create feature branch -Ensure the base branch is up-to-date before branching: +Ensure the base branch is a perfect mirror of origin before branching. The hard reset below is safe under the CodeCannon workflow (the integration/production branch is never edited locally — all changes flow through PRs), but the dirty-tree guard catches accidental local edits before they get silently discarded: ```bash -git checkout dev && git fetch origin dev && git reset --hard origin/dev +git checkout dev +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` Now create the feature branch: @@ -281,10 +283,12 @@ Present numbered findings: ### Step 4 — Check out branch -Ensure the base branch is up-to-date before branching: +Ensure the base branch is a perfect mirror of origin before branching (same safety rationale as Case A Step 4): ```bash -git checkout dev && git fetch origin dev && git reset --hard origin/dev +git checkout dev +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` Find and check out the existing branch, or create a new one linked to the issue: @@ -319,4 +323,4 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. - + diff --git a/.cursor/rules/deploy.mdc b/.cursor/rules/deploy.mdc index 5ce73de..a049c8d 100644 --- a/.cursor/rules/deploy.mdc +++ b/.cursor/rules/deploy.mdc @@ -25,9 +25,11 @@ Required branch: `dev` (two-branch mode). If not on the required branch, abort and say: "Switch to `` before running `/deploy`." -Sync to the remote before proceeding (hard reset — the deploy branch is never edited locally, only fast-forwarded from CodeCannon's own merges): +Sync to the remote before proceeding. The deploy branch is never edited locally under the CodeCannon workflow (only fast-forwarded from CodeCannon's own merges), so a hard reset to origin is the correct sync; the dirty-tree guard catches accidental local edits before they get silently discarded: + ```bash -git fetch && git reset --hard @{u} +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` --- @@ -266,4 +268,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.cursor/rules/start.mdc b/.cursor/rules/start.mdc index d1fb74a..e709312 100644 --- a/.cursor/rules/start.mdc +++ b/.cursor/rules/start.mdc @@ -196,10 +196,12 @@ gh issue comment --body-file /issue_comment.md ### Step 4 — Create feature branch -Ensure the base branch is up-to-date before branching: +Ensure the base branch is a perfect mirror of origin before branching. The hard reset below is safe under the CodeCannon workflow (the integration/production branch is never edited locally — all changes flow through PRs), but the dirty-tree guard catches accidental local edits before they get silently discarded: ```bash -git checkout dev && git fetch origin dev && git reset --hard origin/dev +git checkout dev +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` Now create the feature branch: @@ -287,10 +289,12 @@ Present numbered findings: ### Step 4 — Check out branch -Ensure the base branch is up-to-date before branching: +Ensure the base branch is a perfect mirror of origin before branching (same safety rationale as Case A Step 4): ```bash -git checkout dev && git fetch origin dev && git reset --hard origin/dev +git checkout dev +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` Find and check out the existing branch, or create a new one linked to the issue: @@ -325,4 +329,4 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. - + diff --git a/.gemini/skills/deploy/SKILL.md b/.gemini/skills/deploy/SKILL.md index b991dd2..6a97b75 100644 --- a/.gemini/skills/deploy/SKILL.md +++ b/.gemini/skills/deploy/SKILL.md @@ -24,9 +24,11 @@ Required branch: `dev` (two-branch mode). If not on the required branch, abort and say: "Switch to `` before running `/deploy`." -Sync to the remote before proceeding (hard reset — the deploy branch is never edited locally, only fast-forwarded from CodeCannon's own merges): +Sync to the remote before proceeding. The deploy branch is never edited locally under the CodeCannon workflow (only fast-forwarded from CodeCannon's own merges), so a hard reset to origin is the correct sync; the dirty-tree guard catches accidental local edits before they get silently discarded: + ```bash -git fetch && git reset --hard @{u} +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` --- @@ -265,4 +267,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.gemini/skills/start/SKILL.md b/.gemini/skills/start/SKILL.md index 8c65c68..d286314 100644 --- a/.gemini/skills/start/SKILL.md +++ b/.gemini/skills/start/SKILL.md @@ -195,10 +195,12 @@ gh issue comment --body-file /issue_comment.md ### Step 4 — Create feature branch -Ensure the base branch is up-to-date before branching: +Ensure the base branch is a perfect mirror of origin before branching. The hard reset below is safe under the CodeCannon workflow (the integration/production branch is never edited locally — all changes flow through PRs), but the dirty-tree guard catches accidental local edits before they get silently discarded: ```bash -git checkout dev && git fetch origin dev && git reset --hard origin/dev +git checkout dev +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` Now create the feature branch: @@ -286,10 +288,12 @@ Present numbered findings: ### Step 4 — Check out branch -Ensure the base branch is up-to-date before branching: +Ensure the base branch is a perfect mirror of origin before branching (same safety rationale as Case A Step 4): ```bash -git checkout dev && git fetch origin dev && git reset --hard origin/dev +git checkout dev +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on dev — resolve before continuing."; exit 1; } +git fetch origin dev && git reset --hard origin/dev ``` Find and check out the existing branch, or create a new one linked to the issue: @@ -324,4 +328,4 @@ When done, say: **"The code is ready for review. Please run `make dev` and test - The issue is assigned to `@me` at creation. If you are creating a ticket on someone else's behalf, remove the assignee after creation with `gh issue edit --remove-assignee @me`. - Apply resolved labels and milestone to every new issue. Label resolution order: per-invocation flag → pool selection from `bug, documentation, enhancement, chore` → omit `--label` entirely. Never apply a label outside `bug, documentation, enhancement, chore`. - Milestone resolution order: per-invocation flag → auto-detected from GitHub open milestones. Never prompt for a milestone more than once per invocation. - + diff --git a/Makefile.agents.mk b/Makefile.agents.mk index 8f89365..2f0dc01 100644 --- a/Makefile.agents.mk +++ b/Makefile.agents.mk @@ -83,7 +83,15 @@ merge: fi; \ gh pr merge --merge && \ git checkout $(INTEGRATION_BRANCH) && \ + if ! git diff --quiet || ! git diff --cached --quiet; then \ + echo "Error: uncommitted changes on $(INTEGRATION_BRANCH); refusing to reset to origin. Resolve manually."; exit 1; \ + fi; \ git fetch origin $(INTEGRATION_BRANCH) && \ + ahead=$$(git rev-list --count origin/$(INTEGRATION_BRANCH)..HEAD); \ + if [ "$$ahead" != "0" ]; then \ + echo "Warning: discarding $$ahead local-only commit(s) on $(INTEGRATION_BRANCH) to match origin (recover via 'git reflog' within 90 days):"; \ + git log --oneline origin/$(INTEGRATION_BRANCH)..HEAD; \ + fi; \ git reset --hard origin/$(INTEGRATION_BRANCH) && \ echo "PR merged into $(INTEGRATION_BRANCH)." diff --git a/skills/deploy.md b/skills/deploy.md index d2943ce..ae8b799 100644 --- a/skills/deploy.md +++ b/skills/deploy.md @@ -32,10 +32,28 @@ Required branch: `{{BRANCH_PROD}}` (trunk mode). If not on the required branch, abort and say: "Switch to `` before running `/deploy`." -Sync to the remote before proceeding (hard reset — the deploy branch is never edited locally, only fast-forwarded from CodeCannon's own merges): +Sync to the remote before proceeding. The deploy branch is never edited locally under the CodeCannon workflow (only fast-forwarded from CodeCannon's own merges), so a hard reset to origin is the correct sync; the dirty-tree guard catches accidental local edits before they get silently discarded: + +{{#if BRANCH_TEST}} +```bash +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on {{BRANCH_TEST}} — resolve before continuing."; exit 1; } +git fetch origin {{BRANCH_TEST}} && git reset --hard origin/{{BRANCH_TEST}} +``` +{{/if}} +{{#if !BRANCH_TEST}} +{{#if BRANCH_DEV}} ```bash -git fetch && git reset --hard @{u} +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on {{BRANCH_DEV}} — resolve before continuing."; exit 1; } +git fetch origin {{BRANCH_DEV}} && git reset --hard origin/{{BRANCH_DEV}} ``` +{{/if}} +{{#if !BRANCH_DEV}} +```bash +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on {{BRANCH_PROD}} — resolve before continuing."; exit 1; } +git fetch origin {{BRANCH_PROD}} && git reset --hard origin/{{BRANCH_PROD}} +``` +{{/if}} +{{/if}} --- diff --git a/skills/start.md b/skills/start.md index 2c964f6..86206b4 100644 --- a/skills/start.md +++ b/skills/start.md @@ -238,16 +238,20 @@ gh issue comment --body-file /issue_comment.md ### Step 4 — Create feature branch -Ensure the base branch is up-to-date before branching: +Ensure the base branch is a perfect mirror of origin before branching. The hard reset below is safe under the CodeCannon workflow (the integration/production branch is never edited locally — all changes flow through PRs), but the dirty-tree guard catches accidental local edits before they get silently discarded: {{#if BRANCH_DEV}} ```bash -git checkout {{BRANCH_DEV}} && git fetch origin {{BRANCH_DEV}} && git reset --hard origin/{{BRANCH_DEV}} +git checkout {{BRANCH_DEV}} +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on {{BRANCH_DEV}} — resolve before continuing."; exit 1; } +git fetch origin {{BRANCH_DEV}} && git reset --hard origin/{{BRANCH_DEV}} ``` {{/if}} {{#if !BRANCH_DEV}} ```bash -git checkout {{BRANCH_PROD}} && git fetch origin {{BRANCH_PROD}} && git reset --hard origin/{{BRANCH_PROD}} +git checkout {{BRANCH_PROD}} +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on {{BRANCH_PROD}} — resolve before continuing."; exit 1; } +git fetch origin {{BRANCH_PROD}} && git reset --hard origin/{{BRANCH_PROD}} ``` {{/if}} @@ -345,16 +349,20 @@ Present numbered findings: ### Step 4 — Check out branch -Ensure the base branch is up-to-date before branching: +Ensure the base branch is a perfect mirror of origin before branching (same safety rationale as Case A Step 4): {{#if BRANCH_DEV}} ```bash -git checkout {{BRANCH_DEV}} && git fetch origin {{BRANCH_DEV}} && git reset --hard origin/{{BRANCH_DEV}} +git checkout {{BRANCH_DEV}} +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on {{BRANCH_DEV}} — resolve before continuing."; exit 1; } +git fetch origin {{BRANCH_DEV}} && git reset --hard origin/{{BRANCH_DEV}} ``` {{/if}} {{#if !BRANCH_DEV}} ```bash -git checkout {{BRANCH_PROD}} && git fetch origin {{BRANCH_PROD}} && git reset --hard origin/{{BRANCH_PROD}} +git checkout {{BRANCH_PROD}} +git diff --quiet && git diff --cached --quiet || { echo "Uncommitted changes on {{BRANCH_PROD}} — resolve before continuing."; exit 1; } +git fetch origin {{BRANCH_PROD}} && git reset --hard origin/{{BRANCH_PROD}} ``` {{/if}}