@metasession.co/devaudit-cli 0.3.14 → 0.3.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/sdlc/files/_common/Test_Policy.md +2 -2
- package/sdlc/files/_common/Test_Strategy.md +4 -4
- package/sdlc/files/_common/scripts/check-release-pr-scope.sh +11 -0
- package/sdlc/files/_common/scripts/check-release-pr-scope.test.sh +42 -1
- package/sdlc/files/_common/scripts/standalone-housekeeping-release.sh +98 -0
- package/sdlc/files/_common/scripts/standalone-housekeeping-release.test.sh +45 -0
- package/sdlc/files/_common/skills/e2e-test-engineer/SKILL.md +9 -2
- package/sdlc/files/_common/skills/e2e-test-engineer/references/e2e-regression-3-tier.yml +4 -6
- package/sdlc/files/_common/skills/sdlc-implementer/SKILL.md +12 -16
- package/sdlc/files/_common/workflows/devaudit-update-install.md +4 -4
- package/sdlc/files/ci/ci.yml.template +20 -0
- package/sdlc/files/ci/compliance-evidence.yml.template +13 -43
- package/sdlc/files/ci/post-deploy-prod.yml.template +32 -3
- package/sdlc/package.json +1 -1
- package/sdlc/src/blueprints/3-compile-evidence.raw.md +8 -24
- package/sdlc/src/blueprints/5-deploy-main.raw.md +23 -50
- package/sdlc/src/blueprints/implementing-an-sdlc-issue.raw.md +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metasession.co/devaudit-cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.16",
|
|
4
4
|
"description": "DevAudit CLI — installs, syncs, and operates the Metasession SDLC across consumer projects.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@clack/prompts": "^0.8.2",
|
|
36
|
-
"@metasession.co/devaudit-plugin-sdk": "^0.3.
|
|
36
|
+
"@metasession.co/devaudit-plugin-sdk": "^0.3.16",
|
|
37
37
|
"ajv": "^8.20.0",
|
|
38
38
|
"commander": "^12.1.0",
|
|
39
39
|
"consola": "^3.2.3",
|
|
@@ -155,8 +155,8 @@ AI involvement in Medium or High categories raises risk by one level. The Test S
|
|
|
155
155
|
The MoSCoW prioritisation of acceptance criteria maps onto three E2E gates, each enforced at a different point in the workflow:
|
|
156
156
|
|
|
157
157
|
- **Must-tier ACs in the smoke subset** must pass on every push to the integration branch. Blocking — a red smoke gate stops the integration hop.
|
|
158
|
-
- **Must-tier ACs in the critical subset** must pass on every PR to the release branch. Blocking — a red critical gate stops
|
|
159
|
-
- **Should/Could-tier ACs (full regression)**
|
|
158
|
+
- **Must-tier ACs in the critical subset** must pass on every consumer-enabled PR to the release branch. Blocking — a red critical gate stops that release.
|
|
159
|
+
- **Should/Could-tier ACs (full regression)** are not pre-merge blocking. The consumer chooses a post-merge, scheduled, or manual-dispatch safety net and must triage any recorded failure within working hours.
|
|
160
160
|
|
|
161
161
|
Operator override on a hotfix issue (accept-with-rationale) is logged on the issue itself + carried in the next release's `test-execution-summary.md` design record (devaudit#50). The framework does not permit silently shipping a failing test — every red regression spec ends as either fixed, reverted, or accepted-with-recorded-rationale.
|
|
162
162
|
|
|
@@ -45,14 +45,14 @@ Full E2E regression on every PR is expensive — a 30+ minute wait per release-P
|
|
|
45
45
|
| Tier | Location | When it runs | Wall-clock target | Audit role |
|
|
46
46
|
| --- | --- | --- | --- | --- |
|
|
47
47
|
| **smoke** | `e2e/smoke/*.spec.ts` | every push to `$INTEGRATION_BRANCH` (via `ci.yml`) | ~3–5 min | fast feedback on every change |
|
|
48
|
-
| **critical** | `e2e/smoke/` + `e2e/critical/*.spec.ts` | PR-to-`$RELEASE_BRANCH`
|
|
49
|
-
| **regression** | all `e2e/**/*.spec.ts` |
|
|
48
|
+
| **critical** | `e2e/smoke/` + `e2e/critical/*.spec.ts` | PR-to-`$RELEASE_BRANCH` when the consumer enables `e2e-regression.yml` | ~10–15 min | release-readiness Must gate |
|
|
49
|
+
| **regression** | all `e2e/**/*.spec.ts` | `workflow_dispatch` and any consumer-configured post-merge or scheduled run | ~35 min (or your project's full pack) | full audit trail + drift catch |
|
|
50
50
|
|
|
51
51
|
The mapping to MoSCoW: **Must-priority SRS items live in `e2e/smoke/` (fast feedback) and `e2e/critical/` (release gate); Should/Could items live in `e2e/` and are covered by the regression tier.** The classifier is the developer authoring the spec — see `skills/e2e-test-engineer/SKILL.md` Phase 3 for the decision tree.
|
|
52
52
|
|
|
53
|
-
**Cost philosophy.** Smoke protects every push from breaking the headline flow. Critical protects every release from a Must-tier regression. Full regression protects the audit trail
|
|
53
|
+
**Cost philosophy.** Smoke protects every push from breaking the headline flow. Critical protects every release from a Must-tier regression. Full regression protects the audit trail and catches drift when the consumer elects to run it. We accept that a Should/Could-tier regression can sit outside the PR gate; the consumer chooses whether its safety net is post-merge, scheduled, or manual dispatch. The framework does not impose a daily/nightly run.
|
|
54
54
|
|
|
55
|
-
**Post-merge safety net.**
|
|
55
|
+
**Post-merge safety net.** When a consumer enables a post-merge regression run, `e2e-regression.yml` may file a `bug, priority:high` issue tagging the merge commit and failing specs. The operator triages within working hours — hotfix forward, revert the commit, or accept-with-rationale if the failure is environmental. No automated revert: flakes and UAT-data drift require human judgment.
|
|
56
56
|
|
|
57
57
|
**Reference workflow.** A copy-pasteable `e2e-regression.yml` shape lives at `skills/e2e-test-engineer/references/e2e-regression-3-tier.yml`. Adoption is opt-in per consumer (the framework doesn't currently sync this workflow; consumers own their own `e2e-regression.yml`).
|
|
58
58
|
|
|
@@ -73,6 +73,17 @@ if [ "$DECLARED_SCOPE" != "$CURRENT_RELEASE" ]; then
|
|
|
73
73
|
exit 1
|
|
74
74
|
fi
|
|
75
75
|
|
|
76
|
+
if [[ "$CURRENT_RELEASE" =~ ^v[0-9]{4}\.[0-9]{2}\.[0-9]{2}(\.[0-9]+)?$ ]]; then
|
|
77
|
+
DECLARATION="compliance/standalone-housekeeping/STANDALONE-HOUSEKEEPING-${CURRENT_RELEASE}.json"
|
|
78
|
+
if ! printf '%s\n%s\n' "${PR_TITLE:-}" "${PR_BODY:-}" | grep -Fqi "Standalone housekeeping promotion"; then
|
|
79
|
+
echo "::error::Bare-date releases may only be promoted with an explicit standalone housekeeping exception."
|
|
80
|
+
echo "::error::Add 'Standalone housekeeping promotion' to the PR title or body and include ${DECLARATION}."
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
chmod +x scripts/standalone-housekeeping-release.sh 2>/dev/null || true
|
|
84
|
+
bash scripts/standalone-housekeeping-release.sh validate "$CURRENT_RELEASE" "$DECLARATION"
|
|
85
|
+
fi
|
|
86
|
+
|
|
76
87
|
if [[ "$CURRENT_RELEASE" =~ ^REQ-[0-9]+$ ]]; then
|
|
77
88
|
if [ ! -x scripts/extract-release-metadata.sh ]; then
|
|
78
89
|
chmod +x scripts/extract-release-metadata.sh 2>/dev/null || true
|
|
@@ -39,9 +39,10 @@ assert_grep() {
|
|
|
39
39
|
make_fixture() {
|
|
40
40
|
local dir="$1" subject="$2"
|
|
41
41
|
rm -rf "$dir"
|
|
42
|
-
mkdir -p "$dir/scripts" "$dir/compliance/pending-releases"
|
|
42
|
+
mkdir -p "$dir/scripts" "$dir/compliance/pending-releases" "$dir/compliance/standalone-housekeeping"
|
|
43
43
|
cp "$SCRIPT_DIR/derive-release-version.sh" "$dir/scripts/derive-release-version.sh"
|
|
44
44
|
cp "$SCRIPT_DIR/extract-release-metadata.sh" "$dir/scripts/extract-release-metadata.sh"
|
|
45
|
+
cp "$SCRIPT_DIR/standalone-housekeeping-release.sh" "$dir/scripts/standalone-housekeeping-release.sh"
|
|
45
46
|
cp "$HELPER" "$dir/scripts/check-release-pr-scope.sh"
|
|
46
47
|
chmod +x "$dir/scripts/"*.sh
|
|
47
48
|
(
|
|
@@ -133,5 +134,45 @@ assert_exit "hotfix branch skips" 0 "$CODE"
|
|
|
133
134
|
assert_grep "hotfix skip message" 'Hotfix PR detected' "$OUT"
|
|
134
135
|
echo ""
|
|
135
136
|
|
|
137
|
+
echo "--- Test 5: bare-date releases require an explicit standalone declaration ---"
|
|
138
|
+
make_fixture "$WORK/test5" "chore: standalone housekeeping release"
|
|
139
|
+
cat > "$WORK/test5/compliance/standalone-housekeeping/STANDALONE-HOUSEKEEPING-v2026.07.18.json" <<'EOF'
|
|
140
|
+
{
|
|
141
|
+
"schemaVersion": 1,
|
|
142
|
+
"version": "v2026.07.18",
|
|
143
|
+
"releaseMode": "standalone_housekeeping",
|
|
144
|
+
"reason": "Urgent operational change cannot wait for the next tracked requirement release."
|
|
145
|
+
}
|
|
146
|
+
EOF
|
|
147
|
+
OUT="$WORK/test5.out"
|
|
148
|
+
if run_check "$WORK/test5" "$OUT" env PR_TITLE="Standalone housekeeping promotion: v2026.07.18" PR_BODY=$'## Release\n- Release: v2026.07.18\n'; then
|
|
149
|
+
CODE=0
|
|
150
|
+
else
|
|
151
|
+
CODE=$?
|
|
152
|
+
fi
|
|
153
|
+
assert_exit "declared standalone housekeeping release passes" 0 "$CODE"
|
|
154
|
+
assert_grep "standalone validation is emitted" 'Standalone housekeeping declaration is valid' "$OUT"
|
|
155
|
+
echo ""
|
|
156
|
+
|
|
157
|
+
echo "--- Test 6: bare-date releases without the exception marker fail ---"
|
|
158
|
+
make_fixture "$WORK/test6" "chore: standalone housekeeping release"
|
|
159
|
+
cat > "$WORK/test6/compliance/standalone-housekeeping/STANDALONE-HOUSEKEEPING-v2026.07.18.json" <<'EOF'
|
|
160
|
+
{
|
|
161
|
+
"schemaVersion": 1,
|
|
162
|
+
"version": "v2026.07.18",
|
|
163
|
+
"releaseMode": "standalone_housekeeping",
|
|
164
|
+
"reason": "Urgent operational change cannot wait for the next tracked requirement release."
|
|
165
|
+
}
|
|
166
|
+
EOF
|
|
167
|
+
OUT="$WORK/test6.out"
|
|
168
|
+
if run_check "$WORK/test6" "$OUT" env PR_TITLE="Release: v2026.07.18" PR_BODY=$'## Release\n- Release: v2026.07.18\n'; then
|
|
169
|
+
CODE=0
|
|
170
|
+
else
|
|
171
|
+
CODE=$?
|
|
172
|
+
fi
|
|
173
|
+
assert_exit "bare-date release without exception marker fails" 1 "$CODE"
|
|
174
|
+
assert_grep "exception marker failure is clear" 'explicit standalone housekeeping exception' "$OUT"
|
|
175
|
+
echo ""
|
|
176
|
+
|
|
136
177
|
echo "=== check-release-pr-scope.test.sh: $PASS passed, $FAIL failed ==="
|
|
137
178
|
[ "$FAIL" -eq 0 ]
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# standalone-housekeeping-release.sh — validate and promote an explicit
|
|
3
|
+
# standalone-housekeeping exception after a reviewed, green main promotion.
|
|
4
|
+
#
|
|
5
|
+
# Manifest contract:
|
|
6
|
+
# compliance/standalone-housekeeping/STANDALONE-HOUSEKEEPING-vYYYY.MM.DD.json
|
|
7
|
+
# {
|
|
8
|
+
# "schemaVersion": 1,
|
|
9
|
+
# "version": "vYYYY.MM.DD",
|
|
10
|
+
# "releaseMode": "standalone_housekeeping",
|
|
11
|
+
# "reason": "Why this cannot wait for the next tracked REQ release."
|
|
12
|
+
# }
|
|
13
|
+
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
|
|
16
|
+
COMMAND="${1:-}"
|
|
17
|
+
VERSION="${2:-}"
|
|
18
|
+
MANIFEST_PATH="${3:-}"
|
|
19
|
+
|
|
20
|
+
usage() {
|
|
21
|
+
echo "Usage: $0 validate <version> <manifest-path>" >&2
|
|
22
|
+
echo " $0 promote <project-slug> <version> <manifest-path>" >&2
|
|
23
|
+
exit 2
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
validate_manifest() {
|
|
27
|
+
local expected_version="$1" path="$2"
|
|
28
|
+
if ! [[ "$expected_version" =~ ^v[0-9]{4}\.[0-9]{2}\.[0-9]{2}(\.[0-9]+)?$ ]]; then
|
|
29
|
+
echo "Error: ${expected_version} is not a bare-date housekeeping version." >&2
|
|
30
|
+
return 1
|
|
31
|
+
fi
|
|
32
|
+
if [ ! -f "$path" ]; then
|
|
33
|
+
echo "Error: standalone-housekeeping declaration not found: ${path}" >&2
|
|
34
|
+
return 1
|
|
35
|
+
fi
|
|
36
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
37
|
+
echo "Error: jq is required." >&2
|
|
38
|
+
return 1
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
local schema_version manifest_version release_mode reason
|
|
42
|
+
schema_version=$(jq -r '.schemaVersion // empty' "$path")
|
|
43
|
+
manifest_version=$(jq -r '.version // empty' "$path")
|
|
44
|
+
release_mode=$(jq -r '.releaseMode // empty' "$path")
|
|
45
|
+
reason=$(jq -r '.reason // empty' "$path")
|
|
46
|
+
|
|
47
|
+
[ "$schema_version" = "1" ] || { echo "Error: schemaVersion must be 1." >&2; return 1; }
|
|
48
|
+
[ "$manifest_version" = "$expected_version" ] || { echo "Error: declaration version must exactly match ${expected_version}." >&2; return 1; }
|
|
49
|
+
[ "$release_mode" = "standalone_housekeeping" ] || { echo "Error: releaseMode must be standalone_housekeeping." >&2; return 1; }
|
|
50
|
+
if [ "${#reason}" -lt 20 ]; then
|
|
51
|
+
echo "Error: reason must explain why this cannot wait for the next tracked REQ (minimum 20 characters)." >&2
|
|
52
|
+
return 1
|
|
53
|
+
fi
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
case "$COMMAND" in
|
|
57
|
+
validate)
|
|
58
|
+
[ -n "$VERSION" ] && [ -n "$MANIFEST_PATH" ] || usage
|
|
59
|
+
validate_manifest "$VERSION" "$MANIFEST_PATH"
|
|
60
|
+
echo "Standalone housekeeping declaration is valid for ${VERSION}."
|
|
61
|
+
;;
|
|
62
|
+
promote)
|
|
63
|
+
PROJECT_SLUG="${2:-}"
|
|
64
|
+
VERSION="${3:-}"
|
|
65
|
+
MANIFEST_PATH="${4:-}"
|
|
66
|
+
[ -n "$PROJECT_SLUG" ] && [ -n "$VERSION" ] && [ -n "$MANIFEST_PATH" ] || usage
|
|
67
|
+
validate_manifest "$VERSION" "$MANIFEST_PATH"
|
|
68
|
+
: "${DEVAUDIT_BASE_URL:?DEVAUDIT_BASE_URL must be set}"
|
|
69
|
+
: "${DEVAUDIT_API_KEY:?DEVAUDIT_API_KEY must be set}"
|
|
70
|
+
|
|
71
|
+
BASE_URL="${DEVAUDIT_BASE_URL%/}"
|
|
72
|
+
ENCODED_SLUG=$(jq -rn --arg value "$PROJECT_SLUG" '$value|@uri')
|
|
73
|
+
ENCODED_VERSION=$(jq -rn --arg value "$VERSION" '$value|@uri')
|
|
74
|
+
RESOLVED=$(curl -fsS -H "Authorization: Bearer ${DEVAUDIT_API_KEY}" \
|
|
75
|
+
"${BASE_URL}/api/ci/releases/resolve?projectSlug=${ENCODED_SLUG}&versionPrefix=${ENCODED_VERSION}")
|
|
76
|
+
RELEASE_ID=$(jq -r '.latest.id // empty' <<<"$RESOLVED")
|
|
77
|
+
RESOLVED_VERSION=$(jq -r '.latest.version // empty' <<<"$RESOLVED")
|
|
78
|
+
[ -n "$RELEASE_ID" ] || { echo "Error: could not resolve ${VERSION}." >&2; exit 1; }
|
|
79
|
+
[ "$RESOLVED_VERSION" = "$VERSION" ] || { echo "Error: resolve returned ${RESOLVED_VERSION}, not exact ${VERSION}." >&2; exit 1; }
|
|
80
|
+
|
|
81
|
+
REASON=$(jq -r '.reason' "$MANIFEST_PATH")
|
|
82
|
+
PAYLOAD=$(jq -n --arg releaseMode standalone_housekeeping --arg standaloneReason "$REASON" \
|
|
83
|
+
'{releaseMode: $releaseMode, standaloneReason: $standaloneReason}')
|
|
84
|
+
RESPONSE_FILE=$(mktemp)
|
|
85
|
+
trap 'rm -f "$RESPONSE_FILE"' EXIT
|
|
86
|
+
HTTP_CODE=$(curl -sS -o "$RESPONSE_FILE" -w '%{http_code}' \
|
|
87
|
+
-X PATCH "${BASE_URL}/api/ci/releases/${RELEASE_ID}" \
|
|
88
|
+
-H "Authorization: Bearer ${DEVAUDIT_API_KEY}" \
|
|
89
|
+
-H 'Content-Type: application/json' --data "$PAYLOAD")
|
|
90
|
+
if [ "$HTTP_CODE" != "200" ]; then
|
|
91
|
+
echo "Error: standalone housekeeping promotion failed with HTTP ${HTTP_CODE}." >&2
|
|
92
|
+
sed 's/^/ /' "$RESPONSE_FILE" >&2
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
echo "Promoted ${VERSION} as standalone housekeeping (release ${RELEASE_ID})."
|
|
96
|
+
;;
|
|
97
|
+
*) usage ;;
|
|
98
|
+
esac
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
5
|
+
HELPER="$SCRIPT_DIR/standalone-housekeeping-release.sh"
|
|
6
|
+
WORK=$(mktemp -d)
|
|
7
|
+
trap 'rm -rf "$WORK"' EXIT
|
|
8
|
+
|
|
9
|
+
MANIFEST="$WORK/standalone.json"
|
|
10
|
+
cat > "$MANIFEST" <<'JSON'
|
|
11
|
+
{"schemaVersion":1,"version":"v2026.07.18","releaseMode":"standalone_housekeeping","reason":"Urgent production CI repair cannot wait for the next tracked requirement."}
|
|
12
|
+
JSON
|
|
13
|
+
|
|
14
|
+
bash "$HELPER" validate v2026.07.18 "$MANIFEST"
|
|
15
|
+
|
|
16
|
+
MOCK_BIN="$WORK/bin"
|
|
17
|
+
mkdir -p "$MOCK_BIN"
|
|
18
|
+
cat > "$MOCK_BIN/curl" <<'MOCK'
|
|
19
|
+
#!/usr/bin/env bash
|
|
20
|
+
set -euo pipefail
|
|
21
|
+
if [[ "$*" == *"/resolve?"* ]]; then
|
|
22
|
+
printf '{"latest":{"id":"rel_123","version":"v2026.07.18"}}'
|
|
23
|
+
exit 0
|
|
24
|
+
fi
|
|
25
|
+
output_file=""
|
|
26
|
+
for ((i=1; i <= $#; i++)); do
|
|
27
|
+
if [ "${!i}" = "-o" ]; then
|
|
28
|
+
next=$((i + 1))
|
|
29
|
+
output_file="${!next}"
|
|
30
|
+
fi
|
|
31
|
+
done
|
|
32
|
+
[ -z "$output_file" ] || printf '{"ok":true}' > "$output_file"
|
|
33
|
+
printf '200'
|
|
34
|
+
MOCK
|
|
35
|
+
chmod +x "$MOCK_BIN/curl"
|
|
36
|
+
|
|
37
|
+
PATH="$MOCK_BIN:$PATH" DEVAUDIT_BASE_URL=https://devaudit.example.test DEVAUDIT_API_KEY=mc_test \
|
|
38
|
+
bash "$HELPER" promote fixture-project v2026.07.18 "$MANIFEST"
|
|
39
|
+
|
|
40
|
+
if bash "$HELPER" validate REQ-999 "$MANIFEST" >/dev/null 2>&1; then
|
|
41
|
+
echo "Expected tracked version validation to fail" >&2
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
echo "standalone-housekeeping-release: PASS"
|
|
@@ -139,7 +139,7 @@ When designing each scenario, also pick the tier it'll live in. Three tiers map
|
|
|
139
139
|
| --- | --- | --- |
|
|
140
140
|
| **smoke** | `e2e/smoke/*.spec.ts` | Cross-cutting sanity that proves the app is up: login, basic nav, one canonical CRUD per main domain. Runs on every push to the integration branch. Keep small — total smoke wall-clock target is ~3–5 min. |
|
|
141
141
|
| **critical** | `e2e/critical/*.spec.ts` | Must-priority SRS item that breaks a headline flow if it regresses. Examples: payment authorisation, order completion, admin permission editing, RBAC enforcement on financial surfaces. Runs on PR-to-release-branch. Total critical wall-clock target ~10–15 min (includes smoke). |
|
|
142
|
-
| **regression** | `e2e/<area>/*.spec.ts` | Should/Could-priority SRS item, edge cases, less-load-bearing flows. Runs
|
|
142
|
+
| **regression** | `e2e/<area>/*.spec.ts` | Should/Could-priority SRS item, edge cases, less-load-bearing flows. Runs by dispatch and any consumer-configured post-merge or scheduled cadence. Total full pack can be 30+ min; that is the point of the tier. |
|
|
143
143
|
|
|
144
144
|
Decision tree, applied per scenario:
|
|
145
145
|
|
|
@@ -229,6 +229,12 @@ Before running the suite (Phase 6), verify that the evidence traceability wiring
|
|
|
229
229
|
|
|
230
230
|
Also verify the import is present: `import { tagTest } from './helpers/test-tags'` (or the correct relative path from the spec's location to `e2e/helpers/test-tags.ts`).
|
|
231
231
|
|
|
232
|
+
4. **Check release and cycle provenance.** Before handing the work back to `sdlc-implementer`, identify the tracked `REQ-XXX`, the source branch SHA, and the expected SDLC stage/cycle for the run. The CI evidence upload must retain those values so the portal can show the result in the correct numbered cycle for the release that produced it.
|
|
233
|
+
- A passing local run is not portal evidence by itself. Report it as local verification and let the configured CI workflow upload the resulting report and screenshots.
|
|
234
|
+
- For a bundled release, evidence remains attributed to its originating REQ and cycle. The absorbing release may reference that source release through bundle lineage, but must not relabel the source E2E run as newly produced by the absorbing REQ.
|
|
235
|
+
- Confirm the CI invocation has an unambiguous release context (`REQ-XXX` or the documented standalone-housekeeping declaration). A bare-date integration housekeeping run is historical CI only; it must not create an approval-ready E2E evidence set.
|
|
236
|
+
- If the project workflow cannot provide this context, halt and report a workflow-contract gap. Do not claim that screenshots or E2E results will appear correctly on the portal.
|
|
237
|
+
|
|
232
238
|
**If any check fails:**
|
|
233
239
|
|
|
234
240
|
Halt and report the gap to the user:
|
|
@@ -241,7 +247,7 @@ Halt and report the gap to the user:
|
|
|
241
247
|
|
|
242
248
|
Do **not** proceed to Phase 6 until all gaps are resolved. The user may choose to skip an AC (e.g. API-only, transport-only) — that's valid, but it must be an explicit decision recorded in the test-execution-summary, not an omission.
|
|
243
249
|
|
|
244
|
-
**Write the evidence-wiring sentinel (devaudit-installer#226).** After all Phase 5½ checks pass (all `@requirement`, `evidenceShot()`,
|
|
250
|
+
**Write the evidence-wiring sentinel (devaudit-installer#226).** After all Phase 5½ checks pass (all `@requirement`, `evidenceShot()`, `tagTest()`, and release/cycle provenance checks verified), write a `.e2e-evidence-wired` sentinel file in the repo root so the pre-push hook and `sdlc-implementer` Phase 2 step 5b can verify evidence wiring was validated:
|
|
245
251
|
|
|
246
252
|
```bash
|
|
247
253
|
echo "WIRED $(date -u +%Y-%m-%dT%H:%M:%SZ) REQ-XXX" > .e2e-evidence-wired
|
|
@@ -442,6 +448,7 @@ Wrap up with a summary the user can drop into the PR or ticket:
|
|
|
442
448
|
- Defects filed — count, with links.
|
|
443
449
|
- Requirements gap reports — count, with details (devaudit-installer#212 Gap 4). These are ACs classified as "impossible to test" or "missing AC" — returned to `sdlc-implementer` for the requirements gap flow, not filed as defects.
|
|
444
450
|
- Missed requirements — count, with links.
|
|
451
|
+
- **Release provenance** — originating `REQ-XXX`, local run result, expected CI workflow/run, and expected portal stage/cycle. For bundled work, state the source REQ explicitly and that the absorbing release will reference it through lineage rather than overwrite its attribution.
|
|
445
452
|
|
|
446
453
|
**Then feed the test-design record (devaudit#50).** The Stage 3 `test-execution-summary.md` (generated per `3-compile-evidence.md` Step 1a) carries a `## Test design` section at the top. Before Stage 3 finalises the file, populate that section with the design-time decisions this skill made, so the SDLC has a recorded trace that scope was *decided*, not implicit:
|
|
447
454
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Copy this into your consumer-owned .github/workflows/e2e-regression.yml
|
|
4
4
|
# to adopt the 3-tier model: smoke (every develop push, fast) / critical
|
|
5
|
-
# (PR
|
|
6
|
-
#
|
|
5
|
+
# (consumer-enabled release PR, ~10-15 min target) / regression (post-merge
|
|
6
|
+
# or scheduled only when the consumer opts in, plus dispatch).
|
|
7
7
|
#
|
|
8
8
|
# The framework does NOT sync this file automatically — your consumer
|
|
9
9
|
# owns its e2e-regression.yml. Apply the patterns below to your own
|
|
@@ -25,8 +25,6 @@ on:
|
|
|
25
25
|
branches: [main] # critical-tier gate before merge
|
|
26
26
|
push:
|
|
27
27
|
branches: [main] # full regression after merge; auto-issues on failure
|
|
28
|
-
schedule:
|
|
29
|
-
- cron: '0 2 * * *' # nightly full regression
|
|
30
28
|
workflow_dispatch:
|
|
31
29
|
inputs:
|
|
32
30
|
specs:
|
|
@@ -62,8 +60,8 @@ jobs:
|
|
|
62
60
|
run: npx playwright install --with-deps chromium
|
|
63
61
|
|
|
64
62
|
# Decide which Playwright project to run based on the trigger.
|
|
65
|
-
# PR-to-main uses critical with smoke fall-back;
|
|
66
|
-
#
|
|
63
|
+
# PR-to-main uses critical with smoke fall-back; a consumer-enabled
|
|
64
|
+
# post-merge push runs the full regression project; workflow_dispatch
|
|
67
65
|
# accepts an optional spec filter.
|
|
68
66
|
- name: Determine E2E project + spec selector
|
|
69
67
|
id: select
|
|
@@ -307,7 +307,7 @@ _Test fix surfaced by suite drift_
|
|
|
307
307
|
> - **Requirement:** none
|
|
308
308
|
> - **Risk:** LOW
|
|
309
309
|
> - **Path:** Lightweight (gates → PR review → merge)
|
|
310
|
-
> - **Gates/evidence:** quality-gates smoke (default CI Gate 4); no full regression on PR (
|
|
310
|
+
> - **Gates/evidence:** quality-gates smoke (default CI Gate 4); no full regression on PR (use `workflow_dispatch` while iterating; any post-merge or scheduled regression is consumer-configured)
|
|
311
311
|
> - **Your approvals:** PR review only
|
|
312
312
|
> - **Skipped:** RTM, evidence pack, UAT four-eyes, Production approval
|
|
313
313
|
|
|
@@ -341,8 +341,9 @@ Reached from Phase 0 for non-tracked change-types. The skill drives this end-to-
|
|
|
341
341
|
- **Post-merge-only CI (older generated workflows — `push: branches: [<integration>]` with no `pull_request:` trigger)** — say so explicitly in the LAST/NEXT sticky: _"no PR-time checks will fire; review + merge is the gate; CI runs post-merge on `$INTEGRATION_BRANCH`."_ Don't poll the PR for checks that won't arrive. The post-merge run (CI Pipeline + Compliance Evidence Upload on the integration branch) is the actual gate; address it via fix-forward if it fails.
|
|
342
342
|
|
|
343
343
|
Either way, never bypass a gate (no `--no-verify`, no `--admin` merge of a red required check); the only difference is **where** you wait for the gate to fire — before merge vs. after merge.
|
|
344
|
-
8. **Guide review
|
|
345
|
-
9. **
|
|
344
|
+
8. **Guide review -> merge.** A human still reviews the PR. Merge only after all required checks are terminal green on the current PR head SHA; queued, running, stale, cancelled, unexpectedly skipped, or failed checks are not green. There is no portal release approval, UAT four-eyes, Production gate, or standalone close-out on the normal lightweight path.
|
|
345
|
+
9. **Record the correct release meaning.** A housekeeping push produces at most a bare-date release (`vYYYY.MM.DD`) that is integration/history, not an active approval by default. It waits on `$INTEGRATION_BRANCH` until the next tracked release absorbs it through the required bundled-changes markdown/JSON manifest and portal lineage. A doc-only push attaches documents to the existing `REQ-XXX` release.
|
|
346
|
+
10. **Standalone exception.** Only when housekeeping cannot reasonably wait for the next tracked release may the skill prepare a standalone promotion. It must state `Standalone housekeeping promotion` and why in the release PR, add `compliance/standalone-housekeeping/STANDALONE-HOUSEKEEPING-vYYYY.MM.DD.json` with `schemaVersion: 1`, the exact derived bare-date version, `releaseMode: standalone_housekeeping`, and a specific reason. It must obtain terminal-green CI and PR review. The installed release-scope check validates the declaration before merge; post-deploy uploads it as release-ticket evidence and changes the portal row to standalone housekeeping. Use portal approval only if project policy explicitly opts in. If the installed workflow cannot implement that policy, halt and keep the change on the normal integration path.
|
|
346
347
|
|
|
347
348
|
### Phase 1 — Plan (SDLC stage 1)
|
|
348
349
|
|
|
@@ -662,8 +663,8 @@ Reached only on the **tracked** route from Phase 0 (the issue is already fetched
|
|
|
662
663
|
**When an external gate hangs or fails for unrelated reasons.** A required gate may fail for reasons outside the change's scope — flaky infra, an unrelated regression test that hangs at hour-plus runtime with no log activity, a known-failing suite. When this happens:
|
|
663
664
|
|
|
664
665
|
1. **Verify it's actually unrelated.** Read the failure (or the lack of one). If it's the change's fault, fix it; this section does not apply.
|
|
665
|
-
2. **Document the rationale on the PR.** A sticky comment naming: which gate, what the failure was, why it's unrelated to the change, what
|
|
666
|
-
3. **Cancel-and-admin-merge is allowed** when **all three** hold: (a) ≥3 other required gates are green, (b) the change has no scope-overlap with the failing gate (e.g. service-layer fix vs hung UI e2e, or an `E2E: N/A by scope` test-plan), and (c) a fallback verification exists (
|
|
666
|
+
2. **Document the rationale on the PR.** A sticky comment naming: which gate, what the failure was, why it's unrelated to the change, and what concrete fallback verification is available (for example, a consumer-configured regression run or post-deploy verification).
|
|
667
|
+
3. **Cancel-and-admin-merge is allowed** when **all three** hold: (a) ≥3 other required gates are green, (b) the change has no scope-overlap with the failing gate (e.g. service-layer fix vs hung UI e2e, or an `E2E: N/A by scope` test-plan), and (c) a concrete fallback verification exists (a consumer-configured regression run, manual dispatch, or post-deploy smoke). If any of the three fail, hold the merge and surface the blocker to the operator.
|
|
667
668
|
4. **Record the decision in the release ticket.** The release ticket's `## Verification` section must mention the cancelled gate by run-ID and the fallback that justifies bypassing it. Auditors look here first.
|
|
668
669
|
|
|
669
670
|
**When the cancel-and-admin-merge conditions are NOT met.** If only one or two of the three conditions hold, the skill cannot bypass the gate. Escalation path:
|
|
@@ -699,16 +700,11 @@ Invoked separately by the user after UAT activity on the portal. Trigger: "resum
|
|
|
699
700
|
- If `released` (Option B): PATCH directly to `released` — `PATCH /releases/<version>` with `{"status": "released"}`.
|
|
700
701
|
- If `prod_review` (Option A, default): after `post-deploy-prod.yml` completes, the release is at `prod_review`. Update the sticky to "Phase 5 — production deployed; awaiting prod approval on portal" and halt. The operator clicks "Approve Production" (`prod_review` → `prod_approved`) then "Mark as Released" (`prod_approved` → `released`) in the portal. On next `resume REQ-XXX`, the skill reads the portal state — if `released`, finalise (close issue, update sticky to terminal). If `prod_approved`, prompt the operator to click "Mark as Released". If still `prod_review`, report "awaiting production approval" and stop.
|
|
701
702
|
- Comment on the issue: "Released. Production smoke evidence: <link>." (only after release status is `released`)
|
|
702
|
-
- **Phase 5 close-out — mandatory
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
5. **Push the close-out commit** to `$INTEGRATION_BRANCH`.
|
|
708
|
-
|
|
709
|
-
These steps are mandatory — the native agent must not treat "PR merged" or "release marked Released" as completion without performing the close-out. Without moving the release ticket to `approved-releases/`, CI continues uploading evidence for the REQ on every subsequent release, polluting the portal's audit trail.
|
|
710
|
-
- **Update SDLC status sticky** to the terminal state: `bash scripts/update-sdlc-status.sh "$ISSUE_NUM" "Phase 5 complete — release marked Released; production smoke evidence uploaded; close-out committed (RTM → APPROVED - DEPLOYED, ticket → approved-releases/)" "Done — close issue + retire feature branch (sdlc-implementer halts)"`.
|
|
711
|
-
- Close the issue.
|
|
703
|
+
- **Phase 5 close-out — mandatory automated reconciliation.** After the portal release is `released`, wait for the portal's `repository_dispatch('release-closed')` event to open `chore/close-out-REQ-XXX` against `$INTEGRATION_BRANCH`. Verify the PR updates the RTM, moves the ticket to `approved-releases/`, and moves manifest-listed predecessors to `superseded-releases/`. Review and merge the close-out PR only after its required checks are terminal green on its current head SHA. If no PR appears, manually dispatch the Release Close-out workflow. Use `scripts/close-out-release.sh` locally only for documented recovery/catch-up; never make a normal direct close-out commit to a protected branch.
|
|
704
|
+
|
|
705
|
+
These steps are mandatory — "PR merged" or "release marked Released" is not complete until the automated close-out PR has merged or a documented fallback reconciliation is complete. Without it, CI can keep uploading evidence against a completed REQ and pollute the audit trail.
|
|
706
|
+
- **Update SDLC status sticky** to the terminal state: `bash scripts/update-sdlc-status.sh "$ISSUE_NUM" "Phase 5 complete — release marked Released; production smoke evidence uploaded; automated close-out reconciled RTM and release ticket" "Done — close issue + retire feature branch (sdlc-implementer halts)"`.
|
|
707
|
+
- Close the issue only after close-out reconciliation completes.
|
|
712
708
|
- If production smoke fails: do NOT mark as Released. **Delegate incident filing to `governance-doc-author` (devaudit-installer#210 §6c)** — invoke `Skill(name: "governance-doc-author", args: "Production smoke failure for REQ-XXX. File an incident issue with the `incident` label + `### Framework attribution` section (ISO29119.3.5.4 + SOC2.CC7.2), severity `blocker`. Include the production URL, git SHA, testCycleId (CI run ID), and smoke results in the issue body.")`. Page the on-call per the project's incident playbook, follow the rollback plan from the implementation plan. If the rollback also fails: update the sticky to "Phase 5 CRITICAL — production smoke failed AND rollback failed. Production is in a broken state. Operator action — page on-call immediately, engage hosting platform support, declare incident per the project's incident playbook. This is beyond the skill's scope." Do NOT attempt further automated remediation. **Update the sticky** to reflect the incident state: `… "Phase 5 BLOCKED — production smoke failed; INCIDENT issue #N filed" "Operator action — read INCIDENT #N + execute rollback per plan"`.
|
|
713
709
|
|
|
714
710
|
- **Changes requested** → run change-request loop:
|
|
@@ -769,7 +765,7 @@ The skill re-reads state from the filesystem and continues from where it left of
|
|
|
769
765
|
|
|
770
766
|
The native agent must NOT continue to the next phase (Phase 3 → Phase 4, Phase 2 → Phase 3) without re-invoking the skill. The only exception is the skill's own auto-continue steps (Phase 2 step 11) where the skill explicitly says it will continue to the next phase in the same turn.
|
|
771
767
|
|
|
772
|
-
**PR merged to main
|
|
768
|
+
**PR merged to main is not done.** After the release PR is merged, Phase 5 waits for deploy/host verification, portal `released`, and the automated close-out PR back to the integration branch. The merge is not the end of the workflow.
|
|
773
769
|
|
|
774
770
|
### Commit-history hygiene recovery (devaudit-installer#315)
|
|
775
771
|
|
|
@@ -137,20 +137,20 @@ Key files to expect:
|
|
|
137
137
|
|
|
138
138
|
### 5. Hand off to the sdlc-implementer skill
|
|
139
139
|
|
|
140
|
-
The changes are staged in the working tree. The remaining steps — invoking the SDLC engine for the sentinel, running local gates, creating a feature branch, committing, pushing, opening a PR, monitoring CI, and
|
|
140
|
+
The changes are staged in the working tree. The remaining steps — invoking the SDLC engine for the sentinel, running local gates, creating a feature branch, committing, pushing, opening a PR, monitoring CI, and recording the correct housekeeping release meaning — are all owned by the **sdlc-implementer** skill that was synced into `.claude/skills/` by the install/update.
|
|
141
141
|
|
|
142
142
|
Invoke the sdlc-implementer skill and tell it:
|
|
143
143
|
|
|
144
|
-
> **Housekeeping change.** The working tree has uncommitted changes from `devaudit install` (or `devaudit update`). Commit type is `chore:`, no `REQ-XXX`. Use the SDLC lightweight path: invoke the SDLC engine for the sentinel, run local gates, create a `chore/sync-devaudit-sdlc-{version}` branch, commit, push, open a PR targeting `develop`,
|
|
144
|
+
> **Housekeeping change.** The working tree has uncommitted changes from `devaudit install` (or `devaudit update`). Commit type is `chore:`, no `REQ-XXX`. Use the SDLC lightweight path: invoke the SDLC engine for the sentinel, run local gates, create a `chore/sync-devaudit-sdlc-{version}` branch, commit, push, open a PR targeting `develop`, wait for terminal-green checks on the current PR SHA, then guide merge. This is normal integration housekeeping: it has PR review only, creates no tracked approval release, and is absorbed into the next tracked REQ through bundled-change lineage. A standalone housekeeping release is allowed only when the `sdlc-implementer` standalone-exception contract is explicitly satisfied.
|
|
145
145
|
|
|
146
146
|
The skill will:
|
|
147
147
|
1. Invoke `node SDLC/bin/devaudit-sdlc.js --phase=issue --view` to write the `.sdlc-implementer-invoked` sentinel
|
|
148
148
|
2. Run local gates (lint, tsc, test)
|
|
149
149
|
3. Create a `chore/` branch, commit, and push
|
|
150
150
|
4. Open a PR targeting `develop`
|
|
151
|
-
5. Monitor CI checks
|
|
151
|
+
5. Monitor CI checks and wait for terminal green on the current PR SHA
|
|
152
152
|
6. Guide review → merge
|
|
153
|
-
7.
|
|
153
|
+
7. Record the merge as integration history to be bundled into the next tracked REQ, unless the explicit standalone-housekeeping exception was used
|
|
154
154
|
|
|
155
155
|
**Do not** manually run these steps yourself — the skill owns the SDLC ceremony and stays in sync with the framework's evolution. If the skill is not available (e.g. the AI agent doesn't support skills), fall back to the manual steps documented in `SDLC/0-project-setup.md` and the sdlc-implementer skill definition at `.claude/skills/sdlc-implementer/SKILL.md`.
|
|
156
156
|
|
|
@@ -336,6 +336,26 @@ jobs:
|
|
|
336
336
|
--environment uat --category planning \
|
|
337
337
|
--git-sha ${{ github.sha }} --branch ${{ github.ref_name }} || true
|
|
338
338
|
|
|
339
|
+
- name: Upload standalone housekeeping declaration
|
|
340
|
+
if: env.DEVAUDIT_BASE_URL != '' && steps.version.outputs.version != 'skip'
|
|
341
|
+
run: |
|
|
342
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
343
|
+
if ! [[ "$VERSION" =~ ^v[0-9]{4}\.[0-9]{2}\.[0-9]{2}(\.[0-9]+)?$ ]]; then
|
|
344
|
+
exit 0
|
|
345
|
+
fi
|
|
346
|
+
DECLARATION="compliance/standalone-housekeeping/STANDALONE-HOUSEKEEPING-${VERSION}.json"
|
|
347
|
+
if [ ! -f "$DECLARATION" ]; then
|
|
348
|
+
echo "${VERSION} is integration housekeeping; no standalone declaration uploaded."
|
|
349
|
+
exit 0
|
|
350
|
+
fi
|
|
351
|
+
chmod +x scripts/standalone-housekeeping-release.sh scripts/upload-evidence.sh 2>/dev/null || true
|
|
352
|
+
bash scripts/standalone-housekeeping-release.sh validate "$VERSION" "$DECLARATION"
|
|
353
|
+
bash scripts/upload-evidence.sh \
|
|
354
|
+
{{PROJECT_SLUG}} "$VERSION" release_ticket "$DECLARATION" \
|
|
355
|
+
--release "$VERSION" --create-release-if-missing \
|
|
356
|
+
--environment uat --category release_artifact --sdlc-stage 2 \
|
|
357
|
+
--git-sha ${{ github.sha }} --branch ${{ github.ref_name }}
|
|
358
|
+
|
|
339
359
|
- name: Generate and upload bundled changes (REQ releases only)
|
|
340
360
|
if: env.DEVAUDIT_BASE_URL != '' && steps.version.outputs.version != 'skip'
|
|
341
361
|
run: |
|
|
@@ -49,26 +49,11 @@ jobs:
|
|
|
49
49
|
# double-upload every compliance doc.
|
|
50
50
|
if: github.event_name != 'workflow_run'
|
|
51
51
|
runs-on: {{RUNNER}}
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
# 2. dispatches `ci.yml` on develop after that stub PR merges, so
|
|
56
|
-
# compliance-only housekeeping releases still get the gate evidence
|
|
57
|
-
# the portal approval path currently requires (#361)
|
|
58
|
-
#
|
|
59
|
-
# Without these the github-actions[bot] token gets HTTP 403 on the push,
|
|
60
|
-
# PR create, or workflow dispatch and the housekeeping path leaves a red
|
|
61
|
-
# badge or an unapprovable release behind.
|
|
62
|
-
#
|
|
63
|
-
# `DEVAUDIT_USER_TOKEN` is no longer consulted by this workflow (the
|
|
64
|
-
# auto-stub step now uses `github.token` directly — see the env block
|
|
65
|
-
# on that step). The permissions below grant everything `gh pr create`
|
|
66
|
-
# needs; preferring a (potentially stale) PAT was the cause of the
|
|
67
|
-
# 2026-06-07 401 chain on this issue.
|
|
52
|
+
# #409: this workflow only uploads evidence. Normal housekeeping is
|
|
53
|
+
# integration history, so it must not create PRs, dispatch gates, or
|
|
54
|
+
# receive write-scoped GitHub credentials.
|
|
68
55
|
permissions:
|
|
69
|
-
|
|
70
|
-
contents: write # push the auto-PR branch
|
|
71
|
-
pull-requests: write # gh pr create
|
|
56
|
+
contents: read
|
|
72
57
|
env:
|
|
73
58
|
DEVAUDIT_BASE_URL_VAR: ${{ vars.DEVAUDIT_BASE_URL }}
|
|
74
59
|
DEVAUDIT_API_KEY: ${{ secrets.DEVAUDIT_API_KEY }}
|
|
@@ -141,28 +126,13 @@ jobs:
|
|
|
141
126
|
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
|
142
127
|
echo "Release version: ${VERSION}"
|
|
143
128
|
|
|
144
|
-
#
|
|
145
|
-
#
|
|
146
|
-
#
|
|
147
|
-
#
|
|
148
|
-
#
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
# open a PR that the operator reviews + signs off + merges. Once
|
|
152
|
-
# merged, the next compliance-evidence.yml run uploads them as
|
|
153
|
-
# evidence and the matrix flips both items to ✓.
|
|
154
|
-
#
|
|
155
|
-
# devaudit#284 — release reconciliation merges (from close-out-release.yml)
|
|
156
|
-
# carry a `Release-Closeout: REQ-XXX` marker in the commit body.
|
|
157
|
-
# derive-release-version.sh detects this marker and emits an empty
|
|
158
|
-
# version, which this workflow converts to the explicit `skip` sentinel.
|
|
159
|
-
# Reconciliation pushes therefore never create housekeeping stubs and
|
|
160
|
-
# never attach fresh evidence to an already released tracked record.
|
|
161
|
-
#
|
|
162
|
-
# Mirrors the `incident-export.yml` pattern: auto-PR, operator fills
|
|
163
|
-
# in sign-off, merge to land.
|
|
164
|
-
- name: Auto-generate housekeeping stubs (if needed)
|
|
165
|
-
if: steps.resolve.outputs.skip != 'true' && steps.version.outputs.version != 'skip'
|
|
129
|
+
# #409: normal bare-date changes are integration CI history, not portal
|
|
130
|
+
# releases awaiting approval. The old auto-generated ticket/security
|
|
131
|
+
# summary path is deliberately disabled. An independently promoted
|
|
132
|
+
# exception must carry the reviewed standalone declaration validated by
|
|
133
|
+
# check-release-pr-scope.sh and post-deploy-prod.yml.
|
|
134
|
+
- name: Legacy housekeeping approval path (disabled)
|
|
135
|
+
if: ${{ false }}
|
|
166
136
|
env:
|
|
167
137
|
# Use the workflow's GITHUB_TOKEN directly. The `permissions:`
|
|
168
138
|
# block on the job grants `contents: write` + `pull-requests:
|
|
@@ -241,8 +211,8 @@ jobs:
|
|
|
241
211
|
echo "PR #${EXISTING} already open for ${VERSION} — branch updated in place."
|
|
242
212
|
fi
|
|
243
213
|
|
|
244
|
-
- name:
|
|
245
|
-
if:
|
|
214
|
+
- name: Legacy housekeeping gate dispatch (disabled)
|
|
215
|
+
if: ${{ false }}
|
|
246
216
|
env:
|
|
247
217
|
GH_TOKEN: ${{ github.token }}
|
|
248
218
|
VERSION: ${{ steps.version.outputs.version }}
|