Co-authored-by: Molecule AI Infra-Runtime-BE <infra-runtime-be@agents.moleculesai.app>
Co-committed-by: Molecule AI Infra-Runtime-BE <infra-runtime-be@agents.moleculesai.app>
Co-authored-by: Molecule AI Core-DevOps <core-devops@agents.moleculesai.app>
Co-committed-by: Molecule AI Core-DevOps <core-devops@agents.moleculesai.app>
Three bugs introduced in PR #477:
1. fake_discover(ws_id) missing source_workspace_id kwarg — discover_peer
signature is (target_id, source_workspace_id=None).
2. Direct attribute assignment (d._delegate_sync_via_polling = ...)
does not replace module-level 'from module import name' bindings
resolved at call time; must use monkeypatch.setattr.
3. Assertions checked for [A2A_RESULT_FROM_PEER] but the polling path
uses _A2A_BOUNDARY_START/END — _A2A_RESULT_FROM_PEER is added by
send_a2a_message (messaging path), not by _delegate_sync_via_polling.
Additionally: monkeypatch.setenv("DELEGATION_SYNC_VIA_INBOX", "1") forces
the polling code path so the test exercises the correct logic regardless
of environment defaults.
Closes#495.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Molecule AI Infra-Runtime-BE <infra-runtime-be@agents.moleculesai.app>
Co-committed-by: Molecule AI Infra-Runtime-BE <infra-runtime-be@agents.moleculesai.app>
Co-authored-by: Molecule AI Infra-Runtime-BE <infra-runtime-be@agents.moleculesai.app>
Co-committed-by: Molecule AI Infra-Runtime-BE <infra-runtime-be@agents.moleculesai.app>
Co-authored-by: Molecule AI Core-DevOps <core-devops@agents.moleculesai.app>
Co-committed-by: Molecule AI Core-DevOps <core-devops@agents.moleculesai.app>
tier:low and tier:high are OR gates — any one positive verdict
is sufficient. The previous implementation required ALL groups to have
positive verdicts, causing INCOMPLETE even when core-devops APPROVED
and core-lead was absent.
Now uses tier-specific logic:
- tier:low / tier:high (OR): any positive = CLEAR
- tier:medium (AND): all positive = CLEAR
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Paginate all list endpoints (comments, reviews) to handle PRs with
many comments without missing entries. Uses per_page=100 with page
increment loop, safety-capped at 20 pages.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Gitea reviews use "submitted_at" not "created_at" for when the review
was submitted. The earlier signal_1_comment_scan fix (inherited from
sop-tier-check investigation) already handled this; signal_2 and
signal_3 were missing the same correction.
Fixes KeyError: 'created_at' on PRs with no comments/reviews.
Includes the individual-check-status fix (use "status" not "state").
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Gitea Actions API uses "status" (pending/success/failure) not "state"
for individual status entries. The "state" field is null for pending
runs. This caused all_check_statuses to show Python null instead of
"pending" for queued jobs.
Also verified on PR #391 and PR #393 — individual checks now correctly
display "pending" while combined_state is "pending" (CI_PENDING verdict).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
SOP-6 + CI gate checker for Gitea PRs. Detects:
- Signal 1: Author-aware agent-tag comment scan (tier-aware)
- Signal 2: REQUEST_CHANGES reviews state machine
- Signal 3: Staleness detection (SOP-12)
- Signal 6: CI required-checks awareness
Post `[gate-check-v3] STATUS:` comment on PRs. CLI + Gitea Actions
workflow (cron hourly + PR-triggered).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Documents four persistent operational findings from the 2026-05-11
Gitea migration and CI noise investigation:
1. Runner network isolation (git remote unreachable from container)
2. continue-on-error only works at step level, not job level
3. workflow_dispatch.inputs not supported
4. fetch-depth:0 on actions/checkout times out
References PR #441 (harness-replays detect-changes fix) and
Task #173 (pre-clone manifest deps pattern).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Cherry-picked from PR #452 (fix/canvas-test-and-design-fixes) which
was closed without merge during the PR #443 cascade. The fix adds a
mockPost reference so individual tests can reset the POST mock cleanly
instead of queueing multiple resolved/rejected values.
Without this, the "shows an error toast when POST fails" and "keeps
the card visible when POST fails" tests queue two responses from
beforeEach's mockResolvedValue({}) and the second mockRejectedValueOnce()
call, causing non-deterministic test outcomes.
Fixes test failures in ApprovalBanner suite.
Re-applies PR#462 on current main (PR#443 merged first and renamed
canary-staging.yml -> staging-smoke.yml, conflicting #462).
Swept 6 files (15 secret-ref flips):
- .gitea/workflows/staging-smoke.yml (3 refs + drop continue-on-error + add notify-on-failure step)
- .gitea/workflows/e2e-staging-saas.yml (3 refs)
- .gitea/workflows/e2e-staging-sanity.yml (3 refs)
- .gitea/workflows/e2e-staging-canvas.yml (3 refs)
- .gitea/workflows/e2e-staging-external.yml (3 refs)
- tests/e2e/STAGING_SAAS_E2E.md (1 heading flip + 1 historical-rename breadcrumb)
Each workflow keeps one inline breadcrumb comment pointing back to
the old name and internal#322.
staging-smoke is the 30-min canary cadence for the entire staging
SaaS stack; silent failure (continue-on-error: true) masked exactly
the regressions the smoke exists to surface, same class as PR#461
(`sweep-stale-e2e-orgs`). Dropped continue-on-error from the smoke
job + added a fail-loud `if: failure()` Notify step mirroring
PR#461. The four other `e2e-staging-*` workflows KEEP
continue-on-error: true per RFC #219 §1 — they are advisory.
Excluded from this PR:
- .gitea/workflows/sweep-stale-e2e-orgs.yml (PR#461 owns)
- .gitea/workflows/staging-verify.yml (only references the plural MOLECULE_STAGING_ADMIN_TOKENS canary-fleet secret, out of scope)
- scripts/staging-smoke.sh (same — plural only)
- docs/architecture/canary-release.md (same — plural only)
- .github/ mirror tree (separate scope per reference_molecule_core_actions_gitea_only)
Verified locally: yaml.safe_load clean on all 5 workflows; grep
returns ZERO non-breadcrumb references in the swept files; the
plural MOLECULE_STAGING_ADMIN_TOKENS references in
staging-verify.yml / scripts/staging-smoke.sh / canary-release.md
are intentionally untouched.
Refs: internal#322, PR#461, feedback_rename_pr_and_edit_pr_conflict_sequence
Gitea Actions runners cannot reach https://git.moleculesai.app over HTTPS
(runbooks/gitea-operational-quirks.md §runner-network-isolation).
fetch-depth: 0 on actions/checkout triggers a full repo history fetch
that times out at ~15s, causing the workflow to fail on Gitea runners
(main RED, issue #460).
Fix: use fetch-depth: 1 (shallow clone) and explicitly fetch tags with
git fetch origin --tags --depth=1. The collision check (git tag --list)
still works since we only need the most recent tag, not full history.
git push of the new tag works on a shallow clone.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Follows up on #432 (merged). Extracts _check_delegation_results_pending()
from the inline guard in _run_idle_loop() so tests can call the real
production function directly via patch(builtins.open, ...).
Fixes#401: the previous test used a mirror copy of the guard logic,
which risks drifting from the production implementation over time.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PurchaseSuccessModal tests used a fixed 50ms setTimeout to wait for the
dialog to appear after React useEffect batch + createPortal. This was
flaky because React's rendering timing varies.
Replace waitForDialog() fixed-delay with waitFor() polling — the test
waits exactly as long as React needs, no more. Update all dismiss tests
to use act(() => setTimeout(...)) after vi.useRealTimers() for reliable
real-timer behavior.
Result: 18/18 tests pass (was 14/18 with 4 timing-related failures).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>