From d05a5ec5bf623da81559354458e9d28b736bb153 Mon Sep 17 00:00:00 2001 From: "Molecule AI Dev Engineer B (MiniMax)" Date: Thu, 4 Jun 2026 01:23:56 +0000 Subject: [PATCH 1/3] feat(ci): manifest-entry-existence check at PR-review time (closes #2185) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds .gitea/workflows/manifest-entry-existence-check.yml. Triggers only on PRs that modify manifest.json. For each entry, GETs the Gitea repo existence endpoint. Fails the PR with a per-entry ::error:: annotation naming the broken line, so the author can fix the manifest before it reaches main. Bug class this prevents: latent 404 in manifest.json only surfaces on the next push to main (the publish-workspace-server-image workflow's Pre-clone manifest deps step). Until #2183 was investigated, both free-beats-all and medo-smoke sat in main since 2026-05-08 / earlier without surfacing. This workflow moves the existence check to PR-review time. NOT a required status check today. Open design question: should the CTO make this required via branch-protection admin config? See #2185 for the tradeoff discussion. Sanity-tested locally (bash, simulating the Gitea Actions environment with the same curl + jq logic): - post-fix manifest (30 entries): 0 missing, exits 0 ✓ - pre-fix manifest (32 entries, with free-beats-all + medo-smoke): 2 missing (free-beats-all, medo-smoke), exits 1 ✓ Co-Authored-By: Claude Opus 4.7 --- .../manifest-entry-existence-check.yml | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 .gitea/workflows/manifest-entry-existence-check.yml diff --git a/.gitea/workflows/manifest-entry-existence-check.yml b/.gitea/workflows/manifest-entry-existence-check.yml new file mode 100644 index 000000000..3f3622de8 --- /dev/null +++ b/.gitea/workflows/manifest-entry-existence-check.yml @@ -0,0 +1,79 @@ +name: manifest-entry-existence-check + +# Gitea Actions port of the manual "GET /api/v1/repos/ for each +# manifest entry" audit that the engineer-b identity ran on 2026-06-04 to +# fix #2183 (main-red on 0b91c18031 — publish-workspace-server-image +# failed at the Pre-clone manifest deps step because manifest.json +# referenced 2 non-existent repos: free-beats-all + medo-smoke). +# +# The bug class is "latent 404 in manifest.json only surfaces on the +# next push to main, which is too late". This workflow moves the check +# to PR-review time so the bad entry never reaches main. +# +# Trigger: only on PRs that modify manifest.json. The `paths:` filter +# keeps the workflow out of the PR-CI test matrix for every other PR. +# +# Auth: anonymous Gitea API. Per the 2026-05-08 OSS-surface contract +# (commit 15935143c8d2 _comment), every entry in manifest.json is +# public on git.moleculesai.app. No new secrets required. +# +# Failure surface: each broken entry is named in an ::error:: annotation +# so the PR author sees exactly which line to fix. Mirrors the +# `Pre-clone manifest deps` step's per-entry error format in +# publish-workspace-server-image.yml. +# +# NOT a required status check today. Open design question tracked in +# #2185 — making it required is a CTO ruling (admin-only branch-protection +# config). Watchdog + post-merge RCA is the current backstop. + +on: + pull_request: + paths: + - manifest.json + +permissions: + contents: read + +jobs: + check-entries: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Verify each manifest entry resolves on Gitea + run: | + set -euo pipefail + # Strip JSON5 // comments first to match the publish workflow's + # `Pre-clone manifest deps` parsing path — Integration Tester + # appends `// Triggered by ...` which breaks `jq` otherwise. + sed '/^[[:space:]]*\/\//d' manifest.json > /tmp/manifest.json + # Anonymous API is enough: per the 2026-05-08 OSS-surface contract + # (15935143c8d2 _comment), every entry is public on Gitea. + count=$(jq -r '(.plugins + .workspace_templates + .org_templates) | length' /tmp/manifest.json) + echo "Checking $count manifest entries against Gitea..." + missing=() + for i in $(seq 0 $((count-1))); do + name=$(jq -r "(.plugins + .workspace_templates + .org_templates)[$i].name" /tmp/manifest.json) + repo=$(jq -r "(.plugins + .workspace_templates + .org_templates)[$i].repo" /tmp/manifest.json) + for attempt in 1 2 3; do + http_code=$(curl -s -o /dev/null -w "%{http_code}" "https://git.moleculesai.app/api/v1/repos/${repo}") + if [ "$http_code" = "200" ]; then + echo " OK $name -> $repo" + break + elif [ "$http_code" = "404" ]; then + echo "::error::manifest entry '$name' points at '$repo' which does not exist on Gitea (404)" + missing+=("$name:$repo") + break + else + echo " attempt $attempt: $name -> $repo returned HTTP $http_code, retrying in $((attempt * 2))s" + sleep $((attempt * 2)) + fi + done + done + if [ "${#missing[@]}" -gt 0 ]; then + echo "::error::${#missing[@]} manifest entries are broken:" + printf ' - %s\n' "${missing[@]}" + exit 1 + fi + echo "All $count manifest entries resolve on Gitea." -- 2.52.0 From 95175ffaa85de517539facfe54b6720a50689f22 Mon Sep 17 00:00:00 2001 From: "Molecule AI Dev Engineer B (MiniMax)" Date: Thu, 4 Jun 2026 01:45:04 +0000 Subject: [PATCH 2/3] fix(ci): add bp-required: pending #2185 directive to manifest-entry-existence-check The lint-required-context-exists-in-bp job flagged this workflow as emitting a new commit-status context 'manifest-entry-existence-check / check-entries (pull_request)' without an adjacent BP directive. Per the workflow's own convention: 'bp-required: pending #NNN' is the correct shape when the design question of whether to make the check required is open. This matches what the PR body + #2185 say: the check is NOT required today, the asymmetry is acknowledged, and the CTO ruling is tracked in #2185. Do NOT flip to 'bp-required: yes' until #2185 resolves and BP lists the context in the required-checks list. Reviewer-flagged-by: molecule-code-reviewer (comment 56928 on PR #2186) Refs: #2185 --- .gitea/workflows/manifest-entry-existence-check.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitea/workflows/manifest-entry-existence-check.yml b/.gitea/workflows/manifest-entry-existence-check.yml index 3f3622de8..a05049464 100644 --- a/.gitea/workflows/manifest-entry-existence-check.yml +++ b/.gitea/workflows/manifest-entry-existence-check.yml @@ -35,6 +35,11 @@ permissions: contents: read jobs: + # bp-required: pending #2185 — design question is whether this + # should be a hard required check. The PR-time emit is asymmetric + # until the CTO rules. Tracking: #2185. Do NOT flip to + # `bp-required: yes` until #2185 is resolved and BP lists + # `manifest-entry-existence-check / check-entries (pull_request)`. check-entries: runs-on: ubuntu-latest steps: -- 2.52.0 From cb20abdd6f8eb5d83c248e7baba0c2c6baec0020 Mon Sep 17 00:00:00 2001 From: "Molecule AI Dev Engineer A (Kimi)" Date: Thu, 4 Jun 2026 05:18:47 +0000 Subject: [PATCH 3/3] fix(ci): move bp-directive into lint window for manifest-entry-existence-check The # bp-required: pending #2185 directive was 5 lines above the job key, outside the _DIRECTIVE_WINDOW=3 scan range of lint_required_context_exists_in_bp.py. The lint would therefore fail to detect the directive and flag the new emission as a violation. Move the directive to the last comment line before check-entries: so it sits within the 3-line window and is picked up correctly. Co-Authored-By: Claude Opus 4.7 --- .gitea/workflows/manifest-entry-existence-check.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/manifest-entry-existence-check.yml b/.gitea/workflows/manifest-entry-existence-check.yml index a05049464..928ac83d3 100644 --- a/.gitea/workflows/manifest-entry-existence-check.yml +++ b/.gitea/workflows/manifest-entry-existence-check.yml @@ -35,11 +35,9 @@ permissions: contents: read jobs: - # bp-required: pending #2185 — design question is whether this - # should be a hard required check. The PR-time emit is asymmetric - # until the CTO rules. Tracking: #2185. Do NOT flip to - # `bp-required: yes` until #2185 is resolved and BP lists - # `manifest-entry-existence-check / check-entries (pull_request)`. + # Design question: whether this should be a hard required check. + # The PR-time emit is asymmetric until the CTO rules. Tracking: #2185. + # bp-required: pending #2185 — do NOT flip to yes until BP lists the context. check-entries: runs-on: ubuntu-latest steps: -- 2.52.0