diff --git a/.agents/skills/workflow-ci-contract/references/d-guarantees.md b/.agents/skills/workflow-ci-contract/references/d-guarantees.md index f1f371e1..0b8bd087 100644 --- a/.agents/skills/workflow-ci-contract/references/d-guarantees.md +++ b/.agents/skills/workflow-ci-contract/references/d-guarantees.md @@ -23,6 +23,7 @@ The required behaviors, organized by domain. Each is a **MUST**, and its `Output - **D2.2 Release branch matches version classification.** Input: a real (non-smoke) release build. Output: the gate fails loudly if the default branch carries a prerelease suffix **or** a non-default branch carries none. It strips `+buildmetadata` before testing for the prerelease `-` (only a core/prerelease `-` counts), and on a smoke build the **check exits early while the job still reports success** (a detached PR head always versions as prerelease). Read that as the validation being skipped rather than the job, because a job-level `if:` would skip the job itself, and a dependent whose `if:` carries no status-check function gets the implicit `success()` and skips with it. `dotnet-publish`, `build-nuget`, and `build-pypi` are such dependents of `validate-release`, so a job-level skip there would skip their smoke builds with it. *Prevents: a non-default leg published as stable, a build-metadata false-positive, and the gate blocking every default-base promotion PR.* - **D2.3 Publish only from main or develop.** Input: a dispatch publish. Output: a dispatch from any ref other than `main` or `develop` fails fast. *Prevents: cutting a release from an unintended branch.* - **D2.4 Mutually-exclusive / paired inputs are validated.** Input: a workflow with either/or or must-pair inputs (e.g. the docker-readme task's `repositories` XOR `manifest`+`manifest-jq`). Output: a half-filled or conflicting combination fails fast. *Prevents: a silent fall-through.* +- **D2.5 The release gate refuses a branch input git would not accept as a name.** Input: a release task taking a `branch` input, on any run. Output: the gate runs `git check-ref-format --branch` over that value and fails when git rejects it, ahead of D2.2's smoke exit, with an error echoing no part of the value. *Prevents: a `::` or `##[` in a caller's value forming a workflow command wherever a later step prints the branch, on a smoke run as much as on a publish.* ### D3 - Versioning and Classification diff --git a/.claude-plugin/fleet-skills/.source-digests/workflow-ci-contract b/.claude-plugin/fleet-skills/.source-digests/workflow-ci-contract index 7c7c78a8..c2dc11dd 100644 --- a/.claude-plugin/fleet-skills/.source-digests/workflow-ci-contract +++ b/.claude-plugin/fleet-skills/.source-digests/workflow-ci-contract @@ -1 +1 @@ -0399e2dde2dba6d3 +ef59059f32df5cea diff --git a/.claude-plugin/fleet-skills/skills/workflow-ci-contract/references/d-guarantees.md b/.claude-plugin/fleet-skills/skills/workflow-ci-contract/references/d-guarantees.md index f1f371e1..0b8bd087 100644 --- a/.claude-plugin/fleet-skills/skills/workflow-ci-contract/references/d-guarantees.md +++ b/.claude-plugin/fleet-skills/skills/workflow-ci-contract/references/d-guarantees.md @@ -23,6 +23,7 @@ The required behaviors, organized by domain. Each is a **MUST**, and its `Output - **D2.2 Release branch matches version classification.** Input: a real (non-smoke) release build. Output: the gate fails loudly if the default branch carries a prerelease suffix **or** a non-default branch carries none. It strips `+buildmetadata` before testing for the prerelease `-` (only a core/prerelease `-` counts), and on a smoke build the **check exits early while the job still reports success** (a detached PR head always versions as prerelease). Read that as the validation being skipped rather than the job, because a job-level `if:` would skip the job itself, and a dependent whose `if:` carries no status-check function gets the implicit `success()` and skips with it. `dotnet-publish`, `build-nuget`, and `build-pypi` are such dependents of `validate-release`, so a job-level skip there would skip their smoke builds with it. *Prevents: a non-default leg published as stable, a build-metadata false-positive, and the gate blocking every default-base promotion PR.* - **D2.3 Publish only from main or develop.** Input: a dispatch publish. Output: a dispatch from any ref other than `main` or `develop` fails fast. *Prevents: cutting a release from an unintended branch.* - **D2.4 Mutually-exclusive / paired inputs are validated.** Input: a workflow with either/or or must-pair inputs (e.g. the docker-readme task's `repositories` XOR `manifest`+`manifest-jq`). Output: a half-filled or conflicting combination fails fast. *Prevents: a silent fall-through.* +- **D2.5 The release gate refuses a branch input git would not accept as a name.** Input: a release task taking a `branch` input, on any run. Output: the gate runs `git check-ref-format --branch` over that value and fails when git rejects it, ahead of D2.2's smoke exit, with an error echoing no part of the value. *Prevents: a `::` or `##[` in a caller's value forming a workflow command wherever a later step prints the branch, on a smoke run as much as on a publish.* ### D3 - Versioning and Classification diff --git a/.github/skills/workflow-ci-contract/references/d-guarantees.md b/.github/skills/workflow-ci-contract/references/d-guarantees.md index f1f371e1..0b8bd087 100644 --- a/.github/skills/workflow-ci-contract/references/d-guarantees.md +++ b/.github/skills/workflow-ci-contract/references/d-guarantees.md @@ -23,6 +23,7 @@ The required behaviors, organized by domain. Each is a **MUST**, and its `Output - **D2.2 Release branch matches version classification.** Input: a real (non-smoke) release build. Output: the gate fails loudly if the default branch carries a prerelease suffix **or** a non-default branch carries none. It strips `+buildmetadata` before testing for the prerelease `-` (only a core/prerelease `-` counts), and on a smoke build the **check exits early while the job still reports success** (a detached PR head always versions as prerelease). Read that as the validation being skipped rather than the job, because a job-level `if:` would skip the job itself, and a dependent whose `if:` carries no status-check function gets the implicit `success()` and skips with it. `dotnet-publish`, `build-nuget`, and `build-pypi` are such dependents of `validate-release`, so a job-level skip there would skip their smoke builds with it. *Prevents: a non-default leg published as stable, a build-metadata false-positive, and the gate blocking every default-base promotion PR.* - **D2.3 Publish only from main or develop.** Input: a dispatch publish. Output: a dispatch from any ref other than `main` or `develop` fails fast. *Prevents: cutting a release from an unintended branch.* - **D2.4 Mutually-exclusive / paired inputs are validated.** Input: a workflow with either/or or must-pair inputs (e.g. the docker-readme task's `repositories` XOR `manifest`+`manifest-jq`). Output: a half-filled or conflicting combination fails fast. *Prevents: a silent fall-through.* +- **D2.5 The release gate refuses a branch input git would not accept as a name.** Input: a release task taking a `branch` input, on any run. Output: the gate runs `git check-ref-format --branch` over that value and fails when git rejects it, ahead of D2.2's smoke exit, with an error echoing no part of the value. *Prevents: a `::` or `##[` in a caller's value forming a workflow command wherever a later step prints the branch, on a smoke run as much as on a publish.* ### D3 - Versioning and Classification diff --git a/WORKFLOW.md b/WORKFLOW.md index 3f424b81..5b410c49 100644 --- a/WORKFLOW.md +++ b/WORKFLOW.md @@ -151,6 +151,7 @@ The required behaviors, organized by domain. Each is a **MUST**, and its `Output - **D2.2 Release branch matches version classification.** Input: a real (non-smoke) release build. Output: the gate fails loudly if the default branch carries a prerelease suffix **or** a non-default branch carries none. It strips `+buildmetadata` before testing for the prerelease `-` (only a core/prerelease `-` counts), and on a smoke build the **check exits early while the job still reports success** (a detached PR head always versions as prerelease). Read that as the validation being skipped rather than the job, because a job-level `if:` would skip the job itself, and a dependent whose `if:` carries no status-check function gets the implicit `success()` and skips with it. `dotnet-publish`, `build-nuget`, and `build-pypi` are such dependents of `validate-release`, so a job-level skip there would skip their smoke builds with it. *Prevents: a non-default leg published as stable, a build-metadata false-positive, and the gate blocking every default-base promotion PR.* - **D2.3 Publish only from main or develop.** Input: a dispatch publish. Output: a dispatch from any ref other than `main` or `develop` fails fast. *Prevents: cutting a release from an unintended branch.* - **D2.4 Mutually-exclusive / paired inputs are validated.** Input: a workflow with either/or or must-pair inputs (e.g. the docker-readme task's `repositories` XOR `manifest`+`manifest-jq`). Output: a half-filled or conflicting combination fails fast. *Prevents: a silent fall-through.* +- **D2.5 The release gate refuses a branch input git would not accept as a name.** Input: a release task taking a `branch` input, on any run. Output: the gate runs `git check-ref-format --branch` over that value and fails when git rejects it, ahead of D2.2's smoke exit, with an error echoing no part of the value. *Prevents: a `::` or `##[` in a caller's value forming a workflow command wherever a later step prints the branch, on a smoke run as much as on a publish.* ### D3 - Versioning and Classification diff --git a/reports/canonical-review.json b/reports/canonical-review.json index 37ed10f2..f54e0ce2 100644 --- a/reports/canonical-review.json +++ b/reports/canonical-review.json @@ -771,11 +771,11 @@ }, { "unit": ".agents/skills/workflow-ci-contract/references/d-guarantees.md > The Behavioral Contract", - "digest": "sha256:cb59602471dff258ead049a85eb5d517df893eb6f1c81899ecd243ea0e2e8262", + "digest": "sha256:3fc23c33c6b6e12cc1c93ebf4e1b8c00cc41029a8b90cccf0c772ff32daed922", "reviewer": "agent-skill", - "findings": 0, - "hubCommit": "09971b8051dd11d3748999cc5182116dd42ffa4c", - "stamp": "2026-09-11T19:32:07Z" + "findings": null, + "hubCommit": "d2a7a170ecf5ebf75ff7574a6031f6b4b89ee485", + "stamp": "2026-09-11T22:21:12Z" }, { "unit": ".agents/skills/workflow-ci-contract/references/test-methodology.md > (preamble)", @@ -1035,11 +1035,11 @@ }, { "unit": "WORKFLOW.md > 4. Behavioral Contract: Expected Outcomes", - "digest": "sha256:88009557df8f3467addd53d216e67f2ef2d7e928f05e4b23932ece5dee1c713a", + "digest": "sha256:adf2009ef4e8dd1b78c8ec5f102f479146affdc9940cfa841831a7adb8e4e5ac", "reviewer": "agent-skill", - "findings": 0, - "hubCommit": "09971b8051dd11d3748999cc5182116dd42ffa4c", - "stamp": "2026-09-11T19:32:07Z" + "findings": null, + "hubCommit": "d2a7a170ecf5ebf75ff7574a6031f6b4b89ee485", + "stamp": "2026-09-11T22:21:12Z" }, { "unit": "WORKFLOW.md > 5. Test Methodology",