diff --git a/.agents/skills/deploy/SKILL.md b/.agents/skills/deploy/SKILL.md index 4523b10..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`." -Pull the latest changes before proceeding: +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 pull +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 8389046..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 pull 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 pull 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 2217a29..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`." -Pull the latest changes before proceeding: +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 pull +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 e538771..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 pull 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 pull 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 a55d216..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`." -Pull the latest changes before proceeding: +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 pull +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 afde6cf..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 pull 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 pull 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 b24e427..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`." -Pull the latest changes before proceeding: +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 pull +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 f792167..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 pull 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 pull 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 35a3ea9..2f0dc01 100644 --- a/Makefile.agents.mk +++ b/Makefile.agents.mk @@ -83,7 +83,16 @@ merge: fi; \ gh pr merge --merge && \ git checkout $(INTEGRATION_BRANCH) && \ - git pull origin $(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)." # Promote integration branch to staging. Creates a PR: INTEGRATION_BRANCH → STAGING_BRANCH. diff --git a/skills/deploy.md b/skills/deploy.md index b584b13..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`." -Pull the latest changes before proceeding: +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 pull +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 5fe8fcd..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 pull 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 pull 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 pull 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 pull 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}}