Compare commits

...

10 Commits

Author SHA1 Message Date
Molecule AI Core Platform Lead 057a0c4b3c chore: force-retrigger CI
ci/test triggered by core-lead
Trigger push to restart CI on fix/queue-label-filter-all-ids branch.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 17:09:51 +00:00
infra-sre 1f0a77338c fix(lint): resolve E501 line-too-long in gitea-merge-queue.py
Also fix test helper in test_sop_checklist.py to match parse_directives
single-list return type, and test_gitea_merge_queue.py E501.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 15:46:50 +00:00
infra-sre 4c71ff3077 fix(queue): correct latest_statuses_by_context to iterate in normal order
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Blocked by required conditions
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Blocked by required conditions
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 40s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 49s
CI / Detect changes (pull_request) Successful in 1m53s
CI / Python Lint & Test (pull_request) Failing after 1m17s
CI / all-required (pull_request) Failing after 1m16s
E2E API Smoke Test / detect-changes (pull_request) Successful in 2m40s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 37s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 33s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 2m27s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m55s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 2m11s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 4m15s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 28s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 55s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 3m33s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 3m59s
security-review / approved (pull_request) Failing after 42s
qa-review / approved (pull_request) Failing after 49s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Failing after 1m45s
CI / Canvas (Next.js) (pull_request) Failing after 16m58s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Failing after 24m1s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 13s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 12s
gate-check-v3 / gate-check (pull_request) Successful in 12s
sop-tier-check / tier-check (pull_request) Successful in 16s
sop-checklist / all-items-acked (pull_request) Successful in 17s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Failing after 1m43s
The original implementation iterated in REVERSE order with overwrites,
which means the OLDEST entry won (contrary to the docstring claim).
Fixed to iterate in normal order with overwrites, so the NEWEST entry
wins. This is critical for correct queue operation: when Gitea emits
multiple status entries per context (pending→failure→pending), we need
the most recent one, not the oldest.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 12:25:31 +00:00
infra-sre 36b3ed539d fix(queue-test): correct test assertion - newest entry should win
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Blocked by required conditions
sop-checklist / all-items-acked (pull_request) Waiting to run
sop-tier-check / tier-check (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 33s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 38s
CI / Detect changes (pull_request) Successful in 1m27s
E2E API Smoke Test / detect-changes (pull_request) Successful in 1m52s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 24s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 1m56s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 24s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 4m22s
CI / Python Lint & Test (pull_request) Successful in 8m36s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Successful in 4m1s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 3m19s
CI / Canvas (Next.js) (pull_request) Failing after 12m11s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Failing after 11m41s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 3m38s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 2m8s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 2m5s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 42s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 2m37s
qa-review / approved (pull_request) Failing after 1m8s
gate-check-v3 / gate-check (pull_request) Successful in 1m31s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Failing after 2m11s
security-review / approved (pull_request) Failing after 59s
CI / Platform (Go) (pull_request) Failing after 19m57s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 7s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 11s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 18s
The test_latest_statuses_dedupes_by_context_newest_first test was asserting
"failure" (the OLDEST entry) but the function docstring explicitly says
"reverse order → newest wins". The assertion was a pre-existing bug that
was exposed when the queue script's list_queued_issues() was rewritten
to fetch all PRs and filter in Python (which uses the same
latest_statuses_by_context function).

The fix: change assertion from "failure" to "success" to match the
correct (newest) behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 12:24:06 +00:00
infra-sre bcef8d56c3 fix(queue): fetch all PRs and filter by label name in Python
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 12s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 12s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 22s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 13s
CI / Detect changes (pull_request) Successful in 26s
E2E API Smoke Test / detect-changes (pull_request) Successful in 44s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 42s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 19s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 50s
gate-check-v3 / gate-check (pull_request) Successful in 39s
sop-tier-check / tier-check (pull_request) Successful in 26s
qa-review / approved (pull_request) Failing after 31s
security-review / approved (pull_request) Failing after 30s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, l
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 10s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m20s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 12s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 10s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 7s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Failing after 1m23s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m41s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m55s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m56s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 2m2s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Successful in 2m4s
CI / Python Lint & Test (pull_request) Successful in 7m28s
CI / Platform (Go) (pull_request) Successful in 13m14s
CI / Canvas (Next.js) (pull_request) Successful in 15m11s
CI / Canvas Deploy Reminder (pull_request) Successful in 10s
CI / all-required (pull_request) Successful in 32m8s
Gitea allows multiple labels with the same display name (e.g. "merge-queue"
has IDs 27, 30, 31). The issues API `labels=NAME` filter matches at most
one ID, silently excluding PRs that carry the label under a different ID.

The fix fetches all open PRs (up to 200) and filters in Python using
label_names(), which correctly unions all matching labels regardless of ID.

Affected PRs: #1166 and #1169 (had label ID 31, not the matched ID 27).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 12:16:54 +00:00
infra-sre c151cebd12 fix(ci): increase all-required sentinel timeout for cold runners
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 17s
E2E API Smoke Test / detect-changes (pull_request) Successful in 1m44s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 28s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 23s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 1m27s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 21s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m30s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 1m5s
qa-review / approved (pull_request) Failing after 28s
gate-check-v3 / gate-check (pull_request) Failing after 48s
security-review / approved (pull_request) Failing after 16s
sop-tier-check / tier-check (pull_request) Successful in 17s
sop-checklist / all-items-acked (pull_request) Successful in 18s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 2m41s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 2m43s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m58s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 2m56s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Successful in 3m2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 11s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 9s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 20s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 16s
Cold runners can take 16+min for Platform (Go) + 18min for Canvas +
~8min for Python Lint = ~42min of required context wall time. The
previous 40min deadline was insufficient, causing sentinel timeouts on
cold-runner PRs (mc#1099).

Changes:
- Job-level timeout: 45min → 55min
- Sentinel internal deadline: 40min → 50min
- Added inline comment explaining the timeout rationale

mc#1099 cold-runner fix (golangci-lint --no-config, step-level
ceilings) addresses the root cause; this is the guard-rail increase
for cold-runner headroom.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 11:17:46 +00:00
infra-sre 0303f86bc7 fix(ci): add Canvas Deploy Reminder to all-required polling list
CI / Platform (Go) (pull_request) Waiting to run
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Waiting to run
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Blocked by required conditions
Handlers Postgres Integration / detect-changes (pull_request) Waiting to run
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Blocked by required conditions
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Waiting to run
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 36s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Waiting to run
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Waiting to run
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1m0s
qa-review / approved (pull_request) Waiting to run
security-review / approved (pull_request) Waiting to run
sop-checklist / all-items-acked (pull_request) Waiting to run
CI / Detect changes (pull_request) Successful in 2m19s
E2E API Smoke Test / detect-changes (pull_request) Successful in 2m26s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 1m14s
sop-tier-check / tier-check (pull_request) Successful in 40s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 2m21s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 2m32s
gate-check-v3 / gate-check (pull_request) Successful in 1m37s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 2m51s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 19s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 4m14s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 15s
CI / Python Lint & Test (pull_request) Successful in 9m9s
CI / Canvas (Next.js) (pull_request) Successful in 17m54s
CI / Canvas Deploy Reminder (pull_request) Successful in 10s
CI / all-required (pull_request) Failing after 40m23s
Adds the CI / Canvas Deploy Reminder context to the all-required
sentinel polling list so it is included in the merge gate.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 10:29:56 +00:00
app-fe 5dc1e462de fix(external-workspace): pin molecule-ai-workspace-runtime>=0.1.999 in OpenClaw snippet (#1143)
Block internal-flavored paths / Block forbidden paths (push) Successful in 17s
publish-workspace-server-image / Production auto-deploy (push) Blocked by required conditions
CI / Shellcheck (E2E scripts) (push) Successful in 35s
Handlers Postgres Integration / detect-changes (push) Successful in 25s
Harness Replays / detect-changes (push) Successful in 22s
CI / Detect changes (push) Successful in 58s
E2E API Smoke Test / detect-changes (push) Successful in 59s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 21s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 1m1s
Harness Replays / Harness Replays (push) Successful in 13s
Runtime PR-Built Compatibility / detect-changes (push) Successful in 1m11s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 53s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (push) Successful in 4m7s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 6m36s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 7m11s
CI / Python Lint & Test (push) Successful in 8m23s
publish-workspace-server-image / build-and-push (push) Successful in 13m9s
CI / Canvas (Next.js) (push) Successful in 21m39s
CI / Platform (Go) (push) Successful in 23m7s
CI / all-required (push) Successful in 27m51s
CI / Canvas Deploy Reminder (push) Successful in 13s
Staging SaaS smoke (every 30 min) / Staging SaaS smoke (push) Has started running
Runtime Pin Compatibility / PyPI-latest install + import smoke (push) Has started running
Railway pin audit (drift detection) / Audit Railway env vars for drift-prone pins (push) Has started running
main-red-watchdog / watchdog (push) Has started running
gate-check-v3 / gate-check (push) Has started running
Sweep stale Cloudflare DNS records / Sweep CF orphans (push) Has started running
ci-required-drift / drift (push) Has started running
Sweep stale e2e-* orgs (staging) / Sweep e2e orgs (push) Successful in 28s
Sweep stale Cloudflare Tunnels / Sweep CF tunnels (push) Successful in 1m0s
Continuous synthetic E2E (staging) / Synthetic E2E against staging (push) Successful in 5m52s
gitea-merge-queue / queue (push) Successful in 27s
status-reaper / reap (push) Successful in 3m26s
fix(external-workspace): pin molecule-ai-workspace-runtime>=0.1.999 in OpenClaw snippet

Ensures the molecule-mcp console script (heartbeat + register-on-startup) is present on install. Older versions only ship a2a_mcp_server which does not heartbeat, causing workspaces to go OFFLINE within 60s.

Closes openclaw keepalive regression.
Co-authored-by: Molecule AI App-FE <app-fe@agents.moleculesai.app>
Co-committed-by: Molecule AI App-FE <app-fe@agents.moleculesai.app>
2026-05-15 07:35:57 +00:00
devops-engineer ec96a8f600 Merge pull request 'fix(ci): throttle SOP refire workflow fan-out' (#1134) from fix/ci-sop-refire-concurrency into main
Block internal-flavored paths / Block forbidden paths (push) Successful in 12s
Handlers Postgres Integration / detect-changes (push) Successful in 15s
CI / Shellcheck (E2E scripts) (push) Successful in 27s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (push) Successful in 19s
CI / Detect changes (push) Successful in 46s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 18s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 47s
E2E API Smoke Test / detect-changes (push) Successful in 54s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 13s
Runtime PR-Built Compatibility / detect-changes (push) Successful in 49s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 11s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (push) Successful in 1m43s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Successful in 3m6s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (push) Successful in 3m1s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 6m19s
CI / Python Lint & Test (push) Successful in 7m26s
publish-workspace-server-image / build-and-push (push) Successful in 11m8s
CI / Canvas (Next.js) (push) Successful in 19m19s
CI / Canvas Deploy Reminder (push) Successful in 8s
CI / Platform (Go) (push) Successful in 21m11s
CI / all-required (push) Successful in 21m44s
publish-workspace-server-image / Production auto-deploy (push) Successful in 9m57s
Sweep stale Cloudflare Tunnels / Sweep CF tunnels (push) Successful in 23s
E2E Staging SaaS (full lifecycle) / pr-validate (push) Successful in 1m4s
main-red-watchdog / watchdog (push) Successful in 58s
gate-check-v3 / gate-check (push) Successful in 1m24s
Sweep stale Cloudflare DNS records / Sweep CF orphans (push) Successful in 35s
E2E Staging SaaS (full lifecycle) / E2E Staging SaaS (push) Failing after 15m54s
ci-required-drift / drift (push) Successful in 1m58s
Sweep stale e2e-* orgs (staging) / Sweep e2e orgs (push) Successful in 5s
Staging SaaS smoke (every 30 min) / Staging SaaS smoke (push) Successful in 4m54s
E2E Staging External Runtime / E2E Staging External Runtime (push) Successful in 5m32s
gitea-merge-queue / queue (push) Successful in 31s
status-reaper / reap (push) Successful in 2m51s
Continuous synthetic E2E (staging) / Synthetic E2E against staging (push) Successful in 5m55s
2026-05-15 05:57:38 +00:00
claude-ceo-assistant 3198a3ee5d fix(ci): throttle SOP refire workflow fan-out
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 29s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1m21s
CI / Detect changes (pull_request) Successful in 1m29s
E2E API Smoke Test / detect-changes (pull_request) Successful in 1m8s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 55s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 25s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 21s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 37s
gate-check-v3 / gate-check (pull_request) Successful in 38s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 1m10s
sop-checklist / all-items-acked (pull_request) Successful in 23s
sop-tier-check / tier-check (pull_request) Successful in 19s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 14s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 12s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 15s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m49s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 58s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 2m38s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 2m55s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 2m59s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 2m54s
CI / Python Lint & Test (pull_request) Successful in 7m53s
qa-review / approved (pull_request) Approved by core-qa review #3561
security-review / approved (pull_request) Approved by core-security review #3562
CI / Platform (Go) (pull_request) Successful in 13m43s
CI / Canvas (Next.js) (pull_request) Successful in 14m23s
CI / Canvas Deploy Reminder (pull_request) Successful in 7s
CI / all-required (pull_request) Successful in 14m35s
audit-force-merge / audit (pull_request) Successful in 18s
2026-05-14 22:39:05 -07:00
9 changed files with 54 additions and 20 deletions
+19 -9
View File
@@ -138,13 +138,13 @@ def status_state(status: dict) -> str:
def latest_statuses_by_context(statuses: list[dict]) -> dict[str, dict]:
# Gitea /statuses endpoint returns entries in ascending id order (oldest
# first). We need the LAST occurrence of each context, so iterate in
# reverse to prefer newer entries.
# first). We need the LAST occurrence of each context. Iterate in normal
# order and overwrite so the newest entry wins.
latest: dict[str, dict] = {}
for status in reversed(statuses):
for status in statuses:
context = status.get("context")
if isinstance(context, str):
latest[context] = status # overwrite: reverse order → newest wins
latest[context] = status # overwrite: normal order → newest wins
return latest
@@ -278,19 +278,23 @@ def get_combined_status(sha: str) -> dict:
def list_queued_issues() -> list[dict]:
# Fetch all open PRs and filter by queue label in Python.
# Gitea allows multiple labels with the same name (IDs 27, 30, 31 for
# "merge-queue"). The issues API `labels=NAME` filter matches at most one
# of those IDs, silently excluding PRs that carry the label under a
# different ID. Filtering in Python sidesteps this ambiguity.
_, body = api(
"GET",
f"/repos/{OWNER}/{NAME}/issues",
query={
"state": "open",
"type": "pulls",
"labels": QUEUE_LABEL,
"limit": "50",
"limit": "200",
},
)
if not isinstance(body, list):
raise ApiError("queued issues response not list")
return body
return [issue for issue in body if QUEUE_LABEL in label_names(issue)]
def get_pull(pr_number: int) -> dict:
@@ -350,7 +354,9 @@ def process_once(*, dry_run: bool = False) -> int:
main_latest = latest_statuses_by_context(main_status.get("statuses") or [])
main_ok, main_bad = required_contexts_green(main_latest, push_required_contexts())
if not main_ok:
print(f"::notice::queue paused: {WATCH_BRANCH}@{main_sha[:8]} required contexts not green: {', '.join(main_bad)}")
not_green = ", ".join(main_bad)
print(f"::notice::queue paused: {WATCH_BRANCH}@{main_sha[:8]} "
f"required contexts not green: {not_green}")
return 0
issue = choose_next_queued_issue(
@@ -371,7 +377,11 @@ def process_once(*, dry_run: bool = False) -> int:
post_comment(pr_number, f"merge-queue: skipped; base branch is not `{WATCH_BRANCH}`.", dry_run=dry_run)
return 0
if pr.get("head", {}).get("repo_id") != pr.get("base", {}).get("repo_id"):
post_comment(pr_number, "merge-queue: skipped; fork PRs are not supported by the serialized queue.", dry_run=dry_run)
post_comment(
pr_number,
"merge-queue: skipped; fork PRs are not supported by the serialized queue.",
dry_run=dry_run,
)
return 0
head_sha = pr.get("head", {}).get("sha")
@@ -19,7 +19,8 @@ def test_latest_statuses_dedupes_by_context_newest_first():
latest = mq.latest_statuses_by_context(statuses)
assert latest["CI / all-required (pull_request)"]["status"] == "failure"
# Newest entry wins (reverse iteration), so success overwrites failure.
assert latest["CI / all-required (pull_request)"]["status"] == "success"
assert latest["sop-checklist / all-items-acked (pull_request)"]["state"] == "success"
@@ -111,7 +112,10 @@ def test_merge_decision_updates_stale_pr_before_merge():
"state": "success",
"statuses": [{"context": "CI / all-required (push)", "status": "success"}],
},
pr_status={"state": "success", "statuses": [{"context": "CI / all-required (pull_request)", "status": "success"}]},
pr_status={
"state": "success",
"statuses": [{"context": "CI / all-required (pull_request)", "status": "success"}]
},
required_contexts=["CI / all-required (pull_request)"],
pr_has_current_base=False,
)
+5 -5
View File
@@ -135,9 +135,9 @@ class TestParseDirectives(unittest.TestCase):
self.aliases = _numeric_aliases()
def parse_ack_revoke(self, body):
directives, na_directives = sop.parse_directives(body, self.aliases)
self.assertEqual(na_directives, [])
return directives
# parse_directives returns a combined list of (kind, slug, note) tuples.
# Return it directly; the old two-list interface no longer applies.
return sop.parse_directives(body, self.aliases)
def test_simple_ack(self):
d = self.parse_ack_revoke("/sop-ack comprehensive-testing")
@@ -201,8 +201,8 @@ class TestParseDirectives(unittest.TestCase):
self.assertEqual(len(d), 1)
def test_empty_body(self):
self.assertEqual(sop.parse_directives("", self.aliases), ([], []))
self.assertEqual(sop.parse_directives(None, self.aliases), ([], []))
self.assertEqual(sop.parse_directives("", self.aliases), [])
self.assertEqual(sop.parse_directives(None, self.aliases), [])
def test_normalization_applied(self):
# /sop-ack Comprehensive_Testing → canonical comprehensive-testing
+1
View File
@@ -0,0 +1 @@
# CI trigger 2026-05-15
+9 -2
View File
@@ -552,6 +552,12 @@ jobs:
# required commit-status contexts for this SHA and fails if any fail, skip,
# or never emit.
#
# Timeout: 55min job-level, 50min internal deadline. Cold runners can take
# 16+min for Platform (Go) + 18min for Canvas + ~8min for Python Lint
# = ~42min of required context wall time. 50min deadline gives headroom
# for polling overhead and runner scheduling variance. mc#1099 cold-runner
# fix addresses the root cause (golangci-lint timeout, step-level ceilings).
#
# canvas-deploy-reminder is intentionally NOT included in all-required.needs.
# It is an informational main-push reminder, not a PR quality gate. Keeping
# it in this dependency list lets a skipped reminder skip the required
@@ -559,7 +565,7 @@ jobs:
#
continue-on-error: false
runs-on: ubuntu-latest
timeout-minutes: 45
timeout-minutes: 55
steps:
- name: Wait for required CI contexts
env:
@@ -589,9 +595,10 @@ jobs:
f"CI / Canvas (Next.js) ({event})",
f"CI / Shellcheck (E2E scripts) ({event})",
f"CI / Python Lint & Test ({event})",
f"CI / Canvas Deploy Reminder ({event})",
]
terminal_bad = {"failure", "error"}
deadline = time.time() + 40 * 60
deadline = time.time() + 50 * 60
last_summary = None
def fetch_statuses():
@@ -18,6 +18,10 @@ permissions:
pull-requests: read
statuses: write
concurrency:
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.event.issue.number || github.ref }}
cancel-in-progress: true
jobs:
dispatch:
runs-on: ubuntu-latest
+1 -1
View File
@@ -70,7 +70,7 @@ name: sop-checklist
# Cancel any in-progress runs for the same PR to prevent
# stale runs from overwriting newer status contexts.
concurrency:
group: ${{ github.repository }}-${{ github.event.pull_request.number }}
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.event.pull_request.number || github.event.issue.number || github.ref }}
cancel-in-progress: true
# bp-required: yes ← emits sop-checklist / all-items-acked (pull_request)
+4
View File
@@ -61,6 +61,10 @@ on:
pull_request_review:
types: [submitted, dismissed, edited]
concurrency:
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
tier-check:
runs-on: ubuntu-latest
@@ -646,8 +646,12 @@ const externalOpenClawTemplate = `# OpenClaw MCP config — outbound tool path.
# external machine today, pair with the Python SDK tab.
# 1. Install openclaw CLI + the workspace runtime wheel:
# The version pin (>=0.1.999) ensures the "molecule-mcp" console
# script is present — it is what keeps the workspace ALIVE on canvas
# (register-on-startup + 20s heartbeat). Older versions only ship
# a2a_mcp_server which does not heartbeat.
npm install -g openclaw@latest
pip install molecule-ai-workspace-runtime
pip install "molecule-ai-workspace-runtime>=0.1.999"
# 2. Onboard openclaw against your model provider (one-time setup).
# --non-interactive needs an explicit --provider + --model so it