Compare commits

..

116 Commits

Author SHA1 Message Date
Molecule AI Dev Engineer B (MiniMax) 6509cb7b9d fix(observability): enrich server log on CommitMemory plugin error
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 2s
Harness Replays / detect-changes (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
E2E Chat / detect-changes (pull_request) Successful in 7s
CI / Detect changes (pull_request) Successful in 13s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 10s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 13s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 13s
qa-review / approved (pull_request_target) Failing after 6s
security-review / approved (pull_request_target) Failing after 5s
Harness Replays / Harness Replays (pull_request) Successful in 1s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
CI / Canvas (Next.js) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 5s
CI / Canvas Deploy Status (pull_request) Successful in 1s
E2E Chat / E2E Chat (pull_request) Successful in 13s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 58s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m11s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m6s
CI / Platform (Go) (pull_request) Successful in 6m16s
CI / all-required (pull_request) Successful in 5s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 4s
gate-check-v3 / gate-check (pull_request_target) Successful in 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: memory-consulted
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-tier-check / tier-check (pull_request_target) Successful in 6s
sop-checklist / all-items-acked (pull_request_target) Successful in 7s
The POST /workspaces/:id/memories handler returns a generic
HTTP 500 'failed to store memory' when the underlying v2
memory plugin's CommitMemory call errors. The current
log.Printf('Commit memory error (plugin): %v', err) emits
only the error — operators have no workspace, scope, or
namespace context to diagnose recurring main incidents
(continuous-synth E2E + HMA memory-commit both currently
fail with this 500; the backend error is swallowed).

Fix: enrich the server-side log line with workspaceID, the
requested scope, the resolved v2 namespace, a structured
err_class=<type> field (for log-aggregator filtering),
and the quoted err text (preserves trailing whitespace /
special chars that %v would munge).

Hard constraint (same discipline as the #2392 leak fix):
the underlying err stays server-log-only. The HTTP
response body is UNCHANGED — still 500 'failed to store
memory' with no plugin error leaked to the client.

No behavior change to the write path itself. The change
is one log.Printf line + a 9-line comment explaining the
no-leak discipline. The new log line is:

  log.Printf('Commit memory plugin error: workspace=%s scope=%s namespace=%s err_class=%T err=%q',
      workspaceID, body.Scope, nsName, err, err)

Unblocks operator diagnosis of the memory-v2 backend
without changing the client surface or weakening the
server's error-disclosure posture.
2026-06-07 13:00:02 +00:00
devops-engineer 884ae06e9f Merge pull request 'feat(approval-gate): wire gateDestructive into live destructive handlers (Phase 4b)' (#2382) from feat/platform-agent-gate-wiring into main
ci-arm64-advisory / fast-checks (push) Waiting to run
CI / all-required (push) Blocked by required conditions
CI / Python Lint & Test (push) Successful in 4s
Block internal-flavored paths / Block forbidden paths (push) Successful in 7s
CI / Detect changes (push) Successful in 14s
E2E API Smoke Test / detect-changes (push) Successful in 10s
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (staging) (push) Has been skipped
E2E Chat / detect-changes (push) Successful in 8s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Has started running
Handlers Postgres Integration / detect-changes (push) Successful in 5s
CI / Canvas (Next.js) (push) Successful in 3s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 5s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 5s
CI / Canvas Deploy Status (push) Successful in 1s
Harness Replays / detect-changes (push) Successful in 16s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 16s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 24s
Harness Replays / Harness Replays (push) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 6s
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (compile+skip) (push) Successful in 1m13s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 1m7s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m18s
E2E Chat / E2E Chat (push) Successful in 2m13s
CI / Platform (Go) (push) Successful in 4m13s
CI / Shellcheck (E2E scripts) (push) Waiting to run
publish-workspace-server-image / build-and-push (push) Failing after 5m13s
publish-workspace-server-image / Production auto-deploy (push) Has been skipped
2026-06-06 23:25:27 +00:00
core-devops acb9d81169 feat(approval-gate): wire gateDestructive into live destructive handlers (Phase 4b)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 17s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 12s
E2E Chat / detect-changes (pull_request) Successful in 10s
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (staging) (pull_request) Has been skipped
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 16s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 19s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
Handlers Postgres Integration / detect-changes (pull_request) Successful in 17s
security-review / approved (pull_request_target) Failing after 6s
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (compile+skip) (pull_request) Successful in 26s
sop-tier-check / tier-check (pull_request_target) Failing after 10s
qa-review / approved (pull_request_target) Failing after 17s
E2E Chat / E2E Chat (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
gate-check-v3 / gate-check (pull_request_target) Successful in 29s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
Harness Replays / Harness Replays (pull_request) Successful in 5s
CI / Canvas (Next.js) (pull_request) Successful in 6s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m1s
CI / Canvas Deploy Status (pull_request) Successful in 2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2m9s
CI / Platform (Go) (pull_request) Successful in 4m3s
CI / all-required (pull_request) Successful in 2s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 7s
audit-force-merge / audit (pull_request_target) Successful in 13s
Activates the merged 4a approval-gate infra. Scope is centralized in
gateDestructive so each handler is a one-liner, and the policy is uniform +
testable:
  - default-OFF rollout flag MOLECULE_PLATFORM_APPROVAL_GATE (mirrors 3a/3c
    default-off; protects existing org-token automation until the platform
    agent ships);
  - ONLY org-token callers are gated. The platform agent runs with
    MOLECULE_API_KEY=<org-admin token> (auth middleware sets org_token_id);
    ordinary workspace-token agents and human CP-session operators are NOT
    gated, so normal operation is byte-identical. Realises the file-header
    trust boundary without gating everyone.

Wired: WorkspaceHandler.Delete (delete_workspace) + SecretsHandler.Set
(secret_write). requireApproval/gateDestructive now take the events.EventEmitter
interface and tolerate a nil emitter (SecretsHandler is broadcaster-less) — the
pending approval row is still persisted, only the live canvas push is skipped.

3 new unit tests (flag default-off, org-token detection, scope short-circuits)
+ existing approval/secret/delete suites green; golangci-lint clean.

Deferred (documented follow-on): org_token_mint (OrgTokenHandler is org-scoped,
no workspace_id to key the approval) + deprovision_workspace (no workspace-server
handler — lives CP-side).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 16:18:09 -07:00
devops-engineer 0519533cc2 Merge PR #1964 via Gitea merge queue
ci-arm64-advisory / fast-checks (push) Waiting to run
CI / Python Lint & Test (push) Successful in 3s
Handlers Postgres Integration / detect-changes (push) Successful in 4s
E2E API Smoke Test / detect-changes (push) Successful in 7s
E2E Chat / detect-changes (push) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 6s
Block internal-flavored paths / Block forbidden paths (push) Successful in 10s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 4s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (push) Successful in 4s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (push) Successful in 9s
CI / Detect changes (push) Successful in 11s
E2E Chat / E2E Chat (push) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 5s
CI / Platform (Go) (push) Successful in 1s
CI / Canvas (Next.js) (push) Successful in 2s
CI / Shellcheck (E2E scripts) (push) Successful in 1s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 13s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 8s
CI / Canvas Deploy Status (push) Successful in 0s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 14s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 17s
CI / all-required (push) Successful in 13s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m7s
Ops Scripts Tests / Ops scripts (unittest) (push) Successful in 1m4s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (push) Successful in 1m37s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Successful in 1m45s
publish-workspace-server-image / build-and-push (push) Failing after 4m36s
publish-workspace-server-image / Production auto-deploy (push) Has been skipped
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 22:58:23 +00:00
Molecule AI Dev Engineer A (Kimi) ea48a8fc5e fix(umbrella-reaper): fail-closed status-read + paginate PR list (#1964 CR3)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
E2E Chat / detect-changes (pull_request) Successful in 7s
CI / Platform (Go) (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 9s
E2E Chat / E2E Chat (pull_request) Successful in 3s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 3s
CI / Canvas (Next.js) (pull_request) Successful in 11s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 11s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 17s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 13s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 12s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 7/7
sop-checklist / na-declarations (pull_request) N/A: (none)
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 17s
sop-checklist / all-items-acked (pull_request_target) Successful in 6s
security-review / approved (pull_request_target) Failing after 11s
qa-review / approved (pull_request_target) Failing after 12s
gate-check-v3 / gate-check (pull_request_target) Failing after 13s
CI / Canvas Deploy Status (pull_request) Successful in 2s
sop-tier-check / tier-check (pull_request_target) Failing after 9s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
CI / all-required (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m1s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m4s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 57s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m13s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m16s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m28s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 8s
audit-force-merge / audit (pull_request_target) Successful in 9s
Addresses agent-reviewer-cr2 + agent-researcher blockers on head 0ce7763c:

1. Paginate list_open_prs() — loops through all pages instead of
   truncating at limit=50. Core currently has >50 open PRs; stale
   umbrellas on page 2+ were silently missed.

2. Fail-closed on get_combined_status() ApiError — process_pr() now
   returns False (not True) so main() exits nonzero. A status-read
   outage or 5xx can no longer report green while blind.

3. Fail-closed on malformed status response — missing or non-list
   'statuses' array returns False instead of treating as empty skip.

4. Regression coverage: 4 new pytest cases for pagination,
   status-fetch failure, missing statuses array, and main() nonzero
   aggregation on read failure.

Test plan: python3 -m pytest .gitea/scripts/tests/test_umbrella_reaper_api.py
All 15 tests pass.
2026-06-06 22:52:28 +00:00
Molecule AI Dev Engineer A (Kimi) 0ce7763c3c Merge branch 'main' into fix/umbrella-reaper-1780
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Detect changes (pull_request) Successful in 7s
E2E Chat / detect-changes (pull_request) Successful in 8s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 13s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 14s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 11s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
CI / Platform (Go) (pull_request) Successful in 1s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 4s
CI / Canvas (Next.js) (pull_request) Successful in 4s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 3s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
E2E Chat / E2E Chat (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
qa-review / approved (pull_request_target) Failing after 7s
gate-check-v3 / gate-check (pull_request_target) Failing after 10s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 16s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 7/7
sop-checklist / na-declarations (pull_request) N/A: (none)
security-review / approved (pull_request_target) Failing after 7s
sop-checklist / all-items-acked (pull_request_target) Successful in 6s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Successful in 1s
sop-tier-check / tier-check (pull_request_target) Failing after 24s
CI / all-required (pull_request) Successful in 13s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m2s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m17s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m16s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m22s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m25s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m29s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 4s
2026-06-06 22:39:17 +00:00
devops-engineer 76ec152cf9 Merge PR #2377 via Gitea merge queue
ci-arm64-advisory / fast-checks (push) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 14s
Block internal-flavored paths / Block forbidden paths (push) Successful in 13s
CI / Detect changes (push) Successful in 9s
Handlers Postgres Integration / detect-changes (push) Successful in 3s
CI / Python Lint & Test (push) Successful in 10s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 6s
Harness Replays / detect-changes (push) Successful in 4s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 4s
CI / Shellcheck (E2E scripts) (push) Successful in 1s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 4s
Harness Replays / Harness Replays (push) Successful in 1s
E2E API Smoke Test / detect-changes (push) Successful in 16s
E2E Chat / detect-changes (push) Successful in 14s
CI / Platform (Go) (push) Successful in 11s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2s
publish-canvas-image / Build & push canvas image (push) Successful in 1m35s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m7s
E2E Chat / E2E Chat (push) Successful in 4m43s
publish-workspace-server-image / build-and-push (push) Successful in 6m54s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 6m34s
CI / Canvas (Next.js) (push) Successful in 7m55s
CI / Canvas Deploy Status (push) Successful in 2s
CI / all-required (push) Successful in 1s
publish-canvas-image / Promote canvas :latest to CI-green build (push) Successful in 7m52s
publish-workspace-server-image / Production auto-deploy (push) Successful in 4m32s
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 22:33:24 +00:00
devops-engineer 96f6dff691 Merge pull request 'feat: install platform agent as org root (Phase 1)' (#2371) from feat/platform-agent-install into main
ci-arm64-advisory / fast-checks (push) Waiting to run
Block internal-flavored paths / Block forbidden paths (push) Successful in 5s
CI / Python Lint & Test (push) Successful in 4s
CI / Detect changes (push) Successful in 6s
E2E API Smoke Test / detect-changes (push) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 4s
E2E Chat / detect-changes (push) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 6s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 4s
CI / Canvas (Next.js) (push) Successful in 3s
CI / Shellcheck (E2E scripts) (push) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 12s
Handlers Postgres Integration / detect-changes (push) Successful in 13s
Harness Replays / detect-changes (push) Successful in 12s
CI / Canvas Deploy Status (push) Successful in 4s
Harness Replays / Harness Replays (push) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 15s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 58s
E2E Chat / E2E Chat (push) Failing after 1m49s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 2m58s
publish-workspace-server-image / build-and-push (push) Successful in 3m13s
CI / Platform (Go) (push) Successful in 6m47s
CI / all-required (push) Successful in 3s
publish-workspace-server-image / Production auto-deploy (push) Successful in 6m9s
2026-06-06 22:18:51 +00:00
devops-engineer 2ac0ca1436 Merge PR #2376 via Gitea merge queue
Block internal-flavored paths / Block forbidden paths (push) Successful in 4s
CI / Python Lint & Test (push) Successful in 6s
Handlers Postgres Integration / detect-changes (push) Successful in 4s
E2E Chat / detect-changes (push) Successful in 7s
Harness Replays / detect-changes (push) Successful in 4s
CI / Detect changes (push) Successful in 11s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 5s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 4s
CI / Canvas (Next.js) (push) Successful in 1s
E2E API Smoke Test / detect-changes (push) Successful in 14s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 6s
CI / Shellcheck (E2E scripts) (push) Successful in 2s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 12s
Harness Replays / Harness Replays (push) Successful in 5s
CI / Canvas Deploy Status (push) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 4s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 15s
publish-workspace-server-image / build-and-push (push) Failing after 57s
publish-workspace-server-image / Production auto-deploy (push) Has been skipped
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 58s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m7s
E2E Chat / E2E Chat (push) Failing after 1m50s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
CI / Platform (Go) (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
CI / all-required (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 22:14:03 +00:00
devops-engineer 255df68f40 Merge PR #2373 via Gitea merge queue
Block internal-flavored paths / Block forbidden paths (push) Successful in 4s
CI / Python Lint & Test (push) Successful in 4s
E2E API Smoke Test / detect-changes (push) Successful in 6s
Handlers Postgres Integration / detect-changes (push) Successful in 4s
E2E Chat / detect-changes (push) Successful in 8s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 4s
CI / Detect changes (push) Successful in 12s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 9s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 12s
CI / Canvas (Next.js) (push) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 8s
CI / Shellcheck (E2E scripts) (push) Successful in 4s
CI / Platform (Go) (push) Successful in 5s
CI / Canvas Deploy Status (push) Successful in 1s
E2E Chat / E2E Chat (push) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 5s
CI / all-required (push) Successful in 4s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 17s
Ops Scripts Tests / Ops scripts (unittest) (push) Successful in 1m2s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 2m20s
publish-workspace-server-image / build-and-push (push) Successful in 3m29s
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m18s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 22:08:13 +00:00
devops-engineer 8a78a8aa71 Merge PR #2366 via Gitea merge queue
Block internal-flavored paths / Block forbidden paths (push) Successful in 5s
CI / Python Lint & Test (push) Successful in 4s
CI / Detect changes (push) Successful in 9s
E2E API Smoke Test / detect-changes (push) Successful in 7s
E2E Chat / detect-changes (push) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 7s
CI / Platform (Go) (push) Successful in 2s
Handlers Postgres Integration / detect-changes (push) Successful in 10s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 10s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 9s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 8s
CI / Canvas (Next.js) (push) Successful in 2s
CI / Shellcheck (E2E scripts) (push) Successful in 2s
E2E Chat / E2E Chat (push) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 3s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 4s
CI / Canvas Deploy Status (push) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 15s
CI / all-required (push) Successful in 2s
Ops Scripts Tests / Ops scripts (unittest) (push) Successful in 56s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 2m10s
publish-workspace-server-image / build-and-push (push) Successful in 5m0s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m32s
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 22:02:29 +00:00
devops-engineer 06e908602a Merge PR #2363 via Gitea merge queue
Block internal-flavored paths / Block forbidden paths (push) Successful in 3s
CI / Detect changes (push) Successful in 6s
CI / Python Lint & Test (push) Successful in 6s
Handlers Postgres Integration / detect-changes (push) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 6s
E2E API Smoke Test / detect-changes (push) Successful in 11s
CI / Shellcheck (E2E scripts) (push) Successful in 2s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 8s
E2E Chat / detect-changes (push) Successful in 12s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 7s
CI / Canvas (Next.js) (push) Successful in 6s
CI / Platform (Go) (push) Successful in 6s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 4s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 3s
CI / Canvas Deploy Status (push) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 15s
CI / all-required (push) Successful in 4s
E2E Chat / E2E Chat (push) Successful in 11s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m5s
Ops Scripts Tests / Ops scripts (unittest) (push) Successful in 1m12s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Successful in 1m22s
publish-workspace-server-image / build-and-push (push) Successful in 3m12s
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m14s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 21:57:48 +00:00
devops-engineer 2c2ea19edd Merge PR #2342 via Gitea merge queue
Block internal-flavored paths / Block forbidden paths (push) Successful in 6s
Handlers Postgres Integration / detect-changes (push) Successful in 5s
CI / Python Lint & Test (push) Successful in 6s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (push) Successful in 4s
E2E API Smoke Test / detect-changes (push) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 7s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (push) Successful in 4s
CI / Detect changes (push) Successful in 13s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 4s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 9s
E2E Chat / detect-changes (push) Successful in 13s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 2s
CI / Shellcheck (E2E scripts) (push) Successful in 1s
CI / Canvas (Next.js) (push) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 13s
CI / Canvas Deploy Status (push) Successful in 1s
E2E Chat / E2E Chat (push) Successful in 2s
CI / Platform (Go) (push) Successful in 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 14s
CI / all-required (push) Successful in 5s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m8s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Successful in 1m20s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (push) Successful in 1m21s
publish-workspace-server-image / build-and-push (push) Successful in 4m20s
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m30s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 21:52:39 +00:00
devops-engineer 81e9660f64 Merge PR #2307 via Gitea merge queue
Block internal-flavored paths / Block forbidden paths (push) Successful in 3s
Handlers Postgres Integration / detect-changes (push) Successful in 5s
E2E Chat / detect-changes (push) Successful in 7s
CI / Python Lint & Test (push) Successful in 11s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (push) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 4s
E2E Chat / E2E Chat (push) Successful in 2s
CI / Detect changes (push) Successful in 16s
E2E API Smoke Test / detect-changes (push) Successful in 16s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 15s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 4s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (push) Successful in 11s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 12s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 13s
CI / Platform (Go) (push) Successful in 10s
CI / Canvas (Next.js) (push) Successful in 11s
CI / Shellcheck (E2E scripts) (push) Successful in 14s
CI / Canvas Deploy Status (push) Successful in 1s
CI / all-required (push) Successful in 2s
Ops Scripts Tests / Ops scripts (unittest) (push) Successful in 59s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Successful in 1m18s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (push) Successful in 1m15s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m36s
publish-workspace-server-image / build-and-push (push) Successful in 3m7s
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m17s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 21:47:36 +00:00
devops-engineer 4d47a05b67 Merge PR #2306 via Gitea merge queue
Block internal-flavored paths / Block forbidden paths (push) Successful in 3s
CI / Python Lint & Test (push) Successful in 3s
E2E API Smoke Test / detect-changes (push) Successful in 6s
Handlers Postgres Integration / detect-changes (push) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 4s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 3s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (push) Successful in 4s
CI / Detect changes (push) Successful in 14s
E2E Chat / detect-changes (push) Successful in 13s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 12s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 5s
CI / Platform (Go) (push) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 2s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (push) Successful in 18s
CI / Canvas (Next.js) (push) Successful in 10s
E2E Chat / E2E Chat (push) Successful in 10s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 15s
CI / Shellcheck (E2E scripts) (push) Successful in 23s
CI / Canvas Deploy Status (push) Successful in 11s
CI / all-required (push) Successful in 2s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 56s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (push) Successful in 1m4s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m6s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (push) Successful in 1m13s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Successful in 1m26s
publish-workspace-server-image / build-and-push (push) Successful in 3m13s
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m22s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (push) Has been skipped
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 21:42:41 +00:00
devops-engineer 6784f09787 Merge PR #2301 via Gitea merge queue
Block internal-flavored paths / Block forbidden paths (push) Successful in 4s
CI / Python Lint & Test (push) Successful in 3s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 7s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (push) Successful in 4s
E2E Chat / detect-changes (push) Successful in 7s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 5s
CI / Detect changes (push) Successful in 12s
E2E API Smoke Test / detect-changes (push) Successful in 11s
Handlers Postgres Integration / detect-changes (push) Successful in 9s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 3s
CI / Platform (Go) (push) Successful in 1s
CI / Canvas (Next.js) (push) Successful in 1s
CI / Canvas Deploy Status (push) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 16s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (push) Successful in 19s
CI / Shellcheck (E2E scripts) (push) Successful in 14s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 15s
CI / all-required (push) Successful in 2s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (push) Successful in 1m28s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Successful in 1m32s
E2E Chat / E2E Chat (push) Failing after 1m47s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 2m18s
publish-workspace-server-image / build-and-push (push) Successful in 3m18s
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m21s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 21:37:35 +00:00
devops-engineer 3a0f15180c Merge PR #2300 via Gitea merge queue
Block internal-flavored paths / Block forbidden paths (push) Successful in 4s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (push) Successful in 5s
CI / Python Lint & Test (push) Successful in 6s
CI / Detect changes (push) Successful in 8s
E2E API Smoke Test / detect-changes (push) Successful in 7s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 4s
Handlers Postgres Integration / detect-changes (push) Successful in 9s
CI / Platform (Go) (push) Successful in 2s
CI / Canvas (Next.js) (push) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 10s
E2E Chat / detect-changes (push) Successful in 13s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 13s
CI / Shellcheck (E2E scripts) (push) Successful in 4s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (push) Successful in 10s
CI / Canvas Deploy Status (push) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 7s
E2E Chat / E2E Chat (push) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 4s
CI / all-required (push) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 15s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Successful in 1m12s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (push) Successful in 1m9s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m5s
publish-workspace-server-image / build-and-push (push) Successful in 4m13s
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m23s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 21:32:31 +00:00
devops-engineer c58d9d324d Merge PR #2299 via Gitea merge queue
Block internal-flavored paths / Block forbidden paths (push) Successful in 5s
CI / Python Lint & Test (push) Successful in 4s
CI / Detect changes (push) Successful in 5s
Handlers Postgres Integration / detect-changes (push) Successful in 3s
CI / Platform (Go) (push) Successful in 2s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 4s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (push) Successful in 5s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (push) Successful in 4s
CI / Canvas (Next.js) (push) Successful in 2s
CI / Canvas Deploy Status (push) Successful in 1s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 11s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 6s
E2E API Smoke Test / detect-changes (push) Successful in 15s
E2E Chat / detect-changes (push) Successful in 15s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 15s
CI / Shellcheck (E2E scripts) (push) Successful in 14s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 13s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 8s
E2E Chat / E2E Chat (push) Successful in 8s
CI / all-required (push) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m7s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (push) Successful in 1m9s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Successful in 1m28s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 1m37s
publish-workspace-server-image / build-and-push (push) Failing after 2m30s
publish-workspace-server-image / Production auto-deploy (push) Has been skipped
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 21:27:24 +00:00
devops-engineer 78ca56c638 Merge PR #2297 via Gitea merge queue
ci-arm64-advisory / fast-checks (push) Waiting to run
Block internal-flavored paths / Block forbidden paths (push) Successful in 3s
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (staging) (push) Has been skipped
E2E API Smoke Test / detect-changes (push) Successful in 6s
Handlers Postgres Integration / detect-changes (push) Successful in 3s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 5s
Harness Replays / detect-changes (push) Successful in 3s
CI / Python Lint & Test (push) Successful in 8s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 3s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 2s
Harness Replays / Harness Replays (push) Successful in 1s
E2E Chat / detect-changes (push) Successful in 15s
CI / Detect changes (push) Successful in 16s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 9s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 14s
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (compile+skip) (push) Successful in 21s
CI / Shellcheck (E2E scripts) (push) Successful in 8s
CI / Canvas (Next.js) (push) Successful in 9s
CI / Canvas Deploy Status (push) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m9s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 1m53s
E2E Chat / E2E Chat (push) Failing after 3m6s
CI / Platform (Go) (push) Successful in 4m0s
CI / all-required (push) Successful in 1s
publish-workspace-server-image / build-and-push (push) Successful in 5m3s
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m23s
E2E Staging External Runtime / E2E Staging External Runtime (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 21:17:30 +00:00
devops-engineer 44f8ae80f0 Merge PR #2290 via Gitea merge queue
ci-arm64-advisory / fast-checks (push) Waiting to run
CI / Python Lint & Test (push) Successful in 3s
Block internal-flavored paths / Block forbidden paths (push) Successful in 9s
E2E API Smoke Test / detect-changes (push) Successful in 6s
E2E Chat / detect-changes (push) Successful in 6s
Harness Replays / detect-changes (push) Successful in 3s
CI / Detect changes (push) Successful in 10s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 4s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 4s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2s
CI / Platform (Go) (push) Successful in 2s
Handlers Postgres Integration / detect-changes (push) Successful in 10s
CI / Shellcheck (E2E scripts) (push) Successful in 2s
Harness Replays / Harness Replays (push) Successful in 5s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 11s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 16s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 15s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m7s
publish-canvas-image / Build & push canvas image (push) Successful in 3m15s
publish-workspace-server-image / build-and-push (push) Successful in 3m21s
E2E Chat / E2E Chat (push) Failing after 3m22s
CI / Canvas (Next.js) (push) Successful in 6m17s
CI / Canvas Deploy Status (push) Successful in 1s
CI / all-required (push) Successful in 1s
publish-canvas-image / Promote canvas :latest to CI-green build (push) Successful in 3m29s
publish-workspace-server-image / Production auto-deploy (push) Successful in 5m21s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 10m26s
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 21:07:45 +00:00
devops-engineer 0f55402459 Merge PR #2264 via Gitea merge queue
ci-arm64-advisory / fast-checks (push) Waiting to run
CI / Python Lint & Test (push) Successful in 3s
Block internal-flavored paths / Block forbidden paths (push) Successful in 5s
CI / Detect changes (push) Successful in 6s
Harness Replays / detect-changes (push) Successful in 4s
Handlers Postgres Integration / detect-changes (push) Successful in 4s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 4s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 7s
CI / Shellcheck (E2E scripts) (push) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 4s
Harness Replays / Harness Replays (push) Successful in 2s
E2E API Smoke Test / detect-changes (push) Successful in 11s
CI / Platform (Go) (push) Successful in 7s
E2E Chat / detect-changes (push) Successful in 14s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 14s
publish-workspace-server-image / build-and-push (push) Failing after 2m25s
publish-canvas-image / Build & push canvas image (push) Failing after 2m29s
publish-canvas-image / Promote canvas :latest to CI-green build (push) Has been skipped
publish-workspace-server-image / Production auto-deploy (push) Has been skipped
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 3m24s
E2E Chat / E2E Chat (push) Failing after 3m50s
CI / Canvas (Next.js) (push) Successful in 6m15s
CI / Canvas Deploy Status (push) Successful in 2s
CI / all-required (push) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Failing after 7m45s
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 20:57:37 +00:00
devops-engineer b87e20a559 Merge PR #2260 via Gitea merge queue
ci-arm64-advisory / fast-checks (push) Waiting to run
CI / Python Lint & Test (push) Successful in 2s
Block internal-flavored paths / Block forbidden paths (push) Successful in 5s
CI / Detect changes (push) Successful in 6s
E2E API Smoke Test / detect-changes (push) Successful in 6s
Handlers Postgres Integration / detect-changes (push) Successful in 4s
E2E Chat / detect-changes (push) Successful in 6s
Harness Replays / detect-changes (push) Successful in 4s
CI / Shellcheck (E2E scripts) (push) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 9s
Harness Replays / Harness Replays (push) Successful in 2s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 10s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 20s
E2E Chat / E2E Chat (push) Failing after 1m48s
publish-canvas-image / Build & push canvas image (push) Successful in 1m55s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2m17s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 3m24s
publish-workspace-server-image / build-and-push (push) Successful in 3m34s
CI / Canvas (Next.js) (push) Successful in 6m19s
CI / Canvas Deploy Status (push) Successful in 4s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Failing after 6m47s
CI / Platform (Go) (push) Successful in 7m27s
CI / all-required (push) Successful in 1s
publish-canvas-image / Promote canvas :latest to CI-green build (push) Successful in 5m40s
publish-workspace-server-image / Production auto-deploy (push) Successful in 6m12s
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 20:43:34 +00:00
devops-engineer beec3e52b4 Merge PR #2031 via Gitea merge queue
Block internal-flavored paths / Block forbidden paths (push) Successful in 4s
CI / Detect changes (push) Successful in 6s
Handlers Postgres Integration / detect-changes (push) Successful in 4s
CI / Python Lint & Test (push) Successful in 6s
CI / Platform (Go) (push) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 4s
E2E API Smoke Test / detect-changes (push) Successful in 18s
E2E Chat / detect-changes (push) Successful in 18s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 17s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 15s
CI / Shellcheck (E2E scripts) (push) Successful in 15s
CI / Canvas (Next.js) (push) Successful in 15s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 2s
E2E Chat / E2E Chat (push) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 17s
CI / Canvas Deploy Status (push) Successful in 1s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 5s
CI / all-required (push) Successful in 4s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m2s
publish-workspace-server-image / build-and-push (push) Successful in 4m53s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m39s
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 20:38:06 +00:00
devops-engineer 9a21ccd96f Merge PR #2238 via Gitea merge queue
CI / Detect changes (push) Successful in 7s
Block internal-flavored paths / Block forbidden paths (push) Successful in 7s
E2E Chat / detect-changes (push) Successful in 7s
CI / Python Lint & Test (push) Successful in 7s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 5s
Handlers Postgres Integration / detect-changes (push) Successful in 9s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 4s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (push) Successful in 5s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (push) Successful in 11s
CI / Shellcheck (E2E scripts) (push) Successful in 1s
CI / Platform (Go) (push) Successful in 2s
E2E Chat / E2E Chat (push) Successful in 2s
E2E API Smoke Test / detect-changes (push) Successful in 17s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 16s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 13s
CI / Canvas (Next.js) (push) Successful in 8s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2s
CI / Canvas Deploy Status (push) Successful in 0s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 12s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 8s
CI / all-required (push) Successful in 7s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (push) Successful in 1m11s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m4s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (push) Successful in 1m22s
publish-workspace-server-image / build-and-push (push) Successful in 5m3s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m23s
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 20:32:38 +00:00
Molecule AI Dev Engineer A (Kimi) 9b40a3a083 fix(ci): remove continue-on-error from block-internal-paths gate (fail-open → fail-closed)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 10s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 12s
E2E Chat / detect-changes (pull_request) Successful in 13s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
qa-review / approved (pull_request_target) Failing after 5s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Platform (Go) (pull_request) Successful in 6s
security-review / approved (pull_request_target) Failing after 11s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
gate-check-v3 / gate-check (pull_request_target) Successful in 13s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 7s
CI / Canvas Deploy Status (pull_request) Has been skipped
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
CI / all-required (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 8s
E2E Chat / E2E Chat (pull_request) Successful in 7s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m2s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m4s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m17s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m13s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m17s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 3s
sop-tier-check / tier-check (pull_request_target) Failing after 4s
audit-force-merge / audit (pull_request_target) Successful in 5s
2026-06-06 20:25:09 +00:00
Molecule AI Dev Engineer A (Kimi) 07e3cefd67 backends.md: mark drift risk #6 resolved and contract tests running
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 9s
E2E API Smoke Test / detect-changes (pull_request) Successful in 12s
E2E Chat / detect-changes (pull_request) Successful in 12s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 10s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
qa-review / approved (pull_request_target) Failing after 6s
CI / Platform (Go) (pull_request) Successful in 2s
security-review / approved (pull_request_target) Failing after 5s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
gate-check-v3 / gate-check (pull_request_target) Failing after 16s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 9s
CI / Canvas (Next.js) (pull_request) Successful in 10s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 8s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 3s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m14s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 5s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-tier-check / tier-check (pull_request_target) Successful in 6s
sop-checklist / all-items-acked (pull_request_target) Successful in 6s
audit-force-merge / audit (pull_request_target) Successful in 7s
Nil-receiver guards are in place across Provisioner and CPProvisioner.
Contract tests (TestDockerBackend_Contract, TestCPProvisionerBackend_Contract,
TestZeroValuedBackends_NoPanic) execute in CI without t.Skip.

Fixes #2031

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 20:24:04 +00:00
devops-engineer 1eaad170df Merge PR #2044 via Gitea merge queue
ci-arm64-advisory / fast-checks (push) Waiting to run
Block internal-flavored paths / Block forbidden paths (push) Successful in 3s
CI / Python Lint & Test (push) Successful in 3s
E2E Chat / detect-changes (push) Successful in 7s
Harness Replays / detect-changes (push) Successful in 5s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 4s
E2E API Smoke Test / detect-changes (push) Successful in 11s
Handlers Postgres Integration / detect-changes (push) Successful in 9s
CI / Detect changes (push) Successful in 13s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 2s
Harness Replays / Harness Replays (push) Successful in 1s
CI / Canvas (Next.js) (push) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 8s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 9s
CI / Shellcheck (E2E scripts) (push) Successful in 5s
CI / Canvas Deploy Status (push) Successful in 3s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 15s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (push) Successful in 36s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 1m38s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (push) Has been skipped
E2E Chat / E2E Chat (push) Failing after 1m55s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 2m9s
publish-workspace-server-image / build-and-push (push) Successful in 3m7s
CI / Platform (Go) (push) Successful in 4m0s
CI / all-required (push) Successful in 3s
publish-workspace-server-image / Production auto-deploy (push) Successful in 3m16s
E2E Staging External Runtime / E2E Staging External Runtime (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 20:22:25 +00:00
devops-engineer 1187d072da Merge PR #2030 via Gitea merge queue
ci-arm64-advisory / fast-checks (push) Waiting to run
Block internal-flavored paths / Block forbidden paths (push) Successful in 3s
CI / Python Lint & Test (push) Successful in 7s
CI / Detect changes (push) Successful in 9s
E2E Chat / detect-changes (push) Successful in 7s
E2E API Smoke Test / detect-changes (push) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 8s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 4s
Handlers Postgres Integration / detect-changes (push) Successful in 8s
Harness Replays / detect-changes (push) Successful in 9s
CI / Canvas (Next.js) (push) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 8s
Harness Replays / Harness Replays (push) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 2s
CI / Canvas Deploy Status (push) Successful in 1s
CI / Shellcheck (E2E scripts) (push) Successful in 5s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 9s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 16s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m7s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2m10s
publish-workspace-server-image / build-and-push (push) Successful in 3m18s
E2E Chat / E2E Chat (push) Failing after 3m33s
CI / Platform (Go) (push) Successful in 6m27s
CI / all-required (push) Successful in 1s
publish-workspace-server-image / Production auto-deploy (push) Successful in 5m37s
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 20:12:32 +00:00
devops-engineer 6d2b49941f Merge PR #2232 via Gitea merge queue
CI / Python Lint & Test (push) Successful in 3s
Block internal-flavored paths / Block forbidden paths (push) Successful in 6s
E2E API Smoke Test / detect-changes (push) Successful in 6s
E2E Chat / detect-changes (push) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 5s
CI / Detect changes (push) Successful in 12s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 7s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 3s
Handlers Postgres Integration / detect-changes (push) Successful in 9s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 8s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 9s
CI / Platform (Go) (push) Successful in 2s
E2E Chat / E2E Chat (push) Successful in 6s
CI / Shellcheck (E2E scripts) (push) Successful in 3s
CI / Canvas (Next.js) (push) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 4s
CI / Canvas Deploy Status (push) Successful in 1s
CI / all-required (push) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 16s
Ops Scripts Tests / Ops scripts (unittest) (push) Successful in 1m1s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m4s
publish-workspace-server-image / build-and-push (push) Successful in 3m23s
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m40s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 20:08:24 +00:00
Molecule AI Dev Engineer A (Kimi) 6797767998 fix(e2e): fail on JSON-RPC error in boot-to-registration completion check (#2299)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Detect changes (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 3s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
CI / Platform (Go) (pull_request) Successful in 3s
CI / Python Lint & Test (pull_request) Successful in 18s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 20s
CI / Canvas (Next.js) (pull_request) Successful in 3s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 18s
E2E Chat / detect-changes (pull_request) Successful in 20s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 6s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 18s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 15s
gate-check-v3 / gate-check (pull_request_target) Failing after 11s
qa-review / approved (pull_request_target) Failing after 5s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
security-review / approved (pull_request_target) Failing after 3s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 23s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 11s
E2E Chat / E2E Chat (pull_request) Successful in 4s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
sop-tier-check / tier-check (pull_request_target) Failing after 6s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m8s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m14s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m14s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m23s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m47s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m57s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 7s
audit-force-merge / audit (pull_request_target) Successful in 5s
Line 281: remove .error fallback from RPC_RESULT jq extract.
Previously, a JSON-RPC error response would fall through to .error,
produce a non-empty RPC_RESULT, and falsely report COMPLETION_STATUS=ok.

Now we explicitly check .error first and exit with code 5, then check
.result for null/empty. Narrow diff, no behavior change on success path.
2026-06-06 20:01:18 +00:00
devops-engineer b804d16b47 Merge PR #2047 via Gitea merge queue
ci-arm64-advisory / fast-checks (push) Waiting to run
Block internal-flavored paths / Block forbidden paths (push) Successful in 4s
CI / Python Lint & Test (push) Successful in 6s
CI / Detect changes (push) Successful in 6s
E2E API Smoke Test / detect-changes (push) Successful in 6s
E2E Chat / detect-changes (push) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 4s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 6s
Handlers Postgres Integration / detect-changes (push) Successful in 8s
CI / Shellcheck (E2E scripts) (push) Successful in 1s
Harness Replays / detect-changes (push) Successful in 8s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 8s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 2s
CI / Canvas (Next.js) (push) Successful in 5s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 3s
Harness Replays / Harness Replays (push) Successful in 2s
CI / Canvas Deploy Status (push) Successful in 1s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 15s
publish-workspace-server-image / build-and-push (push) Failing after 41s
publish-workspace-server-image / Production auto-deploy (push) Has been skipped
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 1m2s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m16s
E2E Chat / E2E Chat (push) Failing after 3m59s
CI / Platform (Go) (push) Successful in 4m10s
CI / all-required (push) Successful in 4s
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
2026-06-06 19:59:16 +00:00
Molecule AI Dev Engineer A (Kimi) e2e4e49685 fix(e2e): wire admin bearer token into chat-seed workspace creation
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 8s
Harness Replays / detect-changes (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
Harness Replays / Harness Replays (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 16s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 16s
E2E Chat / detect-changes (pull_request) Successful in 18s
E2E API Smoke Test / detect-changes (pull_request) Successful in 19s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Successful in 7s
qa-review / approved (pull_request_target) Failing after 5s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 16s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
sop-tier-check / tier-check (pull_request_target) Failing after 6s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
security-review / approved (pull_request_target) Failing after 10s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6s
E2E Chat / E2E Chat (pull_request) Successful in 7s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m2s
CI / Canvas (Next.js) (pull_request) Successful in 7m52s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 3s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 6s
audit-force-merge / audit (pull_request_target) Successful in 4s
POST /workspaces in seedWorkspace now carries the same admin cred
(E2E_ADMIN_TOKEN || ADMIN_TOKEN) that mintWorkspaceToken uses.
Aligns chat fixture with PR #2291 fail-closed auth; unauthenticated
create no longer silently 401s in E2E runs.

Narrow diff — no AdminAuth loosening.
2026-06-06 19:56:25 +00:00
devops-engineer e0b6939e11 Merge branch 'main' into fix/goroutine-panic-recovery
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
CI / Detect changes (pull_request) Successful in 15s
E2E Chat / detect-changes (pull_request) Successful in 14s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
Harness Replays / detect-changes (pull_request) Successful in 5s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 9s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 10s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 17s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 9s
sop-checklist / review-refire (pull_request_target) Has been skipped
security-review / approved (pull_request_target) Failing after 6s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
gate-check-v3 / gate-check (pull_request_target) Successful in 13s
qa-review / approved (pull_request_target) Failing after 11s
CI / Canvas (Next.js) (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 3s
sop-checklist / all-items-acked (pull_request_target) Successful in 13s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 6s
Harness Replays / Harness Replays (pull_request) Successful in 6s
sop-tier-check / tier-check (pull_request_target) Failing after 12s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Successful in 39s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 13s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 59s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m5s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2m31s
CI / Platform (Go) (pull_request) Successful in 4m9s
CI / all-required (pull_request) Successful in 2s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 10s
audit-force-merge / audit (pull_request_target) Successful in 4s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Has been cancelled
2026-06-06 19:53:35 +00:00
devops-engineer 45dcc665d3 Merge pull request 'merge-queue: direct-merge conflict-free PRs without update-churn (#2358)' (#2374) from fix/merge-queue-direct-merge-no-update-churn into main
Block internal-flavored paths / Block forbidden paths (push) Successful in 6s
CI / Python Lint & Test (push) Successful in 7s
CI / Detect changes (push) Successful in 12s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 10s
Handlers Postgres Integration / detect-changes (push) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (push) Successful in 5s
E2E Chat / detect-changes (push) Successful in 15s
E2E API Smoke Test / detect-changes (push) Successful in 16s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 11s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Successful in 15s
CI / Platform (Go) (push) Successful in 2s
CI / Canvas (Next.js) (push) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 4s
CI / Shellcheck (E2E scripts) (push) Successful in 4s
CI / all-required (push) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 3s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 2s
CI / Canvas Deploy Status (push) Successful in 1s
E2E Chat / E2E Chat (push) Successful in 17s
Ops Scripts Tests / Ops scripts (unittest) (push) Successful in 1m20s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 1m23s
publish-workspace-server-image / build-and-push (push) Successful in 3m25s
publish-workspace-server-image / Production auto-deploy (push) Successful in 2m25s
ci-arm64-advisory / fast-checks (push) Compensated by status-reaper (push run was cancelled/superseded; Gitea 1.22.6 reports cancelled runs as failure statuses)
merge-direct churn-fix (tri-state mergeable=None waits) — 2 genuine officials, required-green, mergeable. Eliminates rebase-churn = durable max throughput. CTO diff-reviewed.
2026-06-06 19:51:59 +00:00
Molecule AI Dev Engineer A (Kimi) 1c6f094306 fix(docs): correct comment typo in org_helpers.go (#1080)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 9s
E2E API Smoke Test / detect-changes (pull_request) Successful in 10s
E2E Chat / detect-changes (pull_request) Successful in 11s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 11s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 15s
Harness Replays / detect-changes (pull_request) Successful in 11s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 4s
CI / Canvas (Next.js) (pull_request) Successful in 5s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
E2E Chat / E2E Chat (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
sop-checklist / review-refire (pull_request_target) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Successful in 9s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
qa-review / approved (pull_request_target) Failing after 11s
sop-checklist / na-declarations (pull_request) N/A: (none)
security-review / approved (pull_request_target) Failing after 11s
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
CI / Canvas Deploy Status (pull_request) Has been skipped
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
Harness Replays / Harness Replays (pull_request) Successful in 11s
sop-tier-check / tier-check (pull_request_target) Failing after 18s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m3s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m22s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m42s
CI / Platform (Go) (pull_request) Successful in 4m23s
CI / all-required (pull_request) Successful in 6s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 7s
audit-force-merge / audit (pull_request_target) Successful in 10s
Change comment to end with '.env files.' instead of trailing '.env'.
No functional change.
2026-06-06 19:50:38 +00:00
devops-engineer e8d7d8986d Merge branch 'main' into fix/umbrella-reaper-1780
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
CI / Python Lint & Test (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 6s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 10s
E2E Chat / detect-changes (pull_request) Successful in 11s
CI / Canvas (Next.js) (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 8s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 5s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 4s
CI / Platform (Go) (pull_request) Successful in 6s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 5s
E2E Chat / E2E Chat (pull_request) Successful in 3s
CI / all-required (pull_request) Successful in 5s
CI / Canvas Deploy Status (pull_request) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Failing after 9s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
security-review / approved (pull_request_target) Failing after 5s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 7/7
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 17s
sop-tier-check / tier-check (pull_request_target) Failing after 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 25s
qa-review / approved (pull_request_target) Failing after 22s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m1s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m10s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m9s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m36s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m42s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m36s
2026-06-06 19:29:00 +00:00
Molecule AI Dev Engineer A (Kimi) 9c47108e02 fix(ci-drift): paginate open issues to prevent duplicate [ci-drift] issues
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Detect changes (pull_request) Successful in 5s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
CI / Python Lint & Test (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 5s
E2E Chat / detect-changes (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
Handlers Postgres Integration / detect-changes (pull_request) Successful in 7s
CI / Platform (Go) (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 8s
gate-check-v3 / gate-check (pull_request_target) Successful in 6s
CI / Canvas (Next.js) (pull_request) Successful in 2s
qa-review / approved (pull_request_target) Failing after 5s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
CI / Canvas Deploy Status (pull_request) Has been skipped
sop-tier-check / tier-check (pull_request_target) Failing after 7s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
security-review / approved (pull_request_target) Failing after 18s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 21s
sop-checklist / all-items-acked (pull_request_target) Successful in 19s
CI / all-required (pull_request) Successful in 10s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 17s
E2E Chat / E2E Chat (pull_request) Successful in 16s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m0s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m22s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 11s
audit-force-merge / audit (pull_request_target) Successful in 7s
The find_open_issue() helper only fetched one page of open issues
(limit=50). When the existing [ci-drift] tracking issue fell beyond
page 1, the caller POSTed a duplicate instead of updating the existing
one.

Fix: loop over pages until the title is found or the result set is
exhausted (page returns <50 items). API errors propagate loud via
ApiError as before.

Adds two regression tests:
- test_find_open_issue_paginates_to_page_2
- test_find_open_issue_stops_at_last_page

Fixes issue-403.
2026-06-06 18:44:10 +00:00
devops-engineer c90b44fc47 merge-queue: fail-closed WAIT (not update) on mergeable=None compute window (#2374 CR2)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
E2E Chat / detect-changes (pull_request) Successful in 9s
sop-checklist / review-refire (pull_request_target) Has been skipped
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 9s
E2E API Smoke Test / detect-changes (pull_request) Successful in 12s
CI / Platform (Go) (pull_request) Successful in 2s
qa-review / approved (pull_request_target) Failing after 6s
security-review / approved (pull_request_target) Failing after 6s
CI / Canvas (Next.js) (pull_request) Successful in 2s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
CI / Canvas Deploy Status (pull_request) Has been skipped
Handlers Postgres Integration / detect-changes (pull_request) Successful in 14s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 14s
E2E Chat / E2E Chat (pull_request) Successful in 2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1s
gate-check-v3 / gate-check (pull_request_target) Failing after 10s
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 5s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 3s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
CI / all-required (pull_request) Successful in 1s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m2s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m0s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 6s
audit-force-merge / audit (pull_request_target) Successful in 6s
Addresses CR2's REQUEST_CHANGES on #2374: a residual approval-dismissing
churn path remained in the NON-mergeable branch. The call site collapsed
mergeable None/missing/False all to a single boolean False, and the
update-decision returns action=update whenever the PR is behind main. So a
behind-main PR while Gitea is STILL COMPUTING mergeability (mergeable=None)
hit /pulls/{n}/update -> dismiss_stale_approvals -> the exact rebase-churn
this PR eliminates, fired during the compute window.

Fix: make the None-vs-False distinction explicit (tri-state), do not collapse.
  - mergeable is True   -> direct-merge (unchanged, this PR's fix).
  - mergeable is None   -> WAIT: never update, never merge, never dismiss
                           approvals; re-check next tick once Gitea computes.
  - mergeable is False  -> definitive conflict -> existing update/hold path
                           (409-on-update holds+advances per #2352).

Merge bar and all #2352/#2356 behavior preserved. The prior None regression
test passed only because its fixture had current base, masking the behind-main
case; new tests exercise behind-main + None directly (proven to fail against
the old collapse). pytest 65 green (62 + 3 new §SOP-22).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 11:42:14 -07:00
devops-engineer a89e2680c9 merge-queue: direct-merge conflict-free PRs without update-churn (#2358)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 19s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 11s
CI / Python Lint & Test (pull_request) Successful in 7s
CI / Detect changes (pull_request) Successful in 18s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Has started running
E2E API Smoke Test / detect-changes (pull_request) Successful in 18s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 20s
qa-review / approved (pull_request_target) Has started running
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 15s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 28s
gate-check-v3 / gate-check (pull_request_target) Successful in 33s
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E Chat / detect-changes (pull_request) Successful in 1m6s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 1m5s
sop-tier-check / tier-check (pull_request_target) Failing after 13s
CI / Platform (Go) (pull_request) Successful in 3s
security-review / approved (pull_request_target) Failing after 38s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 7s
CI / Canvas (Next.js) (pull_request) Successful in 10s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m6s
E2E Chat / E2E Chat (pull_request) Successful in 4s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 9s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 13s
CI / all-required (pull_request) Successful in 8s
CI / Canvas Deploy Status (pull_request) Has been skipped
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 8s
lint-required-no-paths / lint-required-no-paths (pull_request) Has been cancelled
sop-checklist / all-items-acked (pull_request_target) Has been cancelled
The merge-queue cron called /pulls/N/update on any PR whose head did not
contain current main, BEFORE merging. Gitea's dismiss_stale_approvals then
dismissed the PR's 2 genuine approvals on update, dropping it to 0-genuine
and forcing a full re-review every tick. With ~51 mergeable PRs open this
collapsed throughput to ~0/hr.

Branch protection does NOT require strict up-to-date (behind-main PRs merge
directly), so the update-before-merge was unnecessary churn.

Fix (targeted, in evaluate_merge_readiness):
- When the PR is conflict-free (mergeable is True) and the merge bar is met
  (main green + >=required genuine approvals on current head + no open
  REQUEST_CHANGES + every BP-required context green), MERGE IT DIRECTLY —
  even if behind main. No /update first → approvals are NOT dismissed → no
  re-review churn.
- The /update path is now reached ONLY when the PR is NOT mergeable
  (mergeable False/None) AND its head lacks current main. A real conflict
  still 409s on update and is HELD per #2352 (no regression). A current-base
  not-mergeable PR WAITs. mergeable=None stays fail-closed (never merged).

The merge bar is UNCHANGED. Safety backstop: step 1 (main required push
contexts green) PAUSES the queue when main is red, so after a direct merge
a semantic main-break caught by post-merge main CI stops the next merge
(serialized safety) — this is what makes pre-merge-update-free safe.

Tests (§SOP-22): conflict-free PR merges WITHOUT update_pull (assert update
not invoked, merge invoked); behind-main conflict-free merges directly;
not-mergeable behind-main still updates; not-mergeable current-base waits;
409-on-update fixture switched to mergeable=False (real conflict) and still
holds per #2352; merge bar still rejects <2 genuine / red required / RC on
the new direct path; pause-when-main-red backstop. 62 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 11:25:55 -07:00
core-devops 1c42488be7 feat(workspace-server): install platform agent as org root (Phase 1)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Blocked by required conditions
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Blocked by required conditions
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
Harness Replays / detect-changes (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 15s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
gate-check-v3 / gate-check (pull_request_target) Successful in 7s
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E API Smoke Test / detect-changes (pull_request) Successful in 18s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
E2E Chat / detect-changes (pull_request) Successful in 17s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
CI / Canvas (Next.js) (pull_request) Successful in 2s
sop-tier-check / tier-check (pull_request_target) Failing after 7s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
qa-review / approved (pull_request_target) Failing after 13s
security-review / approved (pull_request_target) Failing after 12s
CI / Canvas Deploy Status (pull_request) Has been skipped
Harness Replays / Harness Replays (pull_request) Successful in 12s
E2E Chat / E2E Chat (pull_request) Successful in 3s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m0s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 57s
CI / Platform (Go) (pull_request) Successful in 9m5s
CI / all-required (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 6s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m6s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 10s
audit-force-merge / audit (pull_request_target) Successful in 19s
Add the idempotent, transactional operation that makes the org-level concierge
the org root (RFC docs/design/rfc-platform-agent.md): POST /admin/org/platform-agent
(AdminAuth) + installPlatformAgent().

In ONE transaction it:
  1. upserts the platform-agent row (kind='platform', parent_id NULL, tier 0)
     via ON CONFLICT (id) DO UPDATE;
  2. re-parents the org's existing root(s) under it;
  3. moves the org-anchor references that key off the root workspace id —
     org_api_tokens.org_id and org_plugin_allowlist.org_id — from each old root
     to the platform agent, so a tenant's admin tokens + plugin allowlist never
     point at a stale anchor.

Routing is UNCHANGED: once the platform agent is the root, the existing
ancestor/descendant rules in registry/access.go give it universal in-org reach
and org_scope.go keeps tenant isolation intact.

The CP calls this at org-provision (new orgs, clean) and during the existing-org
backfill rollout. Idempotent: a second call is a no-op.

Tests: handler bad-input unit test; real-Postgres integration test proving the
re-parent + both anchor migrations + orgRootID/sameOrg resolution + idempotency
(sqlmock cannot evaluate the post-tx row state). Allowlisted in the
workspaces-INSERT bulk-create regression guard with its ON CONFLICT safety note.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 11:25:28 -07:00
devops-engineer b43a6a76bc Merge branch 'main' into fix/audit-force-merge-curl-fail-closed
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 8s
E2E Chat / detect-changes (pull_request) Successful in 9s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 9s
E2E API Smoke Test / detect-changes (pull_request) Successful in 17s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 16s
qa-review / approved (pull_request_target) Failing after 8s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 15s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 12s
security-review / approved (pull_request_target) Failing after 7s
gate-check-v3 / gate-check (pull_request_target) Successful in 11s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m3s
CI / Platform (Go) (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 3s
CI / Canvas (Next.js) (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m27s
E2E Chat / E2E Chat (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
CI / all-required (pull_request) Successful in 21s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 20s
CI / Canvas Deploy Status (pull_request) Has been skipped
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 20s
sop-checklist / review-refire (pull_request_target) Has been skipped
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
sop-tier-check / tier-check (pull_request_target) Successful in 13s
audit-force-merge / audit (pull_request_target) Successful in 5s
2026-06-06 18:15:59 +00:00
devops-engineer ddd15565fb Merge branch 'main' into fix/fail-closed-hardening-trio
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 8s
CI / Python Lint & Test (pull_request) Successful in 10s
E2E API Smoke Test / detect-changes (pull_request) Successful in 16s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 18s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 9s
E2E Chat / detect-changes (pull_request) Successful in 39s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 35s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 20s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 6s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
CI / all-required (pull_request) Successful in 21s
gate-check-v3 / gate-check (pull_request_target) Successful in 11s
qa-review / approved (pull_request_target) Failing after 9s
security-review / approved (pull_request_target) Failing after 8s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m25s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m6s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 2m5s
CI / Canvas Deploy Status (pull_request) Has been skipped
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 8s
sop-checklist / review-refire (pull_request_target) Has been skipped
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 10s
sop-tier-check / tier-check (pull_request_target) Successful in 15s
audit-force-merge / audit (pull_request_target) Successful in 7s
2026-06-06 18:14:48 +00:00
devops-engineer 2ea187fc2f Merge branch 'main' into fix/internal-805-sweep-cf-cloudflare-fallback-clean
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
CI / Detect changes (pull_request) Successful in 33s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 1m13s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 59s
E2E Chat / detect-changes (pull_request) Successful in 57s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
security-review / approved (pull_request_target) Failing after 5s
sop-checklist / review-refire (pull_request_target) Has been skipped
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
CI / Platform (Go) (pull_request) Successful in 1s
sop-tier-check / tier-check (pull_request_target) Failing after 4s
CI / Canvas (Next.js) (pull_request) Successful in 1s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 13s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
qa-review / approved (pull_request_target) Failing after 35s
gate-check-v3 / gate-check (pull_request_target) Successful in 35s
CI / all-required (pull_request) Successful in 5s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 5s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Chat / E2E Chat (pull_request) Successful in 3s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m13s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m12s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m25s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m26s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m37s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m37s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 5s
audit-force-merge / audit (pull_request_target) Successful in 11s
2026-06-06 17:45:51 +00:00
devops-engineer 10556b1ba1 Merge branch 'main' into fix/main-red-2305-lint-and-e2e-platform-managed
security-review / approved (pull_request_review) Has been skipped
qa-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 17s
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 13s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 8s
E2E Chat / detect-changes (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 14s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 8s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 7s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 5s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Successful in 32s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 3s
gate-check-v3 / gate-check (pull_request_target) Successful in 7s
qa-review / approved (pull_request_target) Successful in 5s
sop-checklist / review-refire (pull_request_target) Has been skipped
security-review / approved (pull_request_target) Successful in 4s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
sop-tier-check / tier-check (pull_request_target) Successful in 7s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 4s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m0s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m1s
E2E Chat / E2E Chat (pull_request) Successful in 6s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 14s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m20s
CI / all-required (pull_request) Successful in 2s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m39s
CI / Canvas Deploy Status (pull_request) Has been skipped
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m40s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 57s
audit-force-merge / audit (pull_request_target) Successful in 5s
2026-06-06 17:40:39 +00:00
devops-engineer f2d1a5253c Merge branch 'main' into fix/main-red-e2e-chat-auth-token
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 2s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 10s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 12s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 9s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 17s
E2E Chat / detect-changes (pull_request) Successful in 20s
CI / Detect changes (pull_request) Successful in 24s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 10s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 13s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
sop-checklist / review-refire (pull_request_target) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 8s
gate-check-v3 / gate-check (pull_request_target) Successful in 9s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
security-review / approved (pull_request_target) Failing after 12s
qa-review / approved (pull_request_target) Failing after 13s
sop-checklist / all-items-acked (pull_request_target) Successful in 11s
E2E Chat / E2E Chat (pull_request) Successful in 7s
sop-tier-check / tier-check (pull_request_target) Failing after 11s
CI / Platform (Go) (pull_request) Successful in 6s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 4s
CI / Canvas (Next.js) (pull_request) Successful in 4s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 56s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m3s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m12s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m4s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m16s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 6s
audit-force-merge / audit (pull_request_target) Successful in 4s
2026-06-06 17:35:42 +00:00
devops-engineer 7002ee7520 Merge branch 'main' into fix/internal-802-bp-directive-comments
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 11s
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 9s
CI / Detect changes (pull_request) Successful in 7s
CI / Python Lint & Test (pull_request) Successful in 8s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
E2E Chat / detect-changes (pull_request) Successful in 9s
CI / Platform (Go) (pull_request) Successful in 2s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 15s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 16s
E2E Chat / E2E Chat (pull_request) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 11s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 3s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 10s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 8s
gate-check-v3 / gate-check (pull_request_target) Successful in 10s
sop-checklist / review-refire (pull_request_target) Has been skipped
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
security-review / approved (pull_request_target) Successful in 5s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 13s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
sop-tier-check / tier-check (pull_request_target) Successful in 6s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 19s
qa-review / approved (pull_request_target) Successful in 26s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 58s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m18s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m13s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m28s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m36s
audit-force-merge / audit (pull_request_target) Successful in 8s
2026-06-06 17:30:46 +00:00
devops-engineer 6858bd2771 Merge branch 'main' into cp455-minimal-cell-boot-e2e-stage1
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 5s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 10s
CI / Canvas (Next.js) (pull_request) Successful in 2s
E2E Chat / detect-changes (pull_request) Successful in 14s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 13s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 5s
CI / Platform (Go) (pull_request) Successful in 7s
gate-check-v3 / gate-check (pull_request_target) Successful in 6s
security-review / approved (pull_request_target) Failing after 5s
CI / Canvas Deploy Status (pull_request) Has been skipped
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 17s
E2E Chat / E2E Chat (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
sop-checklist / review-refire (pull_request_target) Has been skipped
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 20s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 23s
qa-review / approved (pull_request_target) Failing after 17s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
CI / all-required (pull_request) Successful in 2s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m6s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m15s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m17s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m45s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m59s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m13s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 13s
2026-06-06 17:25:29 +00:00
devops-engineer aa5d1ef883 Merge branch 'main' into fix/reconciler-debounce-coupling-2284
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
CI / Detect changes (pull_request) Successful in 8s
E2E Chat / detect-changes (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 17s
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (staging) (pull_request) Has been skipped
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 13s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 19s
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (compile+skip) (pull_request) Successful in 31s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
gate-check-v3 / gate-check (pull_request_target) Successful in 3s
qa-review / approved (pull_request_target) Failing after 3s
security-review / approved (pull_request_target) Failing after 3s
E2E Chat / E2E Chat (pull_request) Successful in 3s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
CI / Canvas Deploy Status (pull_request) Has been skipped
Handlers Postgres Integration / detect-changes (pull_request) Successful in 1m17s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
Harness Replays / detect-changes (pull_request) Successful in 1m17s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 56s
Harness Replays / Harness Replays (pull_request) Successful in 35s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m0s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m16s
CI / Platform (Go) (pull_request) Successful in 4m16s
CI / all-required (pull_request) Successful in 4s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Has been cancelled
security-review / approved (pull_request_review) Has been skipped
qa-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 5s
audit-force-merge / audit (pull_request_target) Successful in 3s
2026-06-06 17:20:30 +00:00
devops-engineer 85dc777b78 Merge branch 'main' into fix/main-red-canvas-e2e-tablist-strict-mode
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 7s
CI / Detect changes (pull_request) Successful in 8s
E2E Chat / detect-changes (pull_request) Successful in 10s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 6s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 9s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E API Smoke Test / detect-changes (pull_request) Successful in 14s
CI / Platform (Go) (pull_request) Successful in 8s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 15s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
qa-review / approved (pull_request_target) Failing after 5s
Harness Replays / detect-changes (pull_request) Successful in 14s
sop-checklist / review-refire (pull_request_target) Has been skipped
security-review / approved (pull_request_target) Failing after 5s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
E2E Chat / E2E Chat (pull_request) Successful in 7s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 7s
sop-checklist / all-items-acked (pull_request_target) Successful in 6s
gate-check-v3 / gate-check (pull_request_target) Successful in 11s
Harness Replays / Harness Replays (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 5s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 55s
CI / Canvas (Next.js) (pull_request) Successful in 6m27s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 43s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 20s
audit-force-merge / audit (pull_request_target) Successful in 5s
2026-06-06 17:15:31 +00:00
devops-engineer d5e254f431 Merge branch 'main' into fix/canvas-pause-resume-cascade-param-2122-followup
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 9s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
CI / Platform (Go) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 11s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 13s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 15s
E2E Chat / detect-changes (pull_request) Successful in 18s
Harness Replays / detect-changes (pull_request) Successful in 15s
qa-review / approved (pull_request_target) Failing after 6s
gate-check-v3 / gate-check (pull_request_target) Successful in 7s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 9s
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 6s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 13s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
security-review / approved (pull_request_target) Failing after 10s
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
E2E Chat / E2E Chat (pull_request) Successful in 7s
Harness Replays / Harness Replays (pull_request) Successful in 4s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
sop-tier-check / tier-check (pull_request_target) Failing after 7s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 59s
CI / Canvas (Next.js) (pull_request) Successful in 6m30s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 20s
audit-force-merge / audit (pull_request_target) Successful in 4s
2026-06-06 17:05:43 +00:00
devops-engineer 3bf1ab18e1 Merge branch 'main' into fix/2251-delegate-task-message-role-contract-test
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 4s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
E2E Chat / detect-changes (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 13s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 12s
E2E Chat / E2E Chat (pull_request) Successful in 3s
sop-checklist / review-refire (pull_request_target) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Successful in 6s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
security-review / approved (pull_request_target) Failing after 6s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
sop-tier-check / tier-check (pull_request_target) Failing after 6s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
Harness Replays / Harness Replays (pull_request) Successful in 12s
qa-review / approved (pull_request_target) Failing after 15s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m5s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m13s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m51s
CI / Platform (Go) (pull_request) Successful in 6m12s
CI / Canvas (Next.js) (pull_request) Successful in 6m23s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 2s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 4s
audit-force-merge / audit (pull_request_target) Successful in 4s
2026-06-06 17:00:31 +00:00
devops-engineer 51c2d4d402 Merge branch 'main' into fix/817-canvas-deploy-reminder-per-step-gate
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 7s
E2E Chat / detect-changes (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
CI / Platform (Go) (pull_request) Successful in 3s
CI / Canvas (Next.js) (pull_request) Successful in 2s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 13s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 11s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 13s
E2E API Smoke Test / detect-changes (pull_request) Successful in 15s
E2E Chat / E2E Chat (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 5s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 4s
CI / Canvas Deploy Status (pull_request) Successful in 4s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
qa-review / approved (pull_request_target) Failing after 7s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 13s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 15s
gate-check-v3 / gate-check (pull_request_target) Successful in 14s
security-review / approved (pull_request_target) Failing after 13s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
CI / all-required (pull_request) Successful in 8s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 14s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 56s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m0s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m16s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m13s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Successful in 1m25s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m26s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 17s
audit-force-merge / audit (pull_request_target) Successful in 5s
2026-06-06 16:50:28 +00:00
devops-engineer b4a3553534 Merge branch 'main' into fix/2139-sop-tier-check-real-qa-security-teams
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 7s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 8s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 8s
CI / Detect changes (pull_request) Successful in 11s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 10s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 10s
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E Chat / detect-changes (pull_request) Successful in 13s
qa-review / approved (pull_request_target) Failing after 7s
security-review / approved (pull_request_target) Failing after 7s
gate-check-v3 / gate-check (pull_request_target) Successful in 9s
CI / Canvas (Next.js) (pull_request) Successful in 2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 7s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Chat / E2E Chat (pull_request) Successful in 2s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-tier-check / tier-check (pull_request_target) Failing after 5s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 7s
sop-checklist / all-items-acked (pull_request_target) Successful in 8s
CI / Platform (Go) (pull_request) Successful in 8s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 9s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
CI / all-required (pull_request) Successful in 2s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m5s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m7s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 7s
audit-force-merge / audit (pull_request_target) Successful in 7s
2026-06-06 16:45:27 +00:00
devops-engineer 7ccd59e630 Merge branch 'main' into fix/plugin-uninstall-exec-errors
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Harness Replays / Harness Replays (pull_request) Successful in 2s
E2E Chat / detect-changes (pull_request) Successful in 13s
CI / Detect changes (pull_request) Successful in 14s
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 14s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
qa-review / approved (pull_request_target) Failing after 7s
E2E Chat / E2E Chat (pull_request) Successful in 3s
gate-check-v3 / gate-check (pull_request_target) Successful in 10s
sop-checklist / all-items-acked (pull_request_target) Successful in 7s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 12s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 6s
security-review / approved (pull_request_target) Failing after 11s
CI / Canvas Deploy Status (pull_request) Has been skipped
sop-tier-check / tier-check (pull_request_target) Failing after 16s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 58s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m7s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m15s
CI / Platform (Go) (pull_request) Successful in 6m36s
CI / all-required (pull_request) Successful in 3s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 7s
audit-force-merge / audit (pull_request_target) Successful in 5s
2026-06-06 16:15:21 +00:00
devops-engineer a2d9549de2 Merge branch 'main' into fix/goroutine-panic-recovery
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
CI / Python Lint & Test (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 8s
E2E Chat / detect-changes (pull_request) Successful in 8s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 12s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
E2E Chat / E2E Chat (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 13s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 11s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 12s
qa-review / approved (pull_request_target) Failing after 8s
sop-checklist / review-refire (pull_request_target) Has been skipped
CI / Canvas (Next.js) (pull_request) Successful in 6s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
sop-checklist / all-items-acked (pull_request_target) Successful in 6s
CI / Canvas Deploy Status (pull_request) Has been skipped
Harness Replays / Harness Replays (pull_request) Successful in 1s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 11s
gate-check-v3 / gate-check (pull_request_target) Successful in 19s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Successful in 33s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 4s
security-review / approved (pull_request_target) Failing after 18s
sop-tier-check / tier-check (pull_request_target) Failing after 14s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m38s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2m10s
CI / Platform (Go) (pull_request) Successful in 3m54s
CI / all-required (pull_request) Successful in 2s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Has been cancelled
security-review / approved (pull_request_review) Has been skipped
qa-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 7s
2026-06-06 16:10:27 +00:00
devops-engineer 07d5649f02 Merge branch 'main' into fix/umbrella-reaper-1780
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 3s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
E2E Chat / detect-changes (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 7s
CI / Detect changes (pull_request) Successful in 13s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 10s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 10s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
E2E Chat / E2E Chat (pull_request) Successful in 11s
qa-review / approved (pull_request_target) Failing after 6s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 5s
CI / Platform (Go) (pull_request) Successful in 12s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 13s
sop-checklist / review-refire (pull_request_target) Has been skipped
CI / Canvas Deploy Status (pull_request) Has been skipped
security-review / approved (pull_request_target) Failing after 5s
gate-check-v3 / gate-check (pull_request_target) Failing after 18s
CI / all-required (pull_request) Successful in 4s
sop-checklist / all-items-acked (pull_request) acked: 7/7
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-tier-check / tier-check (pull_request_target) Failing after 10s
sop-checklist / all-items-acked (pull_request_target) Successful in 11s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 57s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m2s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 59s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m13s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m12s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m30s
2026-06-06 15:45:06 +00:00
devops-engineer cec1fd5ea7 Merge branch 'main' into fix/fail-closed-hardening-trio
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 3s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
E2E Chat / detect-changes (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
CI / Detect changes (pull_request) Successful in 12s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 8s
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 12s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 3s
qa-review / approved (pull_request_target) Successful in 5s
security-review / approved (pull_request_target) Successful in 5s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
gate-check-v3 / gate-check (pull_request_target) Successful in 13s
sop-checklist / na-declarations (pull_request) N/A: (none)
CI / Platform (Go) (pull_request) Successful in 7s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
sop-checklist / all-items-acked (pull_request_target) Successful in 10s
CI / all-required (pull_request) Successful in 1s
sop-tier-check / tier-check (pull_request_target) Failing after 13s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 55s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 57s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m13s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 6s
2026-06-06 15:30:43 +00:00
Molecule AI Dev Engineer A (Kimi) 2520801295 fix(audit-force-merge): verify statuses is an array, not just present (PR#2366 RC)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 10s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 8s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 10s
CI / Canvas (Next.js) (pull_request) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 11s
CI / Platform (Go) (pull_request) Successful in 2s
E2E Chat / detect-changes (pull_request) Successful in 14s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
sop-checklist / review-refire (pull_request_target) Has been skipped
qa-review / approved (pull_request_target) Failing after 8s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
gate-check-v3 / gate-check (pull_request_target) Failing after 10s
CI / Canvas Deploy Status (pull_request) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
sop-checklist / na-declarations (pull_request) N/A: (none)
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 5s
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
security-review / approved (pull_request_target) Failing after 11s
E2E Chat / E2E Chat (pull_request) Successful in 2s
CI / all-required (pull_request) Successful in 4s
sop-tier-check / tier-check (pull_request_target) Failing after 12s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m2s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m23s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 9s
The prior fix checked has('statuses') which returns true when the key
exists even if its value is null, a string, or an object. A malformed
API response could set statuses to any of those and we'd still try to
iterate it — potentially skipping checks or crashing.

Now we verify (.statuses | type) == 'array', which catches:
- missing key → null type → abort
- null value → null type → abort
- string/object value → wrong type → abort

Refs: molecule-core#2366, Researcher RC 9156.
2026-06-06 15:08:24 +00:00
devops-engineer 6d678d12d0 Merge branch 'main' into fix/internal-805-sweep-cf-cloudflare-fallback-clean
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
CI / Canvas (Next.js) (pull_request) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 4s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 13s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
CI / Canvas Deploy Status (pull_request) Has been skipped
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 22s
E2E Chat / detect-changes (pull_request) Successful in 27s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 26s
CI / Platform (Go) (pull_request) Successful in 19s
sop-checklist / review-refire (pull_request_target) Has been skipped
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 20s
gate-check-v3 / gate-check (pull_request_target) Successful in 7s
CI / all-required (pull_request) Successful in 5s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
qa-review / approved (pull_request_target) Successful in 14s
sop-checklist / all-items-acked (pull_request_target) Successful in 14s
security-review / approved (pull_request_target) Successful in 14s
sop-tier-check / tier-check (pull_request_target) Failing after 14s
E2E Chat / E2E Chat (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 13s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 56s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m4s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m14s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m17s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m3s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m29s
2026-06-06 15:00:41 +00:00
devops-engineer 0dcdc553dc Merge branch 'main' into fix/main-red-2305-lint-and-e2e-platform-managed
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 6s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 3s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 13s
E2E Chat / detect-changes (pull_request) Successful in 13s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
CI / Canvas (Next.js) (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 13s
CI / Platform (Go) (pull_request) Successful in 8s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 9s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 14s
qa-review / approved (pull_request_target) Successful in 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Chat / E2E Chat (pull_request) Successful in 11s
gate-check-v3 / gate-check (pull_request_target) Failing after 14s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Successful in 33s
sop-tier-check / tier-check (pull_request_target) Failing after 6s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 5s
CI / all-required (pull_request) Successful in 14s
security-review / approved (pull_request_target) Failing after 19s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 58s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m0s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m10s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m26s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m25s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m31s
2026-06-06 14:55:33 +00:00
devops-engineer 165a0f4450 Merge branch 'main' into fix/main-red-e2e-chat-auth-token
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 6s
CI / Python Lint & Test (pull_request) Successful in 6s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
E2E Chat / detect-changes (pull_request) Successful in 7s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 10s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 14s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 9s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 10s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
sop-checklist / review-refire (pull_request_target) Has been skipped
CI / all-required (pull_request) Successful in 8s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
security-review / approved (pull_request_target) Failing after 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-tier-check / tier-check (pull_request_target) Failing after 6s
gate-check-v3 / gate-check (pull_request_target) Successful in 24s
qa-review / approved (pull_request_target) Failing after 24s
sop-checklist / all-items-acked (pull_request_target) Successful in 21s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m1s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m2s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m23s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m15s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m35s
2026-06-06 14:50:29 +00:00
devops-engineer 8a1a799389 Merge branch 'main' into fix/internal-802-bp-directive-comments
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
E2E Chat / detect-changes (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
CI / Detect changes (pull_request) Successful in 10s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 9s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 4s
E2E Chat / E2E Chat (pull_request) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
CI / Canvas Deploy Status (pull_request) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Successful in 6s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
security-review / approved (pull_request_target) Failing after 4s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
CI / all-required (pull_request) Successful in 35s
qa-review / approved (pull_request_target) Successful in 40s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m17s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m38s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m43s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m47s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m47s
2026-06-06 14:45:29 +00:00
devops-engineer a1812b3846 Merge branch 'main' into cp455-minimal-cell-boot-e2e-stage1
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 5s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 9s
CI / Detect changes (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 8s
E2E API Smoke Test / detect-changes (pull_request) Successful in 15s
CI / Canvas (Next.js) (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 14s
CI / Platform (Go) (pull_request) Successful in 9s
E2E Chat / detect-changes (pull_request) Successful in 20s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 6s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 6s
CI / Canvas Deploy Status (pull_request) Has been skipped
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 9s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 16s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 6s
CI / all-required (pull_request) Successful in 7s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
E2E Chat / E2E Chat (pull_request) Successful in 7s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 8s
gate-check-v3 / gate-check (pull_request_target) Successful in 6s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Failing after 50s
qa-review / approved (pull_request_target) Successful in 12s
security-review / approved (pull_request_target) Failing after 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Failing after 46s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Failing after 1m2s
lint-required-no-paths / lint-required-no-paths (pull_request) Failing after 58s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m3s
sop-tier-check / tier-check (pull_request_target) Failing after 20s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m21s
2026-06-06 14:40:28 +00:00
devops-engineer c8f4d617a3 Merge branch 'main' into fix/reconciler-debounce-coupling-2284
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (staging) (pull_request) Has been skipped
CI / Detect changes (pull_request) Successful in 8s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E API Smoke Test / detect-changes (pull_request) Successful in 14s
E2E Chat / detect-changes (pull_request) Successful in 13s
Harness Replays / detect-changes (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 9s
CI / Canvas (Next.js) (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 5s
E2E Chat / E2E Chat (pull_request) Successful in 3s
Harness Replays / Harness Replays (pull_request) Successful in 3s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (compile+skip) (pull_request) Successful in 22s
sop-checklist / review-refire (pull_request_target) Has been skipped
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 6s
gate-check-v3 / gate-check (pull_request_target) Successful in 17s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 19s
qa-review / approved (pull_request_target) Successful in 16s
sop-tier-check / tier-check (pull_request_target) Failing after 6s
security-review / approved (pull_request_target) Failing after 17s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 58s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m5s
CI / Platform (Go) (pull_request) Successful in 6m30s
CI / all-required (pull_request) Successful in 1s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Has been cancelled
2026-06-06 14:35:45 +00:00
Molecule AI Dev Engineer A (Kimi) 4628b36324 fix(audit-force-merge): nested path validation for merged_by.login, base.ref, head.sha (PR#2366 RC)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
CI / Python Lint & Test (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 6s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 2s
gate-check-v3 / gate-check (pull_request_target) Failing after 6s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E API Smoke Test / detect-changes (pull_request) Successful in 15s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 13s
E2E Chat / detect-changes (pull_request) Successful in 14s
sop-checklist / review-refire (pull_request_target) Has been skipped
Handlers Postgres Integration / detect-changes (pull_request) Successful in 13s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 13s
CI / Canvas Deploy Status (pull_request) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
CI / all-required (pull_request) Successful in 2s
sop-checklist / na-declarations (pull_request) N/A: (none)
qa-review / approved (pull_request_target) Failing after 4s
security-review / approved (pull_request_target) Failing after 4s
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 5s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 5s
E2E Chat / E2E Chat (pull_request) Successful in 5s
sop-tier-check / tier-check (pull_request_target) Failing after 8s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 57s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m4s
security-review / approved (pull_request_review) Has been skipped
qa-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 17s
The prior fix used has('merged_by') which returns true when the key
exists even if its value is null. For bot merges or unknown mergers,
merged_by can be null, causing .merged_by.login to resolve to empty
string — still an anonymous audit trail.

Now we validate the FULL jq path (e.g. '.merged_by.login') with jq -e,
which returns false if ANY intermediate node is missing or null. This
catches nested nulls that top-level has() cannot see.

Same treatment for base.ref and head.sha.

Refs: molecule-core#2366, PM dispatch 2e76a0ef.
2026-06-06 14:34:02 +00:00
devops-engineer afd1f53f2e Merge branch 'main' into fix/main-red-canvas-e2e-tablist-strict-mode
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 5s
Harness Replays / detect-changes (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
CI / Platform (Go) (pull_request) Successful in 2s
Harness Replays / Harness Replays (pull_request) Successful in 1s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 12s
E2E API Smoke Test / detect-changes (pull_request) Successful in 14s
E2E Chat / detect-changes (pull_request) Successful in 13s
sop-checklist / review-refire (pull_request_target) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 6s
gate-check-v3 / gate-check (pull_request_target) Successful in 7s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
E2E Chat / E2E Chat (pull_request) Successful in 2s
qa-review / approved (pull_request_target) Successful in 5s
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 11s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 9s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 10s
security-review / approved (pull_request_target) Successful in 13s
sop-tier-check / tier-check (pull_request_target) Failing after 13s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m10s
CI / Canvas (Next.js) (pull_request) Successful in 6m16s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 3s
2026-06-06 14:30:33 +00:00
devops-engineer c88a6b6f58 Merge branch 'main' into fix/canvas-pause-resume-cascade-param-2122-followup
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
CI / Detect changes (pull_request) Successful in 12s
E2E Chat / detect-changes (pull_request) Successful in 10s
Harness Replays / detect-changes (pull_request) Successful in 7s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 11s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 14s
CI / Platform (Go) (pull_request) Successful in 6s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 8s
E2E Chat / E2E Chat (pull_request) Successful in 3s
Harness Replays / Harness Replays (pull_request) Successful in 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
qa-review / approved (pull_request_target) Successful in 11s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 6s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
gate-check-v3 / gate-check (pull_request_target) Successful in 15s
sop-checklist / na-declarations (pull_request) N/A: (none)
security-review / approved (pull_request_target) Successful in 12s
sop-tier-check / tier-check (pull_request_target) Failing after 9s
sop-checklist / all-items-acked (pull_request_target) Successful in 12s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 58s
CI / Canvas (Next.js) (pull_request) Successful in 6m13s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
2026-06-06 14:21:45 +00:00
Molecule AI Dev Engineer A (Kimi) 04e53ff20d fix(audit-force-merge): fail-closed on missing merge_commit_sha, merged_by, base.ref, head.sha, statuses (PR#2366 RC follow-up)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
CI / Python Lint & Test (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 7s
E2E Chat / detect-changes (pull_request) Successful in 13s
CI / Detect changes (pull_request) Successful in 16s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 10s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 11s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
sop-checklist / review-refire (pull_request_target) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Failing after 10s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
CI / Canvas Deploy Status (pull_request) Has been skipped
Handlers Postgres Integration / detect-changes (pull_request) Successful in 28s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
qa-review / approved (pull_request_target) Failing after 7s
sop-checklist / na-declarations (pull_request) N/A: (none)
CI / all-required (pull_request) Successful in 6s
security-review / approved (pull_request_target) Failing after 9s
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
sop-tier-check / tier-check (pull_request_target) Failing after 10s
E2E Chat / E2E Chat (pull_request) Successful in 19s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m16s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m40s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 8s
PM correction: the prior fix only addressed . Remaining
fail-open fallbacks have now been hardened:

- merge_commit_sha: previously defaulted to empty and exited 0 with a warning,
  silently skipping the audit. Now aborts with ::error:: if missing.
- merged_by.login: previously defaulted to 'unknown', creating an anonymous
  audit trail. Now aborts if merged_by is missing.
- base.ref: previously defaulted to 'main', risking wrong-branch required-check
  evaluation. Now aborts if missing.
- head.sha: already fail-closed via the downstream HTTP 404 check, but now
  explicitly checked for presence before the status fetch.
- statuses: previously defaulted to [] and exited 'all checks green', silently
  skipping the audit. Now aborts with ::error:: if missing from the 200
  response.

All critical fields now use explicit has() verification before reading.

Refs: molecule-core#2366, Researcher systemic audit-force-merge audit.
2026-06-06 14:19:08 +00:00
devops-engineer bb14f09ffb Merge branch 'main' into fix/2251-delegate-task-message-role-contract-test
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 8s
CI / Detect changes (pull_request) Successful in 8s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 9s
E2E Chat / detect-changes (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 12s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
Harness Replays / detect-changes (pull_request) Successful in 7s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 15s
Harness Replays / Harness Replays (pull_request) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 8s
sop-checklist / review-refire (pull_request_target) Has been skipped
qa-review / approved (pull_request_target) Successful in 10s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
gate-check-v3 / gate-check (pull_request_target) Successful in 13s
E2E Chat / E2E Chat (pull_request) Successful in 12s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 7s
sop-tier-check / tier-check (pull_request_target) Failing after 6s
security-review / approved (pull_request_target) Failing after 19s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m0s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m24s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 3m7s
CI / Platform (Go) (pull_request) Successful in 8m19s
CI / Canvas (Next.js) (pull_request) Successful in 8m32s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 2s
2026-06-06 14:15:43 +00:00
Molecule AI Dev Engineer A (Kimi) 06a7d14de9 fix(audit-force-merge): fail-closed when 'merged' field missing from 200 response (PR#2366 RC)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 12s
qa-review / approved (pull_request_target) Failing after 4s
gate-check-v3 / gate-check (pull_request_target) Failing after 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 14s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 15s
CI / Detect changes (pull_request) Successful in 16s
E2E Chat / detect-changes (pull_request) Successful in 16s
E2E API Smoke Test / detect-changes (pull_request) Successful in 16s
security-review / approved (pull_request_target) Failing after 5s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 17s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6s
sop-checklist / all-items-acked (pull_request_target) Successful in 8s
E2E Chat / E2E Chat (pull_request) Successful in 2s
sop-tier-check / tier-check (pull_request_target) Failing after 9s
CI / Canvas (Next.js) (pull_request) Successful in 7s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Successful in 7s
CI / all-required (pull_request) Successful in 1s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 54s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m5s
Researcher RC: the prior fix added HTTP status verification, but
'.merged // false' still allowed a 200 response with a missing/malformed
'merged' field to silently skip the audit (treated as not merged).

Now we explicitly verify the 'merged' key exists in the payload before
reading it. If absent, the script aborts with ::error:: instead of
falling through to the no-op path.

Refs: molecule-core#2366, Researcher systemic audit-force-merge audit.
2026-06-06 14:09:04 +00:00
devops-engineer dd5da6184e Merge branch 'main' into fix/817-canvas-deploy-reminder-per-step-gate
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 8s
CI / Detect changes (pull_request) Successful in 10s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
E2E Chat / detect-changes (pull_request) Successful in 10s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 6s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
CI / Platform (Go) (pull_request) Successful in 3s
CI / Canvas (Next.js) (pull_request) Successful in 3s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 9s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 12s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 18s
CI / Canvas Deploy Status (pull_request) Successful in 2s
CI / all-required (pull_request) Successful in 6s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
security-review / approved (pull_request_target) Failing after 7s
gate-check-v3 / gate-check (pull_request_target) Successful in 16s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 19s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 17s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
qa-review / approved (pull_request_target) Failing after 18s
sop-checklist / all-items-acked (pull_request_target) Successful in 7s
sop-tier-check / tier-check (pull_request_target) Failing after 11s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 59s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m1s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m25s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m14s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m14s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Successful in 1m37s
2026-06-06 14:05:48 +00:00
devops-engineer 3e77146c1e Merge branch 'main' into fix/2139-sop-tier-check-real-qa-security-teams
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 4s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
CI / Detect changes (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 8s
CI / Platform (Go) (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Chat / detect-changes (pull_request) Successful in 14s
E2E API Smoke Test / detect-changes (pull_request) Successful in 15s
sop-checklist / review-refire (pull_request_target) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
CI / all-required (pull_request) Successful in 3s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 7s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 3s
gate-check-v3 / gate-check (pull_request_target) Successful in 8s
qa-review / approved (pull_request_target) Failing after 7s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-tier-check / tier-check (pull_request_target) Failing after 6s
sop-checklist / na-declarations (pull_request) N/A: (none)
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
sop-checklist / all-items-acked (pull_request_target) Successful in 13s
security-review / approved (pull_request_target) Failing after 13s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m3s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m13s
2026-06-06 14:00:36 +00:00
Molecule AI Dev Engineer A (Kimi) 93f2a8f971 fix(audit-force-merge): fail-closed on HTTP errors from Gitea API (molecule-core)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 8s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Has started running
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
E2E Chat / detect-changes (pull_request) Successful in 11s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 11s
CI / Platform (Go) (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 15s
CI / Canvas (Next.js) (pull_request) Successful in 4s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 15s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 14s
E2E API Smoke Test / detect-changes (pull_request) Successful in 28s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
CI / all-required (pull_request) Successful in 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
CI / Canvas Deploy Status (pull_request) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Successful in 15s
E2E Chat / E2E Chat (pull_request) Successful in 12s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
qa-review / approved (pull_request_target) Failing after 25s
sop-checklist / all-items-acked (pull_request_target) Successful in 18s
security-review / approved (pull_request_target) Failing after 21s
sop-tier-check / tier-check (pull_request_target) Failing after 10s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 13s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m4s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m4s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 6s
Systemic audit gap found by Researcher: curl -sS without -f or HTTP
status verification silently treats 401/403/404 responses as success.
For the PR fetch, an auth error produced empty/invalid JSON, jq parsed
.merged as false, and the script exited 0 (no-op) — missing the audit
entirely. Same pattern for the status fetch.

Now both API calls capture the HTTP status code and abort with ::error::
if the response is not HTTP 200, matching the fail-closed pattern used in
review-check.sh.

Refs: Researcher systemic audit-force-merge audit, internal#348 Class B.
2026-06-06 13:42:20 +00:00
devops-engineer dcf9d3cdc1 Merge branch 'main' into fix/plugin-uninstall-exec-errors
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 3s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
CI / Detect changes (pull_request) Successful in 11s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
CI / Canvas (Next.js) (pull_request) Successful in 2s
E2E Chat / detect-changes (pull_request) Successful in 16s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
Harness Replays / detect-changes (pull_request) Successful in 14s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 17s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 12s
qa-review / approved (pull_request_target) Successful in 5s
sop-checklist / review-refire (pull_request_target) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Successful in 7s
CI / Canvas Deploy Status (pull_request) Has been skipped
security-review / approved (pull_request_target) Failing after 4s
Harness Replays / Harness Replays (pull_request) Successful in 1s
E2E Chat / E2E Chat (pull_request) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 19s
sop-tier-check / tier-check (pull_request_target) Failing after 18s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 17s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m9s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m8s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m30s
CI / Platform (Go) (pull_request) Successful in 3m52s
CI / all-required (pull_request) Successful in 2s
2026-06-06 13:30:27 +00:00
devops-engineer c967edd162 Merge branch 'main' into fix/goroutine-panic-recovery
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
CI / Python Lint & Test (pull_request) Successful in 7s
CI / Detect changes (pull_request) Successful in 12s
E2E Chat / detect-changes (pull_request) Successful in 13s
CI / Canvas (Next.js) (pull_request) Successful in 3s
E2E API Smoke Test / detect-changes (pull_request) Successful in 17s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 7s
CI / Canvas Deploy Status (pull_request) Has been skipped
Harness Replays / detect-changes (pull_request) Successful in 7s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 11s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 16s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 7s
E2E Chat / E2E Chat (pull_request) Successful in 8s
Harness Replays / Harness Replays (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
qa-review / approved (pull_request_target) Successful in 11s
gate-check-v3 / gate-check (pull_request_target) Successful in 14s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 18s
sop-tier-check / tier-check (pull_request_target) Failing after 9s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
security-review / approved (pull_request_target) Failing after 22s
sop-checklist / all-items-acked (pull_request_target) Successful in 20s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Successful in 1m8s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 5s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m3s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m12s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m15s
CI / Platform (Go) (pull_request) Successful in 3m58s
CI / all-required (pull_request) Successful in 5s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Has been cancelled
2026-06-06 13:25:44 +00:00
devops-engineer c86ff64b2f Merge branch 'main' into fix/umbrella-reaper-1780
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 9s
E2E Chat / detect-changes (pull_request) Successful in 10s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 9s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 12s
E2E API Smoke Test / detect-changes (pull_request) Successful in 18s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 14s
CI / Detect changes (pull_request) Successful in 20s
sop-checklist / review-refire (pull_request_target) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
sop-checklist / all-items-acked (pull_request) acked: 7/7
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
CI / Canvas Deploy Status (pull_request) Has been skipped
security-review / approved (pull_request_target) Failing after 28s
gate-check-v3 / gate-check (pull_request_target) Failing after 30s
qa-review / approved (pull_request_target) Failing after 29s
sop-tier-check / tier-check (pull_request_target) Failing after 26s
CI / all-required (pull_request) Successful in 12s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 56s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 57s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m14s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m12s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m25s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m48s
2026-06-06 13:00:09 +00:00
devops-engineer 24545fb065 Merge branch 'main' into fix/internal-805-sweep-cf-cloudflare-fallback-clean
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
CI / Python Lint & Test (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 10s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 11s
E2E Chat / detect-changes (pull_request) Successful in 13s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 11s
CI / Platform (Go) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 12s
sop-checklist / review-refire (pull_request_target) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Successful in 8s
CI / Canvas Deploy Status (pull_request) Has been skipped
security-review / approved (pull_request_target) Successful in 6s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 35s
qa-review / approved (pull_request_target) Successful in 29s
E2E Chat / E2E Chat (pull_request) Successful in 25s
CI / all-required (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m0s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m11s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m15s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m22s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m21s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m34s
2026-06-06 12:20:29 +00:00
devops-engineer 820b13f3d9 Merge branch 'main' into fix/main-red-2305-lint-and-e2e-platform-managed
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 2s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 5s
CI / Detect changes (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 1s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 4s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 19s
E2E Chat / detect-changes (pull_request) Successful in 22s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
gate-check-v3 / gate-check (pull_request_target) Failing after 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
qa-review / approved (pull_request_target) Successful in 6s
E2E Chat / E2E Chat (pull_request) Successful in 3s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-tier-check / tier-check (pull_request_target) Failing after 6s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 30s
security-review / approved (pull_request_target) Failing after 20s
sop-checklist / all-items-acked (pull_request_target) Successful in 20s
CI / all-required (pull_request) Successful in 3s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Successful in 1m3s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 58s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 57s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m12s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m18s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m25s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m24s
2026-06-06 12:15:34 +00:00
devops-engineer d9dff36d1b Merge branch 'main' into fix/main-red-e2e-chat-auth-token
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 6s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 16s
CI / Platform (Go) (pull_request) Successful in 13s
E2E Chat / detect-changes (pull_request) Successful in 21s
CI / Canvas Deploy Status (pull_request) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
gate-check-v3 / gate-check (pull_request_target) Successful in 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
E2E Chat / E2E Chat (pull_request) Successful in 2s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
CI / all-required (pull_request) Successful in 6s
qa-review / approved (pull_request_target) Failing after 10s
sop-checklist / all-items-acked (pull_request_target) Successful in 8s
security-review / approved (pull_request_target) Failing after 10s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 58s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 58s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m11s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m9s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m25s
2026-06-06 12:10:27 +00:00
devops-engineer 8a6f37128f Merge branch 'main' into fix/internal-802-bp-directive-comments
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 7s
E2E Chat / detect-changes (pull_request) Successful in 7s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 16s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 16s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 18s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 7s
E2E Chat / E2E Chat (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 25s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 17s
gate-check-v3 / gate-check (pull_request_target) Successful in 9s
CI / Canvas (Next.js) (pull_request) Successful in 6s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 10s
CI / Platform (Go) (pull_request) Successful in 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
qa-review / approved (pull_request_target) Successful in 9s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 4s
security-review / approved (pull_request_target) Failing after 5s
CI / Canvas Deploy Status (pull_request) Has been skipped
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 6s
sop-checklist / all-items-acked (pull_request_target) Successful in 8s
sop-tier-check / tier-check (pull_request_target) Failing after 8s
CI / all-required (pull_request) Successful in 3s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m2s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m2s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m12s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m12s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m17s
2026-06-06 12:05:29 +00:00
devops-engineer 87ce80056a Merge branch 'main' into cp455-minimal-cell-boot-e2e-stage1
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Detect changes (pull_request) Successful in 5s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
CI / Python Lint & Test (pull_request) Successful in 6s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 3s
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 7s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 12s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 6s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 15s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 12s
E2E Chat / detect-changes (pull_request) Successful in 16s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 12s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 4s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 15s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
sop-checklist / review-refire (pull_request_target) Has been skipped
qa-review / approved (pull_request_target) Successful in 8s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Chat / E2E Chat (pull_request) Successful in 2s
sop-tier-check / tier-check (pull_request_target) Failing after 6s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 1s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 18s
security-review / approved (pull_request_target) Failing after 17s
gate-check-v3 / gate-check (pull_request_target) Successful in 18s
CI / all-required (pull_request) Successful in 9s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 20s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m1s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m3s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m14s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m15s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m21s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m51s
2026-06-06 12:00:35 +00:00
devops-engineer b6668c3b68 Merge branch 'main' into fix/reconciler-debounce-coupling-2284
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 6s
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (staging) (pull_request) Has been skipped
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
E2E Chat / detect-changes (pull_request) Successful in 6s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
CI / Canvas (Next.js) (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 9s
E2E Chat / E2E Chat (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
Harness Replays / detect-changes (pull_request) Successful in 10s
CI / Canvas Deploy Status (pull_request) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
Harness Replays / Harness Replays (pull_request) Successful in 1s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 16s
gate-check-v3 / gate-check (pull_request_target) Successful in 13s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-tier-check / tier-check (pull_request_target) Failing after 8s
qa-review / approved (pull_request_target) Successful in 14s
sop-checklist / all-items-acked (pull_request_target) Successful in 12s
security-review / approved (pull_request_target) Failing after 13s
E2E Workspace Lifecycle (staginge2e) / E2E Workspace Lifecycle (compile+skip) (pull_request) Successful in 29s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m7s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m9s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m19s
CI / Platform (Go) (pull_request) Successful in 4m9s
CI / all-required (pull_request) Successful in 4s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Has been cancelled
2026-06-06 11:55:40 +00:00
devops-engineer 7c52aacfae Merge branch 'main' into fix/main-red-canvas-e2e-tablist-strict-mode
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 7s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 10s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
Harness Replays / detect-changes (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 6s
Harness Replays / Harness Replays (pull_request) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
E2E Chat / detect-changes (pull_request) Successful in 18s
E2E API Smoke Test / detect-changes (pull_request) Successful in 18s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 15s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 17s
gate-check-v3 / gate-check (pull_request_target) Successful in 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
qa-review / approved (pull_request_target) Successful in 5s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
security-review / approved (pull_request_target) Successful in 5s
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 1s
E2E Chat / E2E Chat (pull_request) Successful in 2s
sop-tier-check / tier-check (pull_request_target) Failing after 4s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 15s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 7s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 57s
CI / Canvas (Next.js) (pull_request) Successful in 6m19s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 2s
2026-06-06 11:50:39 +00:00
Molecule AI Dev Engineer A (Kimi) 98015ad24d fix(ci): tracker-lint fail-closed on fetch error (core#2363)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Detect changes (pull_request) Successful in 5s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
E2E Chat / detect-changes (pull_request) Successful in 7s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 15s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 12s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 13s
E2E API Smoke Test / detect-changes (pull_request) Successful in 15s
gate-check-v3 / gate-check (pull_request_target) Failing after 7s
sop-checklist / review-refire (pull_request_target) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 12s
qa-review / approved (pull_request_target) Failing after 5s
CI / Canvas Deploy Status (pull_request) Has been skipped
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
security-review / approved (pull_request_target) Failing after 6s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1s
CI / all-required (pull_request) Successful in 7s
E2E Chat / E2E Chat (pull_request) Successful in 8s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-tier-check / tier-check (pull_request_target) Failing after 12s
sop-checklist / all-items-acked (pull_request_target) Successful in 12s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m1s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m8s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m15s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 3s
lint_continue_on_error_tracking.py:
- API fetch errors (network, timeout, 5xx) now return violation
  instead of skip/pass. Previously a Gitea outage would silently
  green every tracker check — now it fails closed.

The companion BP-404 fix for ci-required-drift.py was REVERTED:
the original code on main (e441def8) already correctly handles
401/403/5xx fail-closed and 404 skip-with-empty-findings per the
contract tested by test_detect_drift_404_skips_branch. The
"BRANCH_PROTECTION_MISSING" finding over-corrected into FALSE-FAIL
(CR2 9130/9133). No ci-required-drift.py change is needed.

Tests: 22 ci-drift + 14 tracker-lint + 13 script-unit all pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 11:48:16 +00:00
devops-engineer 0e7ff3091f Merge branch 'main' into fix/canvas-pause-resume-cascade-param-2122-followup
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
E2E Chat / detect-changes (pull_request) Successful in 7s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 10s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 12s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 12s
Harness Replays / detect-changes (pull_request) Successful in 12s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 16s
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E Chat / E2E Chat (pull_request) Successful in 3s
gate-check-v3 / gate-check (pull_request_target) Successful in 8s
Harness Replays / Harness Replays (pull_request) Successful in 1s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 6s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 6s
qa-review / approved (pull_request_target) Successful in 9s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
security-review / approved (pull_request_target) Successful in 9s
sop-tier-check / tier-check (pull_request_target) Failing after 9s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 58s
CI / Canvas (Next.js) (pull_request) Successful in 6m21s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
2026-06-06 11:40:31 +00:00
devops-engineer 5e5762486e Merge branch 'main' into fix/2251-delegate-task-message-role-contract-test
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 10s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
E2E Chat / detect-changes (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 8s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
qa-review / approved (pull_request_target) Successful in 7s
Harness Replays / Harness Replays (pull_request) Successful in 2s
gate-check-v3 / gate-check (pull_request_target) Successful in 9s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 12s
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
security-review / approved (pull_request_target) Failing after 5s
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 17s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 18s
E2E Chat / E2E Chat (pull_request) Successful in 15s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m14s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m52s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2m14s
CI / Platform (Go) (pull_request) Successful in 3m57s
CI / Canvas (Next.js) (pull_request) Successful in 6m29s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 3s
2026-06-06 11:35:32 +00:00
devops-engineer dca3ef02cd Merge branch 'main' into fix/817-canvas-deploy-reminder-per-step-gate
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 10s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 7s
E2E Chat / detect-changes (pull_request) Successful in 13s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 11s
CI / Platform (Go) (pull_request) Successful in 1s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 11s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 12s
CI / Canvas (Next.js) (pull_request) Successful in 2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 11s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 5s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 7s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
gate-check-v3 / gate-check (pull_request_target) Successful in 7s
qa-review / approved (pull_request_target) Failing after 6s
E2E Chat / E2E Chat (pull_request) Successful in 9s
CI / Canvas Deploy Status (pull_request) Successful in 1s
sop-checklist / review-refire (pull_request_target) Has been skipped
security-review / approved (pull_request_target) Failing after 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 17s
sop-tier-check / tier-check (pull_request_target) Failing after 4s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 16s
CI / all-required (pull_request) Successful in 3s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 14s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m5s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Successful in 1m6s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m13s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m25s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m15s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m32s
2026-06-06 11:25:30 +00:00
devops-engineer b312083ecd Merge branch 'main' into fix/2139-sop-tier-check-real-qa-security-teams
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 4s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 8s
CI / Detect changes (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
CI / Platform (Go) (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
CI / Canvas (Next.js) (pull_request) Successful in 3s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
E2E Chat / detect-changes (pull_request) Successful in 12s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
CI / Canvas Deploy Status (pull_request) Has been skipped
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
gate-check-v3 / gate-check (pull_request_target) Successful in 6s
qa-review / approved (pull_request_target) Failing after 4s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
E2E Chat / E2E Chat (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 14s
sop-tier-check / tier-check (pull_request_target) Failing after 6s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 16s
security-review / approved (pull_request_target) Failing after 18s
CI / all-required (pull_request) Successful in 10s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m0s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m15s
2026-06-06 11:20:27 +00:00
devops-engineer bf0db08c7c Merge branch 'main' into fix/plugin-uninstall-exec-errors
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 8s
CI / Python Lint & Test (pull_request) Successful in 6s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 6s
Harness Replays / detect-changes (pull_request) Successful in 6s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E API Smoke Test / detect-changes (pull_request) Successful in 14s
CI / Canvas (Next.js) (pull_request) Successful in 10s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 17s
E2E Chat / detect-changes (pull_request) Successful in 18s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 6s
Harness Replays / Harness Replays (pull_request) Successful in 2s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
qa-review / approved (pull_request_target) Successful in 7s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 16s
gate-check-v3 / gate-check (pull_request_target) Successful in 16s
sop-checklist / review-refire (pull_request_target) Has been skipped
CI / Canvas Deploy Status (pull_request) Has been skipped
security-review / approved (pull_request_target) Failing after 7s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
E2E Chat / E2E Chat (pull_request) Successful in 3s
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m2s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m17s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m52s
CI / Platform (Go) (pull_request) Successful in 4m3s
CI / all-required (pull_request) Successful in 1s
2026-06-06 10:50:18 +00:00
devops-engineer 52ab1cc715 Merge branch 'main' into fix/goroutine-panic-recovery
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 14s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
CI / Python Lint & Test (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
E2E Chat / detect-changes (pull_request) Successful in 5s
CI / Detect changes (pull_request) Successful in 14s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 6s
Harness Replays / detect-changes (pull_request) Successful in 6s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 13s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 9s
gate-check-v3 / gate-check (pull_request_target) Successful in 5s
sop-checklist / review-refire (pull_request_target) Has been skipped
qa-review / approved (pull_request_target) Successful in 4s
sop-tier-check / tier-check (pull_request_target) Failing after 6s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
security-review / approved (pull_request_target) Failing after 9s
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
E2E Chat / E2E Chat (pull_request) Successful in 5s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Successful in 34s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Has been skipped
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 8s
Harness Replays / Harness Replays (pull_request) Successful in 6s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m3s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 59s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2m11s
CI / Platform (Go) (pull_request) Successful in 3m59s
CI / all-required (pull_request) Successful in 3s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Successful in 5m19s
2026-06-06 10:45:17 +00:00
devops-engineer 0b620e6563 Merge branch 'main' into fix/umbrella-reaper-1780
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 4s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 8s
E2E Chat / detect-changes (pull_request) Successful in 10s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 6s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 9s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 18s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 6s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 15s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 6s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 10s
qa-review / approved (pull_request_target) Failing after 8s
security-review / approved (pull_request_target) Failing after 9s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 26s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 7/7
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 8s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
gate-check-v3 / gate-check (pull_request_target) Failing after 27s
E2E Chat / E2E Chat (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
CI / Platform (Go) (pull_request) Successful in 1s
CI / Canvas (Next.js) (pull_request) Successful in 2s
sop-tier-check / tier-check (pull_request_target) Failing after 25s
CI / Canvas Deploy Status (pull_request) Has been skipped
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 17s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 5s
CI / all-required (pull_request) Successful in 3s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m3s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m6s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m17s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m12s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m22s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m29s
2026-06-06 10:25:15 +00:00
Molecule AI Dev Engineer A (Kimi) a061a43e8f ci: empty commit to re-trigger workflow run
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 1s
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Detect changes (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 5s
E2E Chat / detect-changes (pull_request) Successful in 9s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 6s
Harness Replays / detect-changes (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 8s
qa-review / approved (pull_request_target) Successful in 5s
sop-checklist / review-refire (pull_request_target) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Successful in 8s
security-review / approved (pull_request_target) Failing after 6s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 11s
sop-checklist / all-items-acked (pull_request_target) Successful in 7s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
Harness Replays / Harness Replays (pull_request) Successful in 1s
E2E Chat / E2E Chat (pull_request) Successful in 7s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m1s
CI / Canvas (Next.js) (pull_request) Successful in 6m28s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 4s
2026-06-05 18:33:16 +00:00
Molecule AI Dev Engineer A (Kimi) 0053c32335 ci: empty commit to re-trigger workflow run
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 0s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 3s
E2E API Smoke Test / detect-changes (pull_request) Successful in 5s
E2E Chat / detect-changes (pull_request) Successful in 5s
CI / Detect changes (pull_request) Successful in 11s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 4s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 3s
Harness Replays / detect-changes (pull_request) Successful in 5s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
gate-check-v3 / gate-check (pull_request_target) Successful in 6s
qa-review / approved (pull_request_target) Successful in 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
security-review / approved (pull_request_target) Failing after 5s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
sop-tier-check / tier-check (pull_request_target) Failing after 4s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1s
E2E Chat / E2E Chat (pull_request) Successful in 2s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
Harness Replays / Harness Replays (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 56s
CI / Canvas (Next.js) (pull_request) Successful in 5m28s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 7s
2026-06-05 18:32:58 +00:00
Molecule AI Dev Engineer A (Kimi) 9b13b71fae fix(ci): resolve main-red #2305 — lint trackers + platform-managed E2E + invalid MiniMax-M2 slug
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 8s
E2E Staging Reconciler (heals terminated EC2) / pr-validate (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 2s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 8s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 6s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 19s
E2E Chat / detect-changes (pull_request) Successful in 20s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
CI / Platform (Go) (pull_request) Successful in 4s
qa-review / approved (pull_request_target) Failing after 5s
gate-check-v3 / gate-check (pull_request_target) Successful in 8s
CI / Canvas (Next.js) (pull_request) Successful in 5s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Successful in 32s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 7s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 3s
sop-checklist / review-refire (pull_request_target) Has been skipped
CI / Shellcheck (E2E scripts) (pull_request) Successful in 13s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
security-review / approved (pull_request_target) Failing after 13s
sop-tier-check / tier-check (pull_request_target) Failing after 4s
E2E Chat / E2E Chat (pull_request) Successful in 2s
CI / all-required (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 56s
CI / Canvas Deploy Status (pull_request) Has been skipped
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m12s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m21s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m11s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m23s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m28s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Successful in 5m23s
E2E Staging Reconciler (heals terminated EC2) / E2E Staging Reconciler (pull_request) Failing after 17m49s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 4s
main-red #2305 (SHA f78fef4c97) fired four contexts:

1. lint-continue-on-error-tracking — two workflows lacked mc#1982 tracker
   comments on their continue-on-error: true masks:
   - e2e-chat.yml job 'e2e-chat' line 138
   - e2e-staging-external.yml job 'e2e-staging-external' line 107

2. E2E Staging SaaS (full lifecycle) — workspace-create 422 because the
   main SaaS job injected MINIMAX_API_KEY into a platform-managed workspace
   (PR #2291 fail-closed auth now blocks direct vendor key writes). Switched
   the main job to E2E_LLM_PATH=platform (moonshot/kimi-k2.6, empty secrets),
   mirroring the sibling Platform Boot job. Removed the hardcoded BYOK
   E2E_MODEL_SLUG fallback.

3. E2E Staging Reconciler — E2E_MODEL_SLUG: MiniMax-M2 is an invalid slug
   (core#2263). Removed the override so the reconciler uses the default
   platform-managed model (moonshot/kimi-k2.6) like the Platform Boot job.

4. E2E Staging Platform Boot — workspace restart race after config.yaml PUT.
   The A2A proxy returned 503 "container restart triggered" immediately
   after status=online. This appears to be a transient timing issue in the
   smoke-mode config.yaml round-trip; the other three fixes are the stable
   regressions.

Also fixes two scheduled workflows that still carried the stale MiniMax-M2
slug (not yet on main — commit 54648a8a was on a side branch):
- staging-smoke.yml: MiniMax-M2 → MiniMax-M2.7
- continuous-synth-e2e.yml: MiniMax-M2 → MiniMax-M2.7

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 18:32:28 +00:00
Molecule AI Dev Engineer A (Kimi) 3cc9dd2515 fix(e2e): stop injecting direct vendor keys into platform-managed peer-visibility workspaces (main-red #2298)
PR #2291 blocks direct vendor key writes (ANTHROPIC_API_KEY,
ANTHROPIC_AUTH_TOKEN, MINIMAX_API_KEY, etc.) for platform-managed
workspaces. The peer-visibility staging E2E already uses platform-managed
models (anthropic/claude-sonnet-4-6, moonshot/kimi-k2.6) and does not need
tenant keys — Molecule owns billing via the CP LLM proxy.

Removes the MiniMax → Anthropic → OpenAI secrets-injection chain from
test_peer_visibility_mcp_staging.sh and keeps SECRETS_JSON empty,
matching test_staging_full_saas.sh's E2E_LLM_PATH=platform branch.
This prevents the workspace-create 400:
  "direct vendor key writes are blocked for platform-managed workspaces"
that was causing the staging E2E Peer Visibility gate to fail on every
main push.

Local peer-visibility E2E is unaffected — it uses its own provisioning
path and already passes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 18:31:34 +00:00
Molecule AI Dev Engineer A (Kimi) e2803dfb3e fix(ci): add mc#1982 tracker comments to continue-on-error masks (main-red #2294)
The lint-continue-on-error-tracking gate failed because two jobs have
continue-on-error: true with no # mc#NNNN tracker within 2 lines:

- e2e-chat.yml line 138
- e2e-staging-external.yml line 107

Both masks are part of the same mc#1982 tracker (pre-existing masks
awaiting root-fix). Add the tracker comment immediately before each
continue-on-error so the linter's 2-line proximity rule is satisfied.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 18:00:35 +00:00
Molecule AI Dev Engineer A (Kimi) 1424fb0d55 fix(ci): add CLOUDFLARE_* secret fallback to sweep-cf workflows (internal#805)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 3s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 7s
CI / Detect changes (pull_request) Successful in 11s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 11s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 10s
E2E Chat / detect-changes (pull_request) Successful in 14s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 18s
CI / Platform (Go) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 19s
gate-check-v3 / gate-check (pull_request_target) Successful in 8s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 15s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 1s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1s
qa-review / approved (pull_request_target) Failing after 21s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 24s
CI / Canvas (Next.js) (pull_request) Successful in 18s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Has been skipped
security-review / approved (pull_request_target) Failing after 22s
CI / all-required (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 58s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Failing after 1m4s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m17s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m14s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m29s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m24s
sop-checklist / review-refire (pull_request_target) Has been skipped
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-tier-check / tier-check (pull_request_target) Failing after 5s
sop-checklist / all-items-acked (pull_request_target) Successful in 6s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 5s
The sweep-cf-orphans and sweep-cf-tunnels workflows reference CI-scoped
secret names (CF_API_TOKEN, CF_ZONE_ID, CF_ACCOUNT_ID) while the
operator-host canonical names are CLOUDFLARE_API_TOKEN,
CLOUDFLARE_ZONE_ID, CLOUDFLARE_ACCOUNT_ID. When the CI-scoped duplicates
are missing from the secret store, the scheduled sweeps hard-fail even
though the canonical names are present.

Changes:
- Workflow YAML: `secrets.CF_API_TOKEN || secrets.CLOUDFLARE_API_TOKEN`
  (same pattern for ZONE_ID and ACCOUNT_ID).
- Scripts: add env-var fallback so direct local invocation also works.
- Comments and error messages updated to mention both naming conventions.

Closes internal#805

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 14:55:58 +00:00
Molecule AI Dev Engineer A (Kimi) 7fd99c0f6c fix(ci): remove workflow_dispatch.inputs for Gitea 1.22.6 compat (PR #2299 CR3)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 3s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 9s
E2E API Smoke Test / detect-changes (pull_request) Successful in 13s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 12s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 12s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 12s
CI / Platform (Go) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
E2E Chat / detect-changes (pull_request) Successful in 18s
qa-review / approved (pull_request_target) Failing after 6s
gate-check-v3 / gate-check (pull_request_target) Failing after 6s
security-review / approved (pull_request_target) Failing after 5s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Chat / E2E Chat (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 24s
CI / all-required (pull_request) Successful in 5s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Failing after 54s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 54s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m8s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m21s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m26s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m31s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 5s
sop-checklist / review-refire (pull_request_target) Has been skipped
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
sop-tier-check / tier-check (pull_request_target) Successful in 6s
Agent-reviewer CR2 follow-up: Gitea 1.22.6 rejects workflow_dispatch.inputs
(feedback_gitea_workflow_dispatch_inputs_unsupported). The lint-workflow-yaml
script flagged this shape.

Fix: remove inputs block and hardcode defaults in job env:
  runtime: claude-code
  billing_mode: platform_managed
  provider: platform
  model: moonshot/kimi-k2.6

Stage 2 can re-add parametric inputs once Gitea supports them.

Refs: cp#455
2026-06-05 10:10:06 +00:00
Molecule AI Dev Engineer A (Kimi) 8092e62de4 fix(ci): set deterministic ADMIN_TOKEN in e2e-chat after PR #2291 fail-closed auth
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 5s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 1s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 8s
E2E Chat / detect-changes (pull_request) Successful in 13s
CI / Detect changes (pull_request) Successful in 16s
E2E API Smoke Test / detect-changes (pull_request) Successful in 18s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 17s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
qa-review / approved (pull_request_target) Failing after 6s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 12s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Successful in 16s
security-review / approved (pull_request_target) Failing after 13s
CI / Platform (Go) (pull_request) Successful in 11s
CI / all-required (pull_request) Successful in 3s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Failing after 1m3s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 57s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m12s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m22s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m28s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-tier-check / tier-check (pull_request_target) Successful in 5s
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
PR #2291 removed dev-mode fail-open auth; the platform server now
requires ADMIN_TOKEN in every environment including development.
e2e-chat.yml was starting the platform with MOLECULE_ENV=development
but no ADMIN_TOKEN, causing all API calls to 401 and the job to fail.

Add a 'Set deterministic admin token' step (mirrors e2e-api.yml):
- ADMIN_TOKEN for the platform server
- MOLECULE_ADMIN_TOKEN for e2e script compatibility
- NEXT_PUBLIC_ADMIN_TOKEN so the canvas dev server sends the matching
  bearer on every API call

Fixes main-red issue #2298 (E2E Chat failure).
2026-06-05 10:03:13 +00:00
Molecule AI Dev Engineer A (Kimi) 40e4805c5e fix(ci): move cp#455 workflow to .gitea/workflows + add bp-exempt (PR #2299 CR2)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
CI / Python Lint & Test (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 9s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
E2E Chat / detect-changes (pull_request) Successful in 10s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 8s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 12s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 10s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 15s
sop-checklist / review-refire (pull_request_target) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
CI / Platform (Go) (pull_request) Successful in 1s
CI / Canvas (Next.js) (pull_request) Successful in 1s
qa-review / approved (pull_request_target) Failing after 5s
E2E Chat / E2E Chat (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 1s
CI / Canvas Deploy Status (pull_request) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-tier-check / tier-check (pull_request_target) Failing after 5s
sop-checklist / all-items-acked (pull_request_target) Has been cancelled
gate-check-v3 / gate-check (pull_request_target) Failing after 16s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 13s
security-review / approved (pull_request_target) Failing after 26s
CI / all-required (pull_request) Successful in 9s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Failing after 54s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Failing after 54s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 55s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m14s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m23s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m34s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 4s
Agent-reviewer requested changes on PR #2299:
1. Workflow was in .github/workflows/ which doesn't exist in molecule-core;
   moved to .gitea/workflows/ where Gitea Actions discovers it.
2. Added # bp-exempt directive above the minimal-cell job key so the
   lint-required-context-exists-in-bp linter (internal#350) passes.
3. Removed accidentally-included reconciler debounce commit (#2284) by
   rebasing the branch onto clean main.

Refs: cp#455, internal#802
2026-06-05 09:53:11 +00:00
Molecule AI Dev Engineer A (Kimi) 11291e2939 fix(ci): add bp-exempt directive to lint-required-workflows-docker-host-pinned (internal#802)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
CI / Python Lint & Test (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 5s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 1s
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
E2E Chat / detect-changes (pull_request) Successful in 7s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 11s
gate-check-v3 / gate-check (pull_request_target) Successful in 4s
qa-review / approved (pull_request_target) Failing after 3s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 17s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Chat / E2E Chat (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 18s
security-review / approved (pull_request_target) Failing after 12s
CI / Platform (Go) (pull_request) Successful in 12s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 10s
CI / all-required (pull_request) Successful in 2s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 57s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Failing after 1m5s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m6s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m10s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m8s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
sop-tier-check / tier-check (pull_request_target) Successful in 5s
The lint-required-context-exists-in-bp linter requires every workflow
job that emits a commit status to carry a bp directive within 3 lines
above the job key. Three of the four flagged files already had correct
directives; this file was missing one.

Add # bp-exempt because this is an informational convention-enforcing
lint (internal#512), not a merge gate.

Closes internal#802
2026-06-05 09:46:09 +00:00
Molecule AI Dev Engineer A (Kimi) 53130ee020 fix(reconciler): export RestartDebounceWindow and assert >= reconcile interval (#2284)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 2s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
Harness Replays / detect-changes (pull_request) Successful in 4s
E2E Chat / detect-changes (pull_request) Successful in 8s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
CI / Python Lint & Test (pull_request) Successful in 9s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 3s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 3s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
gate-check-v3 / gate-check (pull_request_target) Successful in 4s
qa-review / approved (pull_request_target) Failing after 3s
security-review / approved (pull_request_target) Failing after 4s
CI / Detect changes (pull_request) Successful in 15s
E2E API Smoke Test / detect-changes (pull_request) Successful in 13s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 1s
E2E Chat / E2E Chat (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
Harness Replays / Harness Replays (pull_request) Successful in 4s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Has been skipped
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 3s
sop-tier-check / tier-check (pull_request_target) Failing after 13s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 58s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m7s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m17s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Successful in 5m11s
CI / Platform (Go) (pull_request) Successful in 5m44s
CI / all-required (pull_request) Successful in 3s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 5s
The restart debounce window (60s) was set exactly equal to the CP instance
reconciler interval (60s) with zero margin. If someone drops the reconciler
interval below the debounce window, a workspace flipped offline by one tick
can be reprovisioned again by the next tick before the debounce drops it,
reopening the double-reprovision thrash class (internal#544).

Changes:
- Export RestartDebounceWindow from handlers package (was unexported).
- Add explicit COUPLING comment documenting the >= relationship.
- Add runtime assertion in main.go that fatals if the interval ever
  exceeds the debounce window, making the coupling fail-closed.
- Update test that manipulates the window to use the exported name.

Closes #2284 (MED item)
2026-06-05 09:03:52 +00:00
Molecule AI Dev Engineer A (Kimi) 250cea583f fix(tests): update A2A part assertions from type to kind (#2251 followup)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 4s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
Harness Replays / detect-changes (pull_request) Successful in 6s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 9s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 9s
E2E API Smoke Test / detect-changes (pull_request) Successful in 11s
qa-review / approved (pull_request_target) Failing after 5s
E2E Chat / detect-changes (pull_request) Successful in 17s
CI / Detect changes (pull_request) Successful in 18s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 17s
gate-check-v3 / gate-check (pull_request_target) Failing after 11s
security-review / approved (pull_request_target) Failing after 12s
Harness Replays / Harness Replays (pull_request) Successful in 8s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 23s
E2E Chat / E2E Chat (pull_request) Successful in 26s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m1s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 54s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m5s
CI / Platform (Go) (pull_request) Successful in 7m25s
CI / Canvas (Next.js) (pull_request) Successful in 7m45s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
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
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
sop-tier-check / tier-check (pull_request_target) Successful in 9s
PR #2260's contract tests were written against the old v0.2 shape
("type": "text") but main was already fixed to use v0.3's
"kind" discriminator. Update both delegation_test.go and mcp_test.go
to assert "kind" instead of "type".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 07:13:47 +00:00
Molecule AI Dev Engineer A (Kimi) fdf0ac1b11 fix(a2a): add contract test that delegate_task produces schema-valid SendMessageRequest (#2251)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 1s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
E2E Chat / detect-changes (pull_request) Successful in 9s
CI / Detect changes (pull_request) Successful in 11s
Harness Replays / detect-changes (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 3s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request_target) Has been cancelled
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 10s
qa-review / approved (pull_request_target) Failing after 6s
security-review / approved (pull_request_target) Failing after 5s
sop-tier-check / tier-check (pull_request_target) Failing after 5s
gate-check-v3 / gate-check (pull_request_target) Successful in 8s
E2E Chat / E2E Chat (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 3s
Harness Replays / Harness Replays (pull_request) Successful in 1s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m12s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m24s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m37s
CI / Platform (Go) (pull_request) Failing after 3m25s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 15s
CI / Canvas (Next.js) (pull_request) Successful in 6m21s
CI / all-required (pull_request) Has been skipped
CI / Canvas Deploy Status (pull_request) Has been skipped
The code fix (setting message.role="user" in the delegate_task A2A
envelope) was already present in both the MCP tool path
(mcp_tools.go:toolDelegateTask/toolDelegateTaskAsync) and the HTTP API
path (delegation.go:Delegate), added by 1e12ed7e on 2026-05-05.

This commit closes the regression gap by adding the contract tests
explicitly requested in issue #2251:

- Extract buildDelegateA2ABody from delegation.go into a pure function
  so the HTTP delegation envelope can be unit-tested without DB/HTTP.

- Add TestBuildDelegateA2ABody_SchemaValidSendMessageRequest which
  validates: method=message/send, message.role=user, messageId present,
  parts non-empty with a text part, and metadata.delegation_id.

- Add assertA2ASendMessageSchema helper in mcp_test.go and apply it to
  all four MCP delegate_task tests (sync, async, with attachments sync,
  with attachments async), pinning the jsonrpc 2.0 + role=user +
  messageId + parts contract on every outbound A2A dispatch.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 07:00:03 +00:00
Molecule AI Dev Engineer A (Kimi) 10cf157493 fix(e2e): narrow failed-status tolerance to pre-start credential-abort only (#2032 CR2)
Agent-reviewer flagged that the previous commit treated EVERY
status==="failed" as transient (log+poll until timeout). This masks real
boot regressions (image pull errors, panics, PYTHONPATH issues, quota
failures) by blurring them into a generic polling-timeout error.

Fix: only tolerate the pre-start credential-abort shape
(uptime_seconds===0 AND no last_sample_error). All other failed states
immediately hard-throw with boot_stage / last_error / image detail, as
the original code did.

Also updates comments to match the narrowed behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 06:58:09 +00:00
Molecule AI Dev Engineer A (Kimi) dedd55ab37 canvas(e2e): tolerate transient 'failed' status during workspace boot (#2632)
The staging canvas E2E intermittently failed (~50% pass rate) because
the workspace-online poll in staging-setup.ts threw immediately when the
workspace status hit 'failed'. On hermes runtimes the controlplane
bootstrap-watcher deadline fires at 5 min and marks the workspace failed
prematurely; the heartbeat then transitions failed→online after
install.sh finishes at 10–13 min.

Fixes:
- Treat 'failed' as a transient state during workspace-online polling:
  log once and keep polling until the 20-min deadline, matching the
  behavior of test_staging_full_saas.sh step 7/11.
- Add retry-with-exponential-backoff (3 attempts, 3/6/12s) to the
  workspace creation POST so transient 5xx/504 errors from staging CP
  don't kill the entire run.

Closes #2632

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 06:58:09 +00:00
Molecule AI Dev Engineer A (Kimi) 85d05d8ab9 fix(e2e): scope canvas tablist locator to workspace panel (main-red #2289)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Python Lint & Test (pull_request) Successful in 3s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 1s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 8s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
E2E Chat / detect-changes (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 10s
Harness Replays / detect-changes (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 8s
qa-review / approved (pull_request_target) Failing after 5s
security-review / approved (pull_request_target) Failing after 5s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 13s
E2E API Smoke Test / detect-changes (pull_request) Successful in 15s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
Harness Replays / Harness Replays (pull_request) Successful in 1s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
E2E Chat / E2E Chat (pull_request) Successful in 2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
CI / Platform (Go) (pull_request) Successful in 8s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 17s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 56s
CI / Canvas (Next.js) (pull_request) Successful in 5m37s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 3s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 5s
gate-check-v3 / gate-check (pull_request_target) Successful in 6s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
sop-tier-check / tier-check (pull_request_target) Successful in 5s
Commit 32e64274 hardened the staging-tabs E2E by replacing
`page.waitForSelector('[role=\"tablist\"]')` with
`expect(page.locator('[role=\"tablist\"]')).toBeVisible()`.

Playwright's `expect(...).toBeVisible()` enforces strict mode:
exactly one element must match. After the AgentCommsPanel (chat
sub-tab bar for peer threads) gained `role=\"tablist\"` in PR #2833,
clicking a workspace node can leave TWO tablists in the DOM:
1. SidePanel workspace tabs (aria-label=\"Workspace panel tabs\")
2. AgentCommsPanel peer threads (aria-label=\"Peer threads\")

Scope the locator to the workspace panel tablist via its accessible
name so the strict-mode assertion passes regardless of whether the
chat tab (and its nested tablist) is active.

Fixes #2289
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 06:38:21 +00:00
Molecule AI Dev Engineer A (Kimi) c420dad905 fix(canvas): pass ?cascade=true to Pause/Resume endpoints
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 1s
CI / Python Lint & Test (pull_request) Successful in 4s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 4s
Harness Replays / detect-changes (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
CI / Detect changes (pull_request) Successful in 9s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
qa-review / approved (pull_request_target) Failing after 4s
gate-check-v3 / gate-check (pull_request_target) Successful in 5s
security-review / approved (pull_request_target) Failing after 3s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
Harness Replays / Harness Replays (pull_request) Successful in 1s
CI / Platform (Go) (pull_request) Successful in 1s
E2E Chat / detect-changes (pull_request) Successful in 18s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 13s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 13s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 15s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m19s
CI / Canvas (Next.js) (pull_request) Successful in 6m13s
CI / Canvas Deploy Status (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Failing after 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-tier-check / tier-check (pull_request_target) Successful in 4s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 12s
PR #2122 makes workspace Pause/Resume cascade opt-in via ?cascade=true.
Without this parameter, pausing/resuming a workspace with descendants
returns 409 Conflict, breaking the Canvas ContextMenu and batch-pause
flows that currently depend on implicit cascade behavior.

Add ?cascade=true to all Canvas callers so the existing UX behavior
is preserved when #2122 lands.

Refs: #2122
/sop-ack
2026-06-05 06:23:09 +00:00
Molecule AI Dev Engineer A (Kimi) 48b6011e17 fix(2047): pass workspaceID to stripPluginMarkersFromMemory
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 6s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 8s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 2s
CI / Detect changes (pull_request) Successful in 8s
E2E API Smoke Test / detect-changes (pull_request) Successful in 9s
Harness Replays / detect-changes (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 11s
gate-check-v3 / gate-check (pull_request_target) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 13s
security-review / approved (pull_request_target) Failing after 5s
qa-review / approved (pull_request_target) Failing after 6s
E2E Chat / detect-changes (pull_request) Successful in 16s
CI / Canvas (Next.js) (pull_request) Successful in 1s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 13s
Harness Replays / Harness Replays (pull_request) Successful in 6s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 54s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m32s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m49s
CI / Platform (Go) (pull_request) Successful in 3m54s
CI / all-required (pull_request) Successful in 7s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 5s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-tier-check / tier-check (pull_request_target) Successful in 5s
sop-checklist / all-items-acked (pull_request_target) Successful in 8s
2026-06-05 04:09:20 +00:00
Molecule AI Dev Engineer A (Kimi) 6dcde313d1 fix(2044): add missing runtime/debug import for panic recovery
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 1s
CI / Detect changes (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 9s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 12s
E2E Chat / detect-changes (pull_request) Successful in 5s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 6s
Harness Replays / detect-changes (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 11s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 3s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 7s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
qa-review / approved (pull_request_target) Failing after 4s
security-review / approved (pull_request_target) Failing after 4s
CI / Canvas (Next.js) (pull_request) Successful in 2s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Successful in 31s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Has been skipped
E2E Chat / E2E Chat (pull_request) Successful in 2s
gate-check-v3 / gate-check (pull_request_target) Successful in 17s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 1s
CI / Canvas Deploy Status (pull_request) Has been skipped
Harness Replays / Harness Replays (pull_request) Successful in 3s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m14s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 56s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1m15s
CI / Platform (Go) (pull_request) Successful in 4m0s
CI / all-required (pull_request) Successful in 1s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Successful in 5m22s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 7s
sop-tier-check / tier-check (pull_request_target) Failing after 8s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 4s
2026-06-05 04:03:57 +00:00
Molecule AI Dev Engineer A (Kimi) 0aa18baecc fix(handlers,channels,scheduler): add panic recovery to 10 goroutines
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 1s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 5s
E2E Chat / detect-changes (pull_request) Successful in 6s
CI / Python Lint & Test (pull_request) Successful in 19s
CI / Detect changes (pull_request) Successful in 19s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 5s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 9s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 3s
Harness Replays / detect-changes (pull_request) Successful in 9s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
gate-check-v3 / gate-check (pull_request_target) Successful in 4s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Failing after 23s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Has been skipped
sop-tier-check / tier-check (pull_request_target) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 20s
security-review / approved (pull_request_target) Failing after 17s
qa-review / approved (pull_request_target) Failing after 18s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 13s
CI / Canvas Deploy Status (pull_request) Has been skipped
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 59s
Harness Replays / Harness Replays (pull_request) Successful in 5s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Failing after 57s
CI / Platform (Go) (pull_request) Failing after 39s
CI / all-required (pull_request) Has been skipped
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Failing after 48s
E2E Staging External Runtime / E2E Staging External Runtime (pull_request) Successful in 5m12s
Adds defer recover() + stack logging to all background goroutines
launched by the workspace handler, channel manager, and scheduler
to prevent a single panic from crashing the server process.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 03:52:14 +00:00
Molecule AI Dev Engineer A (Kimi) cc99d3fff4 fix(plugins): log silently ignored execAsRoot errors during uninstall
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 1s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
CI / Python Lint & Test (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 5s
E2E Chat / detect-changes (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 5s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 3s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
gate-check-v3 / gate-check (pull_request_target) Successful in 3s
Harness Replays / detect-changes (pull_request) Successful in 17s
qa-review / approved (pull_request_target) Failing after 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 3s
security-review / approved (pull_request_target) Failing after 8s
sop-tier-check / tier-check (pull_request_target) Successful in 4s
CI / Canvas (Next.js) (pull_request) Successful in 1s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 58s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Failing after 25s
CI / Platform (Go) (pull_request) Failing after 36s
CI / all-required (pull_request) Has been skipped
Harness Replays / Harness Replays (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Has been skipped
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Failing after 48s
Plugin uninstall had two sites where execAsRoot errors were discarded:
- Skill directory removal (plugins_install.go:125) — orphaned skill dirs
  if rm -rf failed silently
- CLAUDE.md marker stripping (plugins_install_pipeline.go:326) — stale
  plugin content left in CLAUDE.md if awk script failed

Both now log the error without failing the overall uninstall (best-effort
 cleanup), giving operators visibility into incomplete uninstalls.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 03:52:07 +00:00
Molecule AI Dev Engineer A (Kimi) c536a1ee97 fix(ci): replace placeholder qa/security teams with real ones in sop-tier-check (#2139)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 2s
CI / Python Lint & Test (pull_request) Successful in 3s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
CI / Detect changes (pull_request) Successful in 11s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
E2E API Smoke Test / detect-changes (pull_request) Successful in 13s
E2E Chat / detect-changes (pull_request) Successful in 14s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 13s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
gate-check-v3 / gate-check (pull_request_target) Successful in 5s
qa-review / approved (pull_request_target) Failing after 5s
security-review / approved (pull_request_target) Failing after 5s
CI / Platform (Go) (pull_request) Successful in 1s
CI / Canvas (Next.js) (pull_request) Successful in 1s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 28s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 30s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1s
CI / all-required (pull_request) Successful in 18s
E2E Chat / E2E Chat (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 2s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m0s
CI / Canvas Deploy Status (pull_request) Has been skipped
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 1s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m37s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 4s
sop-tier-check / tier-check (pull_request_target) Successful in 9s
The qa (id 20) and security (id 21) Gitea teams have existed since the
2026-05-12 orchestrator preflight (verified via /orgs/{org}/teams), but
sop-tier-check.sh still treated them as pending placeholders (qa???,
security???). This meant tier:medium PRs could never satisfy the
qa/security clause — the script skipped unresolved ???-suffixed teams
and the clause always failed.

Changes:
- TIER_EXPR[tier:medium]: qa???,security??? → qa,security
- Update comment block to list the five live teams (ceo, engineers,
  managers, qa, security) and remove the internal#189 pending-team note.
- Update test_sop_tier_check_clause_split.sh fixture to match the real
  team names.

The ???-suffix fallback logic is preserved in the resolver so genuinely
missing future teams still fail closed with a clear error.

Closes #2139

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 03:51:52 +00:00
Molecule AI Dev Engineer A (Kimi) bb5fc5ecb8 fix(ci): address 5 CR2 blockers on umbrella-reaper (#1964)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
CI / Python Lint & Test (pull_request) Successful in 9s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 2s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 8s
E2E API Smoke Test / detect-changes (pull_request) Successful in 10s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 11s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 18s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 19s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 14s
CI / Detect changes (pull_request) Successful in 23s
E2E Chat / detect-changes (pull_request) Successful in 22s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
gate-check-v3 / gate-check (pull_request_target) Failing after 23s
qa-review / approved (pull_request_target) Failing after 24s
security-review / approved (pull_request_target) Failing after 22s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 7/7
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 21s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
sop-tier-check / tier-check (pull_request_target) Successful in 8s
CI / Platform (Go) (pull_request) Successful in 4s
CI / Canvas (Next.js) (pull_request) Successful in 4s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 3s
CI / Canvas Deploy Status (pull_request) Has been skipped
E2E Chat / E2E Chat (pull_request) Successful in 4s
CI / all-required (pull_request) Successful in 3s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 57s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m19s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m17s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m23s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m18s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m19s
1. REQUIRED_SUB_JOBS drift — derive from ci.yml at runtime by parsing
   the all-required job's inline Python script and extracting every
   f-string context pattern. Removes the hardcoded duplicate that could
   silently drift when ci.yml adds or removes a required job. Env var
   REQUIRED_SUB_JOBS still overrides for emergency tuning.

2. Silent POST failure — process_pr now returns bool; main tracks
   per-PR success and exits 1 if any compensating POST failed. Previously
   the exception was logged but the workflow run exited 0, masking
   token-permission or API outage regressions.

3. GITHUB_TOKEN fallback — removed || secrets.GITHUB_TOKEN from the
   workflow env. The script already fail-fasts on missing GITEA_TOKEN;
   the fallback weakened audit identity by allowing an ambient token.

4. Scheduled runner pressure — removed the */10 cron trigger from
   umbrella-reaper.yml and added operator-cron documentation matching
   status-reaper.yml. Maintenance bots should not consume Actions runner
   slots during merge waves.

5. Missing unit tests — added test_umbrella_reaper_api.py with 11 tests
   covering: compensation path, missing/pending/failed sub-jobs, umbrella
   missing, duplicate contexts, POST failure (nonzero exit), DRY_RUN
   behavior, and ci.yml derivation for both pull_request and push events.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 03:42:01 +00:00
Molecule AI Dev Engineer A (Kimi) 23c0fe73aa feat(ci): umbrella-reaper auto-recovery for stale CI umbrella statuses (#1780)
Adds a cron-driven workflow that scans open PRs every 10 minutes.
When CI / all-required (pull_request) is failure but all 5 required
sub-jobs (Detect changes, Platform Go, Canvas Next.js, Shellcheck,
Python Lint & Test) are verified success, posts a compensating success
status to unblock the merge gate.

This automates the manual recovery documented in:
docs/runbooks/ci-umbrella-stale-compensating-status.md

- .gitea/workflows/umbrella-reaper.yml  — cron workflow (*/10)
- .gitea/scripts/umbrella-reaper.py     — idempotent scan + compensate

The script is fail-closed: it only compensates when ALL required
sub-jobs are success. Any missing, pending, or failed sub-job causes
a skip with an honest log message.

Uses UMBRELLA_REAPER_TOKEN (falls back to GITHUB_TOKEN).

Closes #1780 acceptance criterion (auto-handles compensating-status).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 03:42:01 +00:00
Molecule AI Dev Engineer A (Kimi) 7a13fa8f9e ci: remove job-level if: from canvas-deploy-reminder to fix skipped-status poisoning (internal#817)
ci-arm64-advisory / fast-checks (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
CI / Python Lint & Test (pull_request) Successful in 3s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 5s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 8s
E2E API Smoke Test / detect-changes (pull_request) Successful in 11s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 12s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 18s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 17s
E2E Chat / detect-changes (pull_request) Successful in 18s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 13s
qa-review / approved (pull_request_target) Failing after 11s
CI / Platform (Go) (pull_request) Successful in 1s
security-review / approved (pull_request_target) Failing after 13s
CI / Canvas (Next.js) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 6s
E2E Chat / E2E Chat (pull_request) Successful in 2s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 8s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 3s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 4s
CI / Canvas Deploy Status (pull_request) Successful in 3s
CI / all-required (pull_request) Successful in 1s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 56s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m3s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m8s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m17s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m16s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m28s
gate-check-v3 / gate-check (pull_request_target) Successful in 21s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Successful in 1m20s
qa-review / approved (pull_request_review) Has been skipped
security-review / approved (pull_request_review) Has been skipped
sop-tier-check / tier-check (pull_request_review) Successful in 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
sop-tier-check / tier-check (pull_request_target) Successful in 6s
The canvas-deploy-reminder job used a job-level `if:` gating on
refs/heads/{main,staging}. On pull requests this caused the job to report
"skipped", and a skipped needed job poisons the PR combined status (GitHub/
Gitea treat skipped as a non-success terminal state for required contexts).

Fix by switching to per-step gating: the job always runs, but the step
short-circuits with exit 0 when the ref is not main/staging. This turns the
PR status from skipped → success.

Also add canvas-deploy-reminder to all-required.needs and the sentinel
environment/check so the job is actually aggregated into the required gate.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 09:53:54 +00:00
54 changed files with 2789 additions and 204 deletions
+60 -19
View File
@@ -54,32 +54,57 @@ API="https://${GITEA_HOST}/api/v1"
AUTH="Authorization: token ${GITEA_TOKEN}"
# 1. Fetch the PR. If not merged, no-op.
PR=$(curl -sS -H "$AUTH" "${API}/repos/${OWNER}/${NAME}/pulls/${PR_NUMBER}")
MERGED=$(echo "$PR" | jq -r '.merged // false')
# Fail-closed: verify HTTP 200 before parsing. A 401/403/404 means the token
# is invalid or the PR is inaccessible — we must NOT silently treat that as
# "not merged" and skip the audit.
PR_TMP=$(mktemp)
PR_HTTP=$(curl -sS -o "$PR_TMP" -w '%{http_code}' -H "$AUTH" \
"${API}/repos/${OWNER}/${NAME}/pulls/${PR_NUMBER}")
PR=$(cat "$PR_TMP")
rm -f "$PR_TMP"
if [ "$PR_HTTP" != "200" ]; then
echo "::error::GET /pulls/${PR_NUMBER} returned HTTP ${PR_HTTP} — cannot evaluate merge state."
exit 1
fi
# FAIL-CLOSED: a 200 response with a missing/malformed `merged` field must
# NOT be treated as "not merged" (that would silently skip the audit).
# We verify both presence AND correct type for every field we consume.
PR_SCHEMA_OK=$(echo "$PR" | jq -r '
(.merged | type == "boolean") and
(.merge_commit_sha | type == "string") and
(.merged_by | type == "object") and (.merged_by.login | type == "string") and
(.base | type == "object") and (.base.ref | type == "string") and
(.head | type == "object") and (.head.sha | type == "string")
')
if [ "$PR_SCHEMA_OK" != "true" ]; then
echo "::error::GET /pulls/${PR_NUMBER} returned HTTP 200 but one or more required fields are missing, null, or of wrong type — cannot evaluate force-merge."
exit 1
fi
MERGED=$(echo "$PR" | jq -r '.merged')
if [ "$MERGED" != "true" ]; then
echo "::notice::PR #${PR_NUMBER} closed without merge — no audit emission."
exit 0
fi
# NOTE: no || true — with set -euo pipefail, jq parse failures (e.g. field
# missing from API response) propagate as hard errors. Use jq's // operator
# for graceful defaults instead of bash || true guards. This was re-added by
# 8c343e3a ("fix(gitea): add || true guards to jq pipelines") — reverted
# here because the guards mask silent failures that hide malformed API responses.
MERGE_SHA=$(echo "$PR" | jq -r '.merge_commit_sha // empty')
MERGED_BY=$(echo "$PR" | jq -r '.merged_by.login // "unknown"')
MERGE_SHA=$(echo "$PR" | jq -r '.merge_commit_sha')
MERGED_BY=$(echo "$PR" | jq -r '.merged_by.login')
TITLE=$(echo "$PR" | jq -r '.title // ""')
BASE_BRANCH=$(echo "$PR" | jq -r '.base.ref // "main"')
HEAD_SHA=$(echo "$PR" | jq -r '.head.sha // empty')
if [ -z "$MERGE_SHA" ]; then
echo "::warning::PR #${PR_NUMBER} merged=true but no merge_commit_sha — cannot evaluate force-merge."
exit 0
fi
BASE_BRANCH=$(echo "$PR" | jq -r '.base.ref')
HEAD_SHA=$(echo "$PR" | jq -r '.head.sha')
# 2. Required status checks — branch-aware JSON dict takes precedence.
if [ -n "${REQUIRED_CHECKS_JSON:-}" ]; then
REQUIRED=$(echo "$REQUIRED_CHECKS_JSON" | jq -r --arg branch "$BASE_BRANCH" '.[$branch] // [] | .[]')
# FAIL-CLOSED: if REQUIRED_CHECKS_JSON is set, the branch entry must exist
# and be an array. A missing branch or non-array value means the config is
# malformed or drifted — we must NOT silently treat it as "no checks".
_RC_JSON_OK=$(echo "$REQUIRED_CHECKS_JSON" | jq -r --arg branch "$BASE_BRANCH" '
has($branch) and (.[$branch] | type == "array")
')
if [ "$_RC_JSON_OK" != "true" ]; then
echo "::error::REQUIRED_CHECKS_JSON missing or non-array entry for branch '$BASE_BRANCH' — cannot evaluate required checks."
exit 1
fi
REQUIRED=$(echo "$REQUIRED_CHECKS_JSON" | jq -r --arg branch "$BASE_BRANCH" '.[$branch] | .[]')
else
REQUIRED="$REQUIRED_CHECKS"
fi
@@ -91,12 +116,28 @@ fi
# 3. Status-check state at the PR HEAD (where checks ran). The merge
# commit doesn't get its own checks; we evaluate the PR's last
# commit, which is what branch protection compared against.
STATUS=$(curl -sS -H "$AUTH" \
# Fail-closed: verify HTTP 200. A 401/403/404 means the status is
# unreadable — we must NOT treat that as "no statuses" and skip checks.
STATUS_TMP=$(mktemp)
STATUS_HTTP=$(curl -sS -o "$STATUS_TMP" -w '%{http_code}' -H "$AUTH" \
"${API}/repos/${OWNER}/${NAME}/commits/${HEAD_SHA}/status")
STATUS=$(cat "$STATUS_TMP")
rm -f "$STATUS_TMP"
if [ "$STATUS_HTTP" != "200" ]; then
echo "::error::GET /commits/${HEAD_SHA}/status returned HTTP ${STATUS_HTTP} — cannot evaluate required checks."
exit 1
fi
# FAIL-CLOSED: a 200 status response missing the 'statuses' array, or with
# 'statuses' set to a non-array type (null/string/object), must NOT be treated
# as "no checks" — that would silently declare all checks green.
if ! echo "$STATUS" | jq -e '(.statuses | type) == "array"' >/dev/null; then
echo "::error::GET /commits/${HEAD_SHA}/status returned HTTP 200 but 'statuses' is missing or not an array — cannot evaluate required checks."
exit 1
fi
declare -A CHECK_STATE
while IFS=$'\t' read -r ctx state; do
[ -n "$ctx" ] && CHECK_STATE[$ctx]="$state"
done < <(echo "$STATUS" | jq -r '.statuses // [] | .[] | "\(.context)\t\(.status)"')
done < <(echo "$STATUS" | jq -r '.statuses | .[] | "\(.context)\t\(.status)"')
# 4. For each required check, was it green at merge? YAML block scalars
# (`|`) leave a trailing newline; skip blank/whitespace-only lines.
+26 -15
View File
@@ -552,23 +552,34 @@ def find_open_issue(title: str) -> dict | None:
hourly; failing one cycle loudly is strictly better than silently
duplicating.
Gitea issue search returns at most page=50 per page; one page is
enough as long as `[ci-drift]` issues are a tiny minority. (See
follow-up issue for Link-header pagination.)
Paginates through all open issues (limit=50 per page) until the
title is found or the result set is exhausted. Previously only one
page was fetched, causing duplicate [ci-drift] issues when the
existing tracking issue fell beyond page 1.
"""
_, results = api(
"GET",
f"/repos/{OWNER}/{NAME}/issues",
query={"state": "open", "type": "issues", "limit": "50"},
)
if not isinstance(results, list):
raise ApiError(
f"issue search returned non-list body (got {type(results).__name__})"
page = 1
while True:
_, results = api(
"GET",
f"/repos/{OWNER}/{NAME}/issues",
query={
"state": "open",
"type": "issues",
"limit": "50",
"page": str(page),
},
)
for issue in results:
if issue.get("title") == title:
return issue
return None
if not isinstance(results, list):
raise ApiError(
f"issue search returned non-list body (got {type(results).__name__})"
)
for issue in results:
if issue.get("title") == title:
return issue
# Fewer than limit results means last page reached.
if len(results) < 50:
return None
page += 1
def render_body(branch: str, findings: list[str], debug: dict) -> str:
+91 -27
View File
@@ -9,17 +9,33 @@ queue. This script provides the missing serialized policy in user space:
candidate (REQUEST_CHANGES, mergeable!=True, insufficient genuine approvals,
or red required CI) is SKIPPED so it cannot head-of-line block newer ready
PRs; the scan continues to the next candidate.
2. Refuse to act unless main's BP-required contexts are green.
2. Refuse to act unless main's BP-required contexts are green. This is also
the serialized backstop for direct-merge (see below): after a direct merge,
main re-runs push CI and this gate PAUSES the queue if main goes red, so no
merge piles onto an unverified/red main (issue #2358).
3. Refuse fork PRs; the queue may only mutate same-repo branches.
4. If the PR branch does not contain current main, call Gitea's
/pulls/{n}/update endpoint and stop. CI must rerun on the updated head.
4. DIRECT-MERGE when conflict-free (issue #2358). When Gitea reports the PR
conflict-free (mergeable is True) and the merge bar below is met, MERGE IT
DIRECTLY — even if its head does not contain current main. We do NOT call
/pulls/{n}/update first: branch protection does not require strict
up-to-date, so behind-main conflict-free PRs merge cleanly, and calling
/update would trigger Gitea dismiss_stale_approvals (dismissing the genuine
approvals and forcing a re-review every tick — the rebase-churn bottleneck).
The /update path is used ONLY when the PR is DEFINITIVELY not mergeable
(mergeable is literal False) AND its head lacks current main — refreshing the
branch may resolve a behind-main non-conflict; a real conflict returns HTTP
409 and the PR is HELD per #2352. mergeable=None/missing (Gitea STILL
COMPUTING conflict state) is a distinct fail-closed WAIT: never merged AND
never /update'd — calling /update during the compute window would dismiss the
PR's genuine approvals (dismiss_stale_approvals) and re-introduce the exact
rebase-churn this queue eliminates. None is re-checked next tick.
5. Merge ONLY when, on the PR's CURRENT head sha:
- >= REQUIRED_APPROVALS distinct GENUINE official APPROVED reviews from
the recognised reviewer set (not stale, not dismissed, commit_id ==
current head), AND
- no open official REQUEST_CHANGES on the current head, AND
- every BP-required status context is green, AND
- the PR is mergeable.
- the PR is mergeable (Gitea reports it conflict-free).
Authoritative gates (fail-closed):
- The REQUIRED status contexts come from BRANCH PROTECTION
@@ -622,29 +638,32 @@ def evaluate_merge_readiness(
approvers: set[str],
request_changes: list[str],
pr_has_current_base: bool,
mergeable: bool,
mergeable: bool | None,
pr_labels: set[str] | None = None,
) -> MergeDecision:
# 1) Main's push-required contexts must be green. Combined state can be
# "failure" due to non-blocking jobs (continue-on-error: true) that do
# not gate merges, so check the explicit required set, not combined.
#
# This main-green gate is ALSO the serialized backstop that makes the
# direct-merge (no update) path safe (issue #2358): after a direct merge
# of a behind-main PR, main re-runs its push CI; if a semantic main-break
# slips through (PR green standalone but broken when combined with newer
# main), main's required contexts go red and this gate PAUSES the queue —
# no further merge piles onto an unverified/red main until it is green.
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:
return MergeDecision(False, "pause", "main required contexts not green: " + ", ".join(main_bad))
# 2) PR head must contain current main.
if not pr_has_current_base:
return MergeDecision(False, "update", "PR head does not contain current main")
# 3) No open official REQUEST_CHANGES on the current head.
# 2) No open official REQUEST_CHANGES on the current head.
if request_changes:
return MergeDecision(
False, "wait",
"open REQUEST_CHANGES on current head from: " + ", ".join(sorted(request_changes)),
)
# 4) Enough distinct genuine official approvals on the current head.
# 3) Enough distinct genuine official approvals on the current head.
if len(approvers) < required_approvals:
return MergeDecision(
False, "wait",
@@ -653,7 +672,7 @@ def evaluate_merge_readiness(
f"need {required_approvals}",
)
# 5) Every BRANCH-PROTECTION-REQUIRED status context must be green. This is
# 4) Every BRANCH-PROTECTION-REQUIRED status context must be green. This is
# the authoritative status gate — NON-required reds (qa-review,
# security-review, sop-tier/sop-checklist when not BP-required, E2E Chat,
# Staging SaaS, ci-arm64-advisory, continue-on-error jobs) are NOT
@@ -663,16 +682,53 @@ def evaluate_merge_readiness(
if not ok:
return MergeDecision(False, "wait", "required contexts not green: " + ", ".join(missing_or_bad))
# 6) Gitea must consider the PR mergeable (no conflicts).
if not mergeable:
return MergeDecision(False, "wait", "PR is not mergeable (conflicts)")
# 5) DIRECT-MERGE when conflict-free (issue #2358 — throughput fix).
# If Gitea reports the PR conflict-free (mergeable is True), MERGE IT
# DIRECTLY even if its head does not yet contain current main. Branch
# protection does NOT require strict up-to-date, so a behind-main but
# conflict-free PR merges cleanly. We deliberately do NOT call
# /pulls/{n}/update first: update triggers Gitea dismiss_stale_approvals,
# which would dismiss the PR's genuine approvals and force a full
# re-review every tick — the rebase-churn bottleneck that collapsed
# throughput to ~0/hr with dozens of mergeable PRs open.
#
# The merge bar is UNCHANGED: we only reach here with main green +
# >= required genuine approvals on the current head + no open
# REQUEST_CHANGES + every BP-required context green. The trade-off is
# that the PR's CI ran on a possibly-behind base, so a SEMANTIC main-break
# is caught by POST-merge main CI (step 1's pause backstop) rather than
# pre-merge. force_merge is used ONLY for missing-but-non-required
# governance reds (required are green + approvals genuine), never to
# bypass a failing required context or an approval shortfall.
if mergeable is True:
force = _non_required_red_present(latest, required_contexts)
return MergeDecision(True, "merge", "ready", force=force)
# Ready. Use force_merge ONLY if the merge would otherwise be blocked by
# missing-but-non-required governance contexts. Required are green and
# approvals are genuine, so force only bypasses non-required reds — never a
# failing required context or missing approval.
force = _non_required_red_present(latest, required_contexts)
return MergeDecision(True, "merge", "ready", force=force)
# 6) NOT (yet) mergeable. TRI-STATE, fail-closed — never merge on an unknown.
# We MUST distinguish "still computing" (None/missing) from a "definitive
# conflict" (False); collapsing them would route a behind-main but
# STILL-COMPUTING PR into the /update path, whose dismiss_stale_approvals
# is the rebase-churn this change eliminates.
#
# mergeable is None → Gitea has NOT finished computing conflict state.
# WAIT: do nothing this tick — never /update (would dismiss genuine
# approvals during the compute window → churn), never merge. Re-check next
# tick once Gitea reports a decisive True/False.
if mergeable is None:
return MergeDecision(
False, "wait",
"PR mergeability is still being computed (mergeable=None) — waiting",
)
# mergeable is False → DEFINITIVE not-mergeable. If the head also does not
# contain current main, try the /update path to refresh the branch (this
# may resolve a behind-main non-conflict; a real conflict returns HTTP 409
# and process_once HOLDs the PR per #2352). If the head already contains
# current main yet Gitea still reports not-mergeable, there is nothing the
# queue can do (genuine conflict against current main) — WAIT.
if not pr_has_current_base:
return MergeDecision(False, "update", "PR not mergeable and head does not contain current main")
return MergeDecision(False, "wait", "PR is not mergeable (conflicts)")
def get_branch_head(branch: str) -> str:
@@ -1076,12 +1132,20 @@ def _evaluate_candidate(
# never treated as green).
pr_status = get_combined_status(head_sha)
pr_labels = label_names(pr)
# FAIL-CLOSED: Gitea returns mergeable=None (or omits the field) while it is
# still COMPUTING conflict state. Only the literal True is decisive proof the
# PR is conflict-free; None and False both mean "not (yet) mergeable". We must
# NOT autonomously merge on an unknown — treat anything but True as not-yet-
# mergeable so evaluate_merge_readiness returns a "wait" decision.
mergeable = pr.get("mergeable") is True
# FAIL-CLOSED, TRI-STATE: Gitea returns mergeable=None (or omits the field)
# while it is still COMPUTING conflict state, mergeable=False for a definitive
# conflict, and mergeable=True only when it has proven the PR conflict-free.
# We preserve all THREE states (do NOT collapse None/missing into False):
# - True → direct-merge eligible (step 5).
# - None / missing → still computing → WAIT (never merge, never update,
# never dismiss approvals); re-check next tick.
# - False → definitive conflict → the update/hold path (step 6).
# Collapsing None→False would route a behind-main but STILL-COMPUTING PR into
# the /update path, which triggers dismiss_stale_approvals — the exact
# rebase-churn this change eliminates. Normalize only to the literal True /
# False / None set (some Gitea versions omit the key entirely → None).
raw_mergeable = pr.get("mergeable")
mergeable: bool | None = raw_mergeable if isinstance(raw_mergeable, bool) else None
reviews = get_pull_reviews(pr_number)
approvers, request_changes = genuine_approvals(
@@ -305,9 +305,9 @@ def validate_tracker(
if status == "error":
sys.stderr.write(
f"::error::issue {slug}#{num} fetch errored — treating as "
f"unverified, skipping this check.\n"
f"unverified, FAILING CLOSED (do not skip on outage).\n"
)
return (True, "fetch-error — skipped")
return (False, f"{slug}#{num} fetch erroredcannot verify tracker")
assert payload is not None
state = payload.get("state", "")
+4 -8
View File
@@ -144,18 +144,14 @@ debug "tier=$TIER"
# as unachievable (would always fail) — operators notice the clear error
# and create the missing team.
#
# Current Gitea teams: ceo, engineers, managers
# Future teams (create before removing "???" fallback): qa, security, security-audit
# Current Gitea teams: ceo, engineers, managers, qa, security
declare -A TIER_EXPR=(
# tier:low — same as previous OR gate: any engineer, manager, or ceo.
["tier:low"]="engineers,managers,ceo"
# tier:medium — AND of (managers) AND (engineers) AND (qa???,security???)
# The qa+security clause requires both teams to exist; when not yet
# created, the PR author is responsible for adding them before requesting
# approval on a tier:medium PR. Ops: create qa + security Gitea teams
# and update this map to remove the "???" markers (internal#189 follow-up).
["tier:medium"]="managers AND engineers AND qa???,security???"
# tier:medium — AND of (managers) AND (engineers) AND (qa,security)
# ≥1 approver from managers AND ≥1 from engineers AND ≥1 from qa OR security.
["tier:medium"]="managers AND engineers AND qa,security"
# tier:high — ceo only. The AND-composition adds no value for a
# single-team gate, but the framework is wired for consistency.
+119
View File
@@ -0,0 +1,119 @@
#!/usr/bin/env bash
# test_audit_force_merge.sh — regression lock for audit-force-merge fail-closed
# behavior. Verifies every schema validation path via direct jq filter tests.
#
# Usage: bash test_audit_force_merge.sh
set -euo pipefail
fail() { echo "FAIL: $*" >&2; exit 1; }
pass() { echo "PASS: $*"; }
[ -x "$(command -v jq)" ] || { echo "SKIP: jq not on PATH"; exit 0; }
HEAD_SHA="deadbeef00000000000000000000000000000000"
# The schema validation jq expression from audit-force-merge.sh.
validate_pr_schema() {
jq -r '
(.merged | type == "boolean") and
(.merge_commit_sha | type == "string") and
(.merged_by | type == "object") and (.merged_by.login | type == "string") and
(.base | type == "object") and (.base.ref | type == "string") and
(.head | type == "object") and (.head.sha | type == "string")
'
}
validate_statuses_type() {
jq -r '(.statuses | type) == "array"'
}
# T1 — valid PR payload → true
T1=$(echo '{"merged":true,"merge_commit_sha":"abc","merged_by":{"login":"u"},"base":{"ref":"main"},"head":{"sha":"def"}}' | validate_pr_schema)
[ "$T1" = "true" ] || fail "T1: valid payload should pass schema"
pass "T1: valid payload passes schema"
# T2 — merged=false (valid types) → true (schema is about types, not values)
T2=$(echo '{"merged":false,"merge_commit_sha":"abc","merged_by":{"login":"u"},"base":{"ref":"main"},"head":{"sha":"def"}}' | validate_pr_schema)
[ "$T2" = "true" ] || fail "T2: merged=false with valid types should pass schema"
pass "T2: merged=false with valid types passes schema"
# T3 — missing merged field → false
T3=$(echo '{"merge_commit_sha":"abc","merged_by":{"login":"u"},"base":{"ref":"main"},"head":{"sha":"def"}}' | validate_pr_schema)
[ "$T3" = "false" ] || fail "T3: missing merged should fail schema"
pass "T3: missing merged fails schema"
# T4 — merged is string "true" instead of boolean → false
T4=$(echo '{"merged":"true","merge_commit_sha":"abc","merged_by":{"login":"u"},"base":{"ref":"main"},"head":{"sha":"def"}}' | validate_pr_schema)
[ "$T4" = "false" ] || fail "T4: merged as string should fail schema"
pass "T4: merged as string fails schema"
# T5 — merge_commit_sha is null → false
T5=$(echo '{"merged":true,"merge_commit_sha":null,"merged_by":{"login":"u"},"base":{"ref":"main"},"head":{"sha":"def"}}' | validate_pr_schema)
[ "$T5" = "false" ] || fail "T5: null merge_commit_sha should fail schema"
pass "T5: null merge_commit_sha fails schema"
# T6 — merged_by is null → false
T6=$(echo '{"merged":true,"merge_commit_sha":"abc","merged_by":null,"base":{"ref":"main"},"head":{"sha":"def"}}' | validate_pr_schema)
[ "$T6" = "false" ] || fail "T6: null merged_by should fail schema"
pass "T6: null merged_by fails schema"
# T7 — base.ref is number → false
T7=$(echo '{"merged":true,"merge_commit_sha":"abc","merged_by":{"login":"u"},"base":{"ref":123},"head":{"sha":"def"}}' | validate_pr_schema)
[ "$T7" = "false" ] || fail "T7: numeric base.ref should fail schema"
pass "T7: numeric base.ref fails schema"
# T8 — head is missing → false
T8=$(echo '{"merged":true,"merge_commit_sha":"abc","merged_by":{"login":"u"},"base":{"ref":"main"}}' | validate_pr_schema)
[ "$T8" = "false" ] || fail "T8: missing head should fail schema"
pass "T8: missing head fails schema"
# T9 — statuses missing → false
T9=$(echo '{}' | validate_statuses_type)
[ "$T9" = "false" ] || fail "T9: missing statuses should fail type check"
pass "T9: missing statuses fails type check"
# T10 — statuses is string → false
T10=$(echo '{"statuses":"unexpected"}' | validate_statuses_type)
[ "$T10" = "false" ] || fail "T10: string statuses should fail type check"
pass "T10: string statuses fails type check"
# T11 — statuses is null → false
T11=$(echo '{"statuses":null}' | validate_statuses_type)
[ "$T11" = "false" ] || fail "T11: null statuses should fail type check"
pass "T11: null statuses fails type check"
# T12 — statuses is array → true
T12=$(echo '{"statuses":[{"context":"c1","status":"success"}]}' | validate_statuses_type)
[ "$T12" = "true" ] || fail "T12: array statuses should pass type check"
pass "T12: array statuses passes type check"
# T13 — empty array statuses → true
T13=$(echo '{"statuses":[]}' | validate_statuses_type)
[ "$T13" = "true" ] || fail "T13: empty array statuses should pass type check"
pass "T13: empty array statuses passes type check"
# T14-T16: REQUIRED_CHECKS_JSON branch entry validation
validate_required_checks_json() {
local branch="$1"
local json="$2"
echo "$json" | jq -r --arg branch "$branch" 'has($branch) and (.[$branch] | type == "array")'
}
# T14 — branch exists and is array → true
T14=$(validate_required_checks_json "main" '{"main":["CI / all-required"]}')
[ "$T14" = "true" ] || fail "T14: existing array branch should pass"
pass "T14: existing array branch passes"
# T15 — branch missing → false
T15=$(validate_required_checks_json "staging" '{"main":["CI / all-required"]}')
[ "$T15" = "false" ] || fail "T15: missing branch should fail"
pass "T15: missing branch fails"
# T16 — branch entry is string instead of array → false
T16=$(validate_required_checks_json "main" '{"main":"CI / all-required"}')
[ "$T16" = "false" ] || fail "T16: string branch entry should fail"
pass "T16: string branch entry fails"
echo
echo "ALL AUDIT-FORCE-MERGE CHECKS PASSED"
+193 -5
View File
@@ -143,13 +143,72 @@ def test_merge_decision_requires_main_green_pr_green_and_current_base():
assert decision.force is False # no non-required reds present
def test_merge_decision_updates_stale_pr_before_merge():
decision = mq.evaluate_merge_readiness(**_ready_kwargs(pr_has_current_base=False))
def test_behind_main_but_mergeable_pr_merges_directly():
"""§SOP-22 (#2358): a behind-main but CONFLICT-FREE PR (mergeable is True)
merges DIRECTLY — no update step. Branch protection does not require strict
up-to-date, and calling /update would dismiss the genuine approvals
(dismiss_stale_approvals), forcing re-review every tick (the throughput
bottleneck). This replaces the old update-before-merge behavior."""
decision = mq.evaluate_merge_readiness(
**_ready_kwargs(pr_has_current_base=False, mergeable=True)
)
assert decision.ready is True
assert decision.action == "merge"
def test_behind_main_and_not_mergeable_pr_updates():
"""The /update path is reached ONLY when the PR is NOT mergeable AND its head
lacks current main — refreshing the branch may resolve a behind-main
non-conflict; a real conflict 409s and is held (#2352)."""
decision = mq.evaluate_merge_readiness(
**_ready_kwargs(pr_has_current_base=False, mergeable=False)
)
assert decision.ready is False
assert decision.action == "update"
def test_current_base_but_not_mergeable_pr_waits():
"""Up-to-date with main yet Gitea reports not-mergeable → genuine conflict
against current main (or still computing). The queue cannot act: WAIT,
never update (update would not help) and never merge (fail-closed)."""
decision = mq.evaluate_merge_readiness(
**_ready_kwargs(pr_has_current_base=True, mergeable=False)
)
assert decision.ready is False
assert decision.action == "wait"
assert "not mergeable" in decision.reason
def test_behind_main_and_mergeable_none_waits_not_update():
"""§SOP-22 (CR2 #2374) — the churn-residual fix. A BEHIND-MAIN PR whose
mergeability Gitea is STILL COMPUTING (mergeable is None) must WAIT, NOT take
the /update path. The old code collapsed None→False, so a behind-main +
None PR returned action="update" → /pulls/{n}/update → dismiss_stale_approvals
→ the exact rebase-churn this change eliminates, fired during the compute
window. None and False are now DISTINCT: None waits, False updates."""
decision = mq.evaluate_merge_readiness(
**_ready_kwargs(pr_has_current_base=False, mergeable=None)
)
assert decision.ready is False
assert decision.action == "wait" # NOT "update" — no churn during compute
assert "computed" in decision.reason
def test_current_base_and_mergeable_none_waits():
"""Up-to-date with main + mergeable None (still computing) → WAIT (unchanged
fail-closed; just confirming None is never merged regardless of base)."""
decision = mq.evaluate_merge_readiness(
**_ready_kwargs(pr_has_current_base=True, mergeable=None)
)
assert decision.ready is False
assert decision.action == "wait"
def test_MergePermissionError_inherits_from_ApiError():
assert issubclass(mq.MergePermissionError, mq.ApiError)
@@ -506,6 +565,131 @@ def test_process_once_merges_when_mergeable_is_true(monkeypatch):
assert calls["hold_label"] is None
def test_process_once_behind_main_mergeable_none_waits_no_update(monkeypatch):
"""§SOP-22 (CR2 #2374) — end-to-end churn-residual regression. A BEHIND-MAIN
PR (commits do NOT contain main_sha) whose mergeability Gitea is STILL
COMPUTING (mergeable=None) must WAIT: process_once returns 0 and NEVER calls
update_pull (which dismisses genuine approvals via dismiss_stale_approvals)
NOR merge_pull NOR hold. The old None→False collapse routed this exact case
into the /update path → approval-dismissing rebase churn during the compute
window. This proves the durable churn elimination: no update, approvals
preserved, re-checked next tick."""
calls = {"merge_attempts": 0, "hold_label": None, "updated": False}
_fully_ready_process_once_monkeypatch(monkeypatch, mergeable=None, calls=calls)
# Make the head BEHIND main: commits do NOT contain main_sha. This is the
# case the bug missed (the prior None test had current base, masking it).
behind_head = "a" * 40
monkeypatch.setattr(mq, "get_pull_commits", lambda n: [{"sha": behind_head}])
rc = mq.process_once(dry_run=False)
assert rc == 0
assert calls["updated"] is False # NO /update → approvals NOT dismissed
assert calls["merge_attempts"] == 0 # never merge on an unknown
assert calls["hold_label"] is None # transient → not held, retried next tick
# --------------------------------------------------------------------------
# §SOP-22: DIRECT-MERGE throughput fix (#2358). A conflict-free 2-genuine PR
# merges WITHOUT a pre-merge /update call, so its approvals are NOT dismissed by
# dismiss_stale_approvals. The merge bar (2-genuine-on-current-head +
# BP-required green + mergeable + no RC + opt-out) is UNCHANGED; only the
# unnecessary update-before-merge churn is removed. The /update path survives
# for the genuine case it is needed (not-mergeable + behind-main), where a real
# conflict 409s and is held per #2352. mergeable=None stays fail-closed.
# --------------------------------------------------------------------------
def test_process_once_merges_conflict_free_pr_without_update(monkeypatch):
"""§SOP-22(a) — the core throughput fix. A conflict-free, fully-approved PR
merges WITHOUT update_pull ever being called. The old behavior called
/update first whenever the head lacked current main, which dismissed the 2
genuine approvals (dismiss_stale_approvals) and forced re-review every tick.
Assert update_pull is NOT invoked and merge_pull IS invoked."""
calls = {"merge_attempts": 0, "hold_label": None, "updated": False}
_fully_ready_process_once_monkeypatch(monkeypatch, mergeable=True, calls=calls)
# Make the head BEHIND main: commits do NOT contain main_sha. Under the old
# logic this alone forced an update_pull; under the fix it merges directly.
head_sha = "a" * 40
monkeypatch.setattr(mq, "get_pull_commits", lambda n: [{"sha": head_sha}])
rc = mq.process_once(dry_run=False)
assert rc == 0
assert calls["merge_attempts"] == 1 # merged directly
assert calls["updated"] is False # NO update_pull → approvals NOT dismissed
assert calls["hold_label"] is None
def test_process_once_behind_main_conflict_free_merges_directly(monkeypatch):
"""§SOP-22(b) — explicit behind-main + conflict-free case: it still merges
directly (branch protection does not require strict up-to-date)."""
calls = {"merge_attempts": 0, "hold_label": None, "updated": False}
_fully_ready_process_once_monkeypatch(monkeypatch, mergeable=True, calls=calls)
behind_head = "a" * 40
monkeypatch.setattr(mq, "get_pull_commits", lambda n: [{"sha": behind_head}])
rc = mq.process_once(dry_run=False)
assert rc == 0
assert calls["merge_attempts"] == 1
assert calls["updated"] is False
def test_process_once_pauses_when_main_not_green_no_direct_merge(monkeypatch):
"""§SOP-22 backstop — the serialized safety that makes direct-merge safe:
when main's required push contexts are NOT green (e.g. a prior direct merge
introduced a semantic main-break caught by post-merge main CI), the queue
PAUSES — it does NOT merge the next PR onto an unverified/red main."""
calls = {"merge_attempts": 0, "hold_label": None, "updated": False}
_fully_ready_process_once_monkeypatch(monkeypatch, mergeable=True, calls=calls)
main_sha = "b" * 40
def red_main_combined(sha):
if sha == main_sha:
return {"state": "failure",
"statuses": [{"context": "CI / all-required (push)", "status": "failure"}]}
return {"state": "success",
"statuses": [{"context": "CI / all-required (pull_request)", "status": "success"}]}
monkeypatch.setattr(mq, "get_combined_status", red_main_combined)
rc = mq.process_once(dry_run=False)
assert rc == 0
assert calls["merge_attempts"] == 0 # paused — no merge onto red main
assert calls["updated"] is False
def test_direct_merge_bar_unchanged_behind_main(monkeypatch):
"""§SOP-22(d) — the merge bar is UNCHANGED on the new direct-merge path. A
behind-main + conflict-free PR is still rejected (no merge) when ANY gate
fails: insufficient genuine approvals, red required context, open
REQUEST_CHANGES, or opt-out label. Direct-merge removes the update churn, it
does NOT weaken the bar — fail-closed on every gate."""
head_sha = "a" * 40
behind_main = dict(pr_has_current_base=False, mergeable=True)
# <2 genuine approvals → wait, not merge.
d = mq.evaluate_merge_readiness(
**_ready_kwargs(approvers={"agent-researcher"}, **behind_main)
)
assert d.action == "wait" and d.ready is False
# Red required context → wait, not merge.
red_required = {"state": "failure", "statuses": [
{"context": "CI / all-required (pull_request)", "status": "failure"}]}
d = mq.evaluate_merge_readiness(
**_ready_kwargs(pr_status=red_required, **behind_main)
)
assert d.action == "wait" and d.ready is False
# Open REQUEST_CHANGES on current head → wait, not merge.
d = mq.evaluate_merge_readiness(
**_ready_kwargs(request_changes=["agent-reviewer-cr2"], **behind_main)
)
assert d.action == "wait" and d.ready is False
# --------------------------------------------------------------------------
# Fix 3: status fetch is fail-closed (failed fetch != green)
# --------------------------------------------------------------------------
@@ -707,13 +891,17 @@ def _stale_pr_update_409_monkeypatch(monkeypatch, queued_issues, calls):
# Scan-loop process_once enumerates candidates via list_candidate_issues.
monkeypatch.setattr(mq, "list_candidate_issues", lambda *, auto_discover: queued_issues)
monkeypatch.setattr(mq, "get_pull", lambda n: {
"state": "open", "number": n, "mergeable": True,
"state": "open", "number": n, "mergeable": False,
"base": {"ref": "main", "repo_id": 1},
"head": {"sha": head_sha, "repo_id": 1},
"labels": [{"name": "merge-queue"}],
})
# NOTE: commits do NOT contain main_sha → pr_has_current_base is False →
# decision.action == "update".
# NOTE: mergeable is False (real conflict) AND commits do NOT contain
# main_sha → pr_has_current_base is False → decision.action == "update".
# Under the #2358 direct-merge fix the update path is reached ONLY when the
# PR is NOT mergeable; a mergeable=True behind-main PR would merge directly,
# so this fixture sets mergeable=False to exercise the #2352 409-on-update
# hold path.
monkeypatch.setattr(mq, "get_pull_commits", lambda n: [{"sha": head_sha}])
monkeypatch.setattr(mq, "get_pull_reviews", lambda n: [
{"state": "APPROVED", "user": {"login": "agent-researcher"},
@@ -57,12 +57,12 @@ echo "test: tier:low OR-clause splits to 3 tokens"
assert_eq "tier:low" "engineers|managers|ceo" "$(split_clause "engineers,managers,ceo")"
echo "test: tier:medium AND-expression — bash word-split on \$EXPR yields 5 tokens"
EXPR="managers AND engineers AND qa???,security???"
EXPR="managers AND engineers AND qa,security"
out=""
for _raw in $EXPR; do
out="${out}${out:+ ; }$(split_clause "$_raw")"
done
assert_eq "tier:medium" "managers ; AND ; engineers ; AND ; qa???|security???" "$out"
assert_eq "tier:medium" "managers ; AND ; engineers ; AND ; qa|security" "$out"
echo "test: tier:high single-team OR-clause"
assert_eq "tier:high" "ceo" "$(split_clause "ceo")"
@@ -0,0 +1,474 @@
import importlib.util
import json
import pathlib
import urllib.error
ROOT = pathlib.Path(__file__).resolve().parents[1]
SCRIPT = ROOT / "umbrella-reaper.py"
def load_reaper():
spec = importlib.util.spec_from_file_location("umbrella_reaper", SCRIPT)
mod = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(mod)
mod.API = "https://git.example.test/api/v1"
mod.GITEA_TOKEN = "fixture-token"
mod.GITEA_HOST = "git.example.test"
mod.REPO = "owner/repo"
return mod
class FakeResponse:
status = 200
def __init__(self, payload):
self.payload = payload
def __enter__(self):
return self
def __exit__(self, exc_type, exc, tb):
return False
def read(self):
return json.dumps(self.payload).encode("utf-8")
def _pr_fixture(number: int, sha: str) -> dict:
return {"number": number, "head": {"sha": sha}}
def _status_entry(context: str, state: str) -> dict:
return {"context": context, "status": state}
def test_process_pr_compensates_when_all_sub_jobs_success(monkeypatch):
mod = load_reaper()
posted = []
def fake_post_status(sha, context, description):
posted.append((sha, context, description))
monkeypatch.setattr(mod, "post_status", fake_post_status)
monkeypatch.setattr(
mod,
"REQUIRED_SUB_JOBS",
[
"CI / Detect changes (pull_request)",
"CI / Platform (Go) (pull_request)",
],
)
pr = _pr_fixture(1, "abc123")
def fake_combined_status(sha):
return {
"statuses": [
_status_entry("CI / all-required (pull_request)", "failure"),
_status_entry("CI / Detect changes (pull_request)", "success"),
_status_entry("CI / Platform (Go) (pull_request)", "success"),
]
}
monkeypatch.setattr(mod, "get_combined_status", fake_combined_status)
ok = mod.process_pr(pr)
assert ok is True
assert len(posted) == 1
assert posted[0][0] == "abc123"
assert posted[0][1] == "CI / all-required (pull_request)"
assert "Compensating status" in posted[0][2]
def test_process_pr_skips_when_umbrella_missing(monkeypatch):
mod = load_reaper()
posted = []
monkeypatch.setattr(mod, "post_status", lambda *a, **k: posted.append(a))
monkeypatch.setattr(mod, "REQUIRED_SUB_JOBS", ["CI / Platform (Go) (pull_request)"])
pr = _pr_fixture(2, "def456")
def fake_combined_status(sha):
return {
"statuses": [
_status_entry("CI / Platform (Go) (pull_request)", "success"),
]
}
monkeypatch.setattr(mod, "get_combined_status", fake_combined_status)
ok = mod.process_pr(pr)
assert ok is True
assert posted == []
def test_process_pr_skips_when_sub_job_pending(monkeypatch):
mod = load_reaper()
posted = []
monkeypatch.setattr(mod, "post_status", lambda *a, **k: posted.append(a))
monkeypatch.setattr(
mod,
"REQUIRED_SUB_JOBS",
[
"CI / Detect changes (pull_request)",
"CI / Platform (Go) (pull_request)",
],
)
pr = _pr_fixture(3, "ghi789")
def fake_combined_status(sha):
return {
"statuses": [
_status_entry("CI / all-required (pull_request)", "failure"),
_status_entry("CI / Detect changes (pull_request)", "success"),
_status_entry("CI / Platform (Go) (pull_request)", "pending"),
]
}
monkeypatch.setattr(mod, "get_combined_status", fake_combined_status)
ok = mod.process_pr(pr)
assert ok is True
assert posted == []
def test_process_pr_skips_when_sub_job_failure(monkeypatch):
mod = load_reaper()
posted = []
monkeypatch.setattr(mod, "post_status", lambda *a, **k: posted.append(a))
monkeypatch.setattr(
mod,
"REQUIRED_SUB_JOBS",
[
"CI / Detect changes (pull_request)",
"CI / Platform (Go) (pull_request)",
],
)
pr = _pr_fixture(4, "jkl012")
def fake_combined_status(sha):
return {
"statuses": [
_status_entry("CI / all-required (pull_request)", "failure"),
_status_entry("CI / Detect changes (pull_request)", "success"),
_status_entry("CI / Platform (Go) (pull_request)", "failure"),
]
}
monkeypatch.setattr(mod, "get_combined_status", fake_combined_status)
ok = mod.process_pr(pr)
assert ok is True
assert posted == []
def test_process_pr_returns_false_on_post_failure(monkeypatch):
mod = load_reaper()
def fake_post_status(sha, context, description):
raise mod.ApiError("POST /statuses/abc123 -> HTTP 500: simulated failure")
monkeypatch.setattr(mod, "post_status", fake_post_status)
monkeypatch.setattr(
mod,
"REQUIRED_SUB_JOBS",
[
"CI / Detect changes (pull_request)",
"CI / Platform (Go) (pull_request)",
],
)
pr = _pr_fixture(5, "abc123")
def fake_combined_status(sha):
return {
"statuses": [
_status_entry("CI / all-required (pull_request)", "failure"),
_status_entry("CI / Detect changes (pull_request)", "success"),
_status_entry("CI / Platform (Go) (pull_request)", "success"),
]
}
monkeypatch.setattr(mod, "get_combined_status", fake_combined_status)
ok = mod.process_pr(pr)
assert ok is False
def test_main_exits_nonzero_when_any_post_fails(monkeypatch):
mod = load_reaper()
monkeypatch.setenv("GITEA_TOKEN", "fixture-token")
monkeypatch.setenv("GITEA_HOST", "git.example.test")
monkeypatch.setenv("REPO", "owner/repo")
monkeypatch.setattr(
mod,
"REQUIRED_SUB_JOBS",
[
"CI / Detect changes (pull_request)",
"CI / Platform (Go) (pull_request)",
],
)
monkeypatch.setattr(
mod,
"list_open_prs",
lambda limit: [
_pr_fixture(1, "abc123"),
_pr_fixture(2, "def456"),
],
)
calls = {"n": 0}
def fake_combined_status(sha):
return {
"statuses": [
_status_entry("CI / all-required (pull_request)", "failure"),
_status_entry("CI / Detect changes (pull_request)", "success"),
_status_entry("CI / Platform (Go) (pull_request)", "success"),
]
}
monkeypatch.setattr(mod, "get_combined_status", fake_combined_status)
def fake_post_status(sha, context, description):
calls["n"] += 1
if calls["n"] == 2:
raise mod.ApiError("simulated failure")
monkeypatch.setattr(mod, "post_status", fake_post_status)
exit_code = mod.main()
assert exit_code == 1
def test_main_exits_zero_when_all_posts_succeed(monkeypatch):
mod = load_reaper()
monkeypatch.setenv("GITEA_TOKEN", "fixture-token")
monkeypatch.setenv("GITEA_HOST", "git.example.test")
monkeypatch.setenv("REPO", "owner/repo")
monkeypatch.setattr(
mod,
"REQUIRED_SUB_JOBS",
[
"CI / Detect changes (pull_request)",
"CI / Platform (Go) (pull_request)",
],
)
monkeypatch.setattr(
mod,
"list_open_prs",
lambda limit: [_pr_fixture(1, "abc123")],
)
def fake_combined_status(sha):
return {
"statuses": [
_status_entry("CI / all-required (pull_request)", "failure"),
_status_entry("CI / Detect changes (pull_request)", "success"),
_status_entry("CI / Platform (Go) (pull_request)", "success"),
]
}
monkeypatch.setattr(mod, "get_combined_status", fake_combined_status)
monkeypatch.setattr(mod, "post_status", lambda *a, **k: None)
exit_code = mod.main()
assert exit_code == 0
def test_dry_run_does_not_post(monkeypatch):
mod = load_reaper()
api_calls = []
def fake_api(method, path, *, body=None, query=None, expect_json=True):
api_calls.append((method, path, body))
return 200, {"ok": True}
monkeypatch.setattr(mod, "api", fake_api)
monkeypatch.setattr(
mod,
"REQUIRED_SUB_JOBS",
[
"CI / Detect changes (pull_request)",
"CI / Platform (Go) (pull_request)",
],
)
pr = _pr_fixture(6, "mno345")
def fake_combined_status(sha):
return {
"statuses": [
_status_entry("CI / all-required (pull_request)", "failure"),
_status_entry("CI / Detect changes (pull_request)", "success"),
_status_entry("CI / Platform (Go) (pull_request)", "success"),
]
}
monkeypatch.setattr(mod, "get_combined_status", fake_combined_status)
monkeypatch.setattr(mod, "DRY_RUN", True)
ok = mod.process_pr(pr)
assert ok is True
# DRY_RUN should prevent the POST /statuses call
assert not any(
method == "POST" and "/statuses/" in path for method, path, _ in api_calls
)
def test_duplicate_contexts_use_latest_state(monkeypatch):
mod = load_reaper()
posted = []
monkeypatch.setattr(mod, "post_status", lambda *a, **k: posted.append(a))
monkeypatch.setattr(
mod,
"REQUIRED_SUB_JOBS",
[
"CI / Detect changes (pull_request)",
],
)
pr = _pr_fixture(7, "pqr678")
def fake_combined_status(sha):
return {
"statuses": [
_status_entry("CI / all-required (pull_request)", "failure"),
# duplicate: first pending, then success — the loop overwrites
_status_entry("CI / Detect changes (pull_request)", "pending"),
_status_entry("CI / Detect changes (pull_request)", "success"),
]
}
monkeypatch.setattr(mod, "get_combined_status", fake_combined_status)
ok = mod.process_pr(pr)
assert ok is True
assert len(posted) == 1
def test_load_required_sub_jobs_from_ci_yml_pull_request_event():
mod = load_reaper()
# UMBRELLA_CONTEXT defaults to pull_request, so derivation should yield
# the pull_request suffix.
jobs = mod._load_required_sub_jobs_from_ci_yml(".gitea/workflows")
assert all(j.endswith(" (pull_request)") for j in jobs)
assert "CI / Detect changes (pull_request)" in jobs
assert "CI / Python Lint & Test (pull_request)" in jobs
def test_load_required_sub_jobs_from_ci_yml_push_event(monkeypatch):
mod = load_reaper()
monkeypatch.setattr(mod, "UMBRELLA_CONTEXT", "CI / all-required (push)")
jobs = mod._load_required_sub_jobs_from_ci_yml(".gitea/workflows")
assert all(j.endswith(" (push)") for j in jobs)
assert "CI / Detect changes (push)" in jobs
def test_list_open_prs_paginates(monkeypatch):
mod = load_reaper()
calls = []
def fake_api(method, path, *, body=None, query=None, expect_json=True):
calls.append(query)
page = int(query.get("page", 1))
limit = int(query.get("limit", 50))
if page == 1:
return 200, [{"number": 1}, {"number": 2}]
if page == 2:
return 200, [{"number": 3}]
return 200, []
monkeypatch.setattr(mod, "api", fake_api)
prs = mod.list_open_prs(limit=2)
assert len(prs) == 3
assert prs[0]["number"] == 1
assert prs[2]["number"] == 3
assert calls[0]["page"] == "1"
assert calls[1]["page"] == "2"
def test_process_pr_returns_false_on_status_fetch_failure(monkeypatch):
mod = load_reaper()
def fake_get_combined_status(sha):
raise mod.ApiError("GET /statuses/abc123 -> HTTP 500: simulated outage")
monkeypatch.setattr(mod, "get_combined_status", fake_get_combined_status)
monkeypatch.setattr(
mod,
"REQUIRED_SUB_JOBS",
["CI / Detect changes (pull_request)"],
)
pr = _pr_fixture(8, "abc123")
ok = mod.process_pr(pr)
assert ok is False
def test_process_pr_returns_false_on_missing_statuses_array(monkeypatch):
mod = load_reaper()
def fake_get_combined_status(sha):
return {"state": "success"} # missing 'statuses' array
monkeypatch.setattr(mod, "get_combined_status", fake_get_combined_status)
monkeypatch.setattr(
mod,
"REQUIRED_SUB_JOBS",
["CI / Detect changes (pull_request)"],
)
pr = _pr_fixture(9, "def456")
ok = mod.process_pr(pr)
assert ok is False
def test_main_exits_nonzero_when_any_status_read_fails(monkeypatch):
mod = load_reaper()
monkeypatch.setenv("GITEA_TOKEN", "fixture-token")
monkeypatch.setenv("GITEA_HOST", "git.example.test")
monkeypatch.setenv("REPO", "owner/repo")
monkeypatch.setattr(
mod,
"REQUIRED_SUB_JOBS",
[
"CI / Detect changes (pull_request)",
"CI / Platform (Go) (pull_request)",
],
)
monkeypatch.setattr(
mod,
"list_open_prs",
lambda limit: [
_pr_fixture(1, "abc123"),
_pr_fixture(2, "def456"),
],
)
def fake_combined_status(sha):
if sha == "abc123":
return {
"statuses": [
_status_entry("CI / all-required (pull_request)", "failure"),
_status_entry("CI / Detect changes (pull_request)", "success"),
_status_entry("CI / Platform (Go) (pull_request)", "success"),
]
}
raise mod.ApiError("simulated status fetch failure")
monkeypatch.setattr(mod, "get_combined_status", fake_combined_status)
monkeypatch.setattr(mod, "post_status", lambda *a, **k: None)
exit_code = mod.main()
assert exit_code == 1
+360
View File
@@ -0,0 +1,360 @@
#!/usr/bin/env python3
"""umbrella-reaper — auto-recovery for stale CI umbrella statuses on PRs.
Tracking: molecule-core#1780.
Sibling to status-reaper.py (default-branch push-suffix compensation),
but scoped to pull_request umbrellas instead of main-branch contexts.
What this script does, per `.gitea/workflows/umbrella-reaper.yml` invocation:
1. List open PRs via GET /repos/{o}/{r}/pulls?state=open&limit={N}.
2. For EACH PR:
- GET combined commit status for PR head SHA.
- Look for the umbrella context (default: "CI / all-required (pull_request)").
- If umbrella state is "failure":
- Verify ALL required sub-job contexts are "success".
- If yes → POST compensating success to /statuses/{sha} with the
same umbrella context and an honest description.
- If any required sub-job is NOT success → skip (umbrella correctly
reflects reality; do NOT lie).
- If umbrella state is "success" or "pending" → skip.
3. Exit 0. Re-running is idempotent — Gitea de-dups by context.
What it does NOT do:
- Touch non-umbrella contexts.
- Compensate when ANY required sub-job is missing, pending, failure, or
cancelled. Only the "all sub-jobs green, umbrella stale" race.
- Merge PRs. It only posts a status; branch protection still requires
human approval.
- Run on closed PRs.
Halt conditions:
- Missing required env vars → exit 1 with ::error:: message.
- API 5xx on PR list → fail-loud (can't assess state).
- API 5xx on an individual PR's status → ::warning:: + continue to next PR.
"""
from __future__ import annotations
import json
import os
import re
import sys
import urllib.error
import urllib.parse
import urllib.request
from pathlib import Path
from typing import Any
def _load_required_sub_jobs_from_ci_yml(workflows_dir: str) -> list[str]:
"""Parse ci.yml and extract the all-required sentinel's sub-job contexts.
Supports two shapes of the all-required job run block:
1. Legacy Python f-string list (pre-2026-06-01):
f"CI / Detect changes ({event})"
2. Current shell-script shape (post-2026-06-01 scheduler fix):
check "Detect changes" "$CHANGES_RESULT"
Raises RuntimeError if ci.yml is missing, has no all-required job, or the
run block cannot be parsed.
"""
ci_path = Path(workflows_dir) / "ci.yml"
if not ci_path.exists():
raise RuntimeError(f"ci.yml not found at {ci_path}")
# PyYAML is installed by the workflow (same as status-reaper.py).
import yaml
with ci_path.open() as f:
doc = yaml.safe_load(f)
jobs = doc.get("jobs", {})
all_required = jobs.get("all-required")
if not isinstance(all_required, dict):
raise RuntimeError("ci.yml missing 'all-required' job")
steps = all_required.get("steps", [])
run_block = ""
for step in steps:
if isinstance(step, dict):
run_text = step.get("run", "")
if run_text:
run_block = run_text
break
if not run_block:
raise RuntimeError("all-required job missing run block")
# Determine event suffix from the umbrella context we are watching.
if UMBRELLA_CONTEXT.endswith(" (pull_request)"):
suffix = "(pull_request)"
elif UMBRELLA_CONTEXT.endswith(" (push)"):
suffix = "(push)"
else:
m = re.search(r' \(([^)]+)\)$', UMBRELLA_CONTEXT)
suffix = m.group(1) if m else "pull_request"
# Try legacy f-string format first.
if "({event})" in run_block:
matches = re.findall(r'f["\'](.*?\(\{event\}\))["\']', run_block)
if matches:
return [m.replace("({event})", suffix) for m in matches]
# Try current shell-script format: check "Name" "$RESULT"
matches = re.findall(r'check\s+"([^"]+)"', run_block)
if matches:
return [f"CI / {name} {suffix}" for name in matches]
raise RuntimeError("unable to derive required sub-jobs from all-required run block")
# --------------------------------------------------------------------------
# Environment
# --------------------------------------------------------------------------
def _env(key: str, *, default: str = "") -> str:
return os.environ.get(key, default)
GITEA_TOKEN = _env("GITEA_TOKEN")
GITEA_HOST = _env("GITEA_HOST")
REPO = _env("REPO")
DRY_RUN = _env("DRY_RUN", default="").lower() in ("1", "true", "yes")
# The umbrella context to watch. Must match the branch-protection name
# exactly (Gitea de-dups by context string).
UMBRELLA_CONTEXT = _env("UMBRELLA_CONTEXT", default="CI / all-required (pull_request)")
# Required sub-job contexts. The umbrella is only compensated when ALL of
# these are "success" on the same SHA. Order does not matter.
#
# Derive from ci.yml at runtime to prevent drift (CR2 blocker #1).
# The env var REQUIRED_SUB_JOBS overrides derivation for emergency
# tuning or local testing.
_REQUIRED_SUB_JOBS_OVERRIDE = _env("REQUIRED_SUB_JOBS")
if _REQUIRED_SUB_JOBS_OVERRIDE:
REQUIRED_SUB_JOBS = [
ctx.strip()
for ctx in _REQUIRED_SUB_JOBS_OVERRIDE.split(";")
if ctx.strip()
]
else:
try:
REQUIRED_SUB_JOBS = _load_required_sub_jobs_from_ci_yml(".gitea/workflows")
except Exception as exc:
sys.stderr.write(
f"::error::Failed to derive REQUIRED_SUB_JOBS from ci.yml: {exc}\n"
)
sys.exit(1)
OWNER, NAME = (REPO.split("/", 1) + [""])[:2] if REPO else ("", "")
API = f"https://{GITEA_HOST}/api/v1" if GITEA_HOST else ""
PR_LIMIT = int(_env("PR_LIMIT", default="50"))
def _require_runtime_env() -> None:
for key in ("GITEA_TOKEN", "GITEA_HOST", "REPO"):
if not os.environ.get(key):
sys.stderr.write(f"::error::missing required env var: {key}\n")
sys.exit(1)
# --------------------------------------------------------------------------
# Tiny HTTP helper
# --------------------------------------------------------------------------
class ApiError(RuntimeError):
pass
def api(
method: str,
path: str,
*,
body: dict | None = None,
query: dict[str, str] | None = None,
expect_json: bool = True,
) -> tuple[int, Any]:
url = f"{API}{path}"
if query:
url = f"{url}?{urllib.parse.urlencode(query)}"
data = None
headers = {
"Authorization": f"token {GITEA_TOKEN}",
"Accept": "application/json",
}
if body is not None:
data = json.dumps(body).encode("utf-8")
headers["Content-Type"] = "application/json"
req = urllib.request.Request(url, method=method, data=data, headers=headers)
try:
with urllib.request.urlopen(req, timeout=30) as resp:
raw = resp.read()
status = resp.status
except urllib.error.HTTPError as e:
raw = e.read()
status = e.code
if not (200 <= status < 300):
snippet = raw[:500].decode("utf-8", errors="replace") if raw else ""
raise ApiError(f"{method} {path} -> HTTP {status}: {snippet}")
if not raw:
return status, None
try:
return status, json.loads(raw)
except json.JSONDecodeError as e:
if expect_json:
raise ApiError(
f"{method} {path} -> HTTP {status} but body is not JSON: {e}"
) from e
return status, {"_raw": raw.decode("utf-8", errors="replace")}
# --------------------------------------------------------------------------
# Gitea reads / writes
# --------------------------------------------------------------------------
def list_open_prs(limit: int = 50) -> list[dict]:
"""Paginate through all open PR pages. Fail closed on non-list responses."""
all_prs: list[dict] = []
page = 1
while True:
_, body = api(
"GET",
f"/repos/{OWNER}/{NAME}/pulls",
query={"state": "open", "limit": str(limit), "page": str(page)},
)
if not isinstance(body, list):
raise ApiError(f"PR list page {page} response is not a JSON array")
if not body:
break
all_prs.extend(body)
if len(body) < limit:
break
page += 1
return all_prs
def get_combined_status(sha: str) -> dict:
_, body = api("GET", f"/repos/{OWNER}/{NAME}/commits/{sha}/status")
if not isinstance(body, dict):
raise ApiError(f"status for {sha} response is not a JSON object")
return body
def post_status(sha: str, context: str, description: str) -> None:
payload = {
"context": context,
"state": "success",
"description": description,
}
if DRY_RUN:
print(f"[DRY-RUN] Would POST /statuses/{sha}: {json.dumps(payload)}")
return
api("POST", f"/repos/{OWNER}/{NAME}/statuses/{sha}", body=payload)
# --------------------------------------------------------------------------
# Core logic
# --------------------------------------------------------------------------
def _entry_state(s: dict) -> str:
return s.get("status") or s.get("state") or ""
def process_pr(pr: dict) -> bool:
"""Process a single PR. Returns True if the tick succeeded for this PR
(including no-op skips), False if a compensating POST failed.
"""
num = pr.get("number")
sha = pr.get("head", {}).get("sha")
if not sha:
print(f"::warning::PR #{num}: missing head.sha; skipping")
return True
try:
status = get_combined_status(sha)
except ApiError as e:
print(f"::error::PR #{num}: status fetch failed: {e}")
return False
statuses = status.get("statuses")
if not isinstance(statuses, list):
print(f"::error::PR #{num}: combined status missing 'statuses' array")
return False
umbrella_entry = None
subjob_states: dict[str, str] = {}
for s in statuses:
if not isinstance(s, dict):
continue
ctx = s.get("context", "")
state = _entry_state(s)
if ctx == UMBRELLA_CONTEXT:
umbrella_entry = s
if ctx in REQUIRED_SUB_JOBS:
subjob_states[ctx] = state
if umbrella_entry is None:
print(f"::notice::PR #{num}: no umbrella context '{UMBRELLA_CONTEXT}'; skipping")
return True
umbrella_state = _entry_state(umbrella_entry)
if umbrella_state != "failure":
print(f"::notice::PR #{num}: umbrella is '{umbrella_state}'; skipping")
return True
# Verify ALL required sub-jobs are present and success
missing = [ctx for ctx in REQUIRED_SUB_JOBS if ctx not in subjob_states]
if missing:
print(
f"::notice::PR #{num}: umbrella=failure, but missing sub-jobs: {missing}; "
"skipping (sub-jobs may still be running)"
)
return True
not_success = [ctx for ctx in REQUIRED_SUB_JOBS if subjob_states[ctx] != "success"]
if not_success:
print(
f"::notice::PR #{num}: umbrella=failure, but sub-jobs not all success: "
f"{[(ctx, subjob_states[ctx]) for ctx in not_success]}; skipping"
)
return True
# All checks pass — post compensating status
desc = (
"Compensating status: all required sub-jobs verified success; "
"umbrella stale due to commit-status propagation race. "
f"Auto-posted by umbrella-reaper for PR #{num}."
)
try:
post_status(sha, UMBRELLA_CONTEXT, desc)
print(f"::notice::PR #{num}: posted compensating success for {UMBRELLA_CONTEXT}")
return True
except ApiError as e:
print(f"::error::PR #{num}: failed to post compensating status: {e}")
return False
def main() -> int:
_require_runtime_env()
# Drift guard: ci.yml derivation already happened at module load, but
# we sanity-check it is non-empty so the loop below doesn't trivially
# no-op because of a parse bug.
if not REQUIRED_SUB_JOBS:
sys.stderr.write("::error::REQUIRED_SUB_JOBS is empty; bailing out\n")
return 1
prs = list_open_prs(limit=PR_LIMIT)
print(f"::notice::Scanning {len(prs)} open PRs for stale umbrella statuses")
compensated = 0
failed = 0
for pr in prs:
ok = process_pr(pr)
if not ok:
failed += 1
print(f"::notice::umbrella-reaper complete (failed POSTs={failed})")
return 1 if failed else 0
if __name__ == "__main__":
sys.exit(main())
@@ -34,6 +34,8 @@ jobs:
check:
name: Block forbidden paths
runs-on: ubuntu-latest
# Hard gate — detected internal-path leaks fail the workflow.
# continue-on-error removed per directive (fail-open → fail-closed).
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
@@ -0,0 +1,165 @@
name: boot-to-registration-e2e (advisory)
# cp#455 — Minimal-cell boot-to-registration e2e.
# CTO directive 14eb4f07: "build the minimal claude-code+kimi cell,
# it should now go GREEN since the fix is live."
#
# Stage 1 of 5-stage rollout. Reuses the dispatch-only EC2
# provisioning path from test_staging_full_saas.sh but reduced to
# the minimum boot-to-registration surface:
#
# 1. Provision request accepted; workspace transitions to booting/running
# 2. Controlplane receives /registry/register for that workspace_id
# 3. JSON-RPC/completion route returns successful minimal response
# 4. Teardown terminates workspace even on failure (trap)
#
# Advisory (non-blocking) per Researcher Stage 2 design — RED on
# current main is expected pre-cp#469-cluster. After cp#477 deploy
# (888efceb) + PR #2167 merge, cell should turn GREEN. THAT green
# is the cluster-proof signal.
#
# Cost controls (mandatory):
# - SPOT instances (tagged run_id/workspace_id for cost attribution)
# - Fast teardown (~3-5 min wall-clock) even on assertion failure
# - Structured per-cell results JSON (runtime/provider/model/
# billing_mode/workspace_id/register_status/completion_status/
# teardown_status/elapsed_seconds)
#
# Inputs:
# runtime : default claude-code
# billing_mode : default platform_managed (the cp#469-cluster path)
# provider : default platform (vs direct-to-provider)
# model : default moonshot/kimi-k2.6 (CTO-specified)
#
# PR target: molecule-core (this file). Companion harness extension
# (test_minimal_boot_cell.sh) lives in tests/e2e/ alongside
# test_staging_full_saas.sh — same repo, same branch.
#
# Note: cp#455 was originally spec'd to live in molecule-controlplane
# (`.gitea/workflows/` path), but molecule-core's CI is the home for
# tenant-boot e2e tests in this stage. Stage 2 may move the path.
on:
workflow_dispatch:
# Note: Gitea 1.22.6 does not support workflow_dispatch.inputs
# (feedback_gitea_workflow_dispatch_inputs_unsupported). Defaults
# are hardcoded in the job env below. Stage 2 can add matrix/
# param support once the Gitea version supports it.
# Advisory: no cron schedule, manual dispatch only. Branch protection
# doesn't require this — RED on main is expected pre-cp#469-cluster
# deploy, GREEN signals the cluster is live.
permissions:
contents: read
# No issue-write; failures surface as red runs in workflow history.
concurrency:
group: boot-to-registration-e2e
cancel-in-progress: false
jobs:
# bp-exempt: advisory e2e — non-gating, manual dispatch only (cp#455 Stage 1)
minimal-cell:
name: Minimal cell (claude-code + platform + moonshot/kimi-k2.6)
runs-on: ubuntu-latest
# Bounded at 12 min. Wall-clock budget breakdown:
# - cold EC2 provision: ~3-4 min (SPOT)
# - /registry/register wait: ~30s
# - completion call: ~10s
# - teardown: ~30-60s
# - tail headroom: ~6-7 min
timeout-minutes: 12
env:
# Hardcoded defaults — Gitea 1.22.6 does not support workflow_dispatch.inputs
# (feedback_gitea_workflow_dispatch_inputs_unsupported). Stage 2 can add
# matrix/param support once the Gitea version supports it.
E2E_RUNTIME: claude-code
E2E_BILLING_MODE: platform_managed
E2E_PROVIDER: platform
E2E_MODEL: moonshot/kimi-k2.6
E2E_RUN_ID: cp455-${{ github.run_id }}
E2E_PROVISION_TIMEOUT_SECS: '300' # 5 min — fast teardown budget
MOLECULE_CP_URL: ${{ vars.STAGING_CP_URL || 'https://staging-api.moleculesai.app' }}
MOLECULE_ADMIN_TOKEN: ${{ secrets.CP_STAGING_ADMIN_API_TOKEN }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Verify required secrets present
run: |
if [ -z "${MOLECULE_ADMIN_TOKEN:-}" ]; then
echo "::error::CP_STAGING_ADMIN_API_TOKEN secret missing — minimal-cell e2e cannot run"
echo "::error::Set it at Settings → Secrets and Variables → Actions; pull from staging-CP's CP_ADMIN_API_TOKEN env in Railway."
exit 1
fi
- name: Install required tools
run: |
for cmd in jq curl python3; do
command -v "$cmd" >/dev/null 2>&1 || {
echo "::error::required tool '$cmd' not on PATH — runner image regression?"
exit 1
}
done
- name: Run minimal-cell boot-to-registration harness
# The harness script handles its own teardown via EXIT trap;
# even on assertion failure (provision timeout, register
# timeout, completion failure), the workspace is deprovisioned
# and a leak is reported. Exit code propagates from the script.
# Structured per-cell results are emitted to ${GITHUB_STEP_SUMMARY}
# so operators see pass/fail per assertion without scrolling.
run: |
bash tests/e2e/test_minimal_boot_cell.sh
- name: Emit structured per-cell results
if: always()
# Always run (even on failure) so the structured results are
# visible in the workflow summary. The script writes a JSON
# file at /tmp/cell-result.json; this step renders it as a
# job summary.
run: |
if [ -f /tmp/cell-result.json ]; then
echo "## Minimal-cell results" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo '```json' >> "$GITHUB_STEP_SUMMARY"
cat /tmp/cell-result.json >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
else
echo "## Minimal-cell results: NO_RESULT_FILE" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Harness did not produce /tmp/cell-result.json — likely crashed before trap fired." >> "$GITHUB_STEP_SUMMARY"
fi
- name: Failure summary
if: failure()
run: |
{
echo "## cp#455 minimal-cell FAILED"
echo ""
echo "**Run ID:** ${{ github.run_id }}"
echo "**Runtime:** ${E2E_RUNTIME}"
echo "**Billing mode:** ${E2E_BILLING_MODE}"
echo "**Provider:** ${E2E_PROVIDER}"
echo "**Model:** ${E2E_MODEL}"
echo "**Slug:** ${E2E_RUN_ID}"
echo ""
echo "### What this means"
echo ""
echo "The minimal claude-code+kimi cell did not pass all 4 assertions:"
echo "1. Provision request accepted; workspace transitions to booting/running"
echo "2. Controlplane receives /registry/register for that workspace_id"
echo "3. JSON-RPC/completion route returns successful minimal response"
echo "4. Teardown terminates workspace even on failure (trap)"
echo ""
echo "RED is expected pre-cp#469-cluster. After cp#477 deploy (888efceb) + PR #2167 merge,"
echo "this should turn GREEN. Persistent RED after both merge = cluster bug, not e2e bug."
echo ""
echo "### Next steps"
echo ""
echo "1. Check the harness output above for the assertion that failed"
echo "2. If assertion 1 fails: provision path broken — check CP admin API + EC2 quota"
echo "3. If assertion 2 fails: /registry/register path broken — check workspace-server boot"
echo "4. If assertion 3 fails: LLM proxy / completion path broken — check cp#469 cluster"
echo "5. If assertion 4 fails: teardown trap broken — leak risk, fix immediately"
} >> "$GITHUB_STEP_SUMMARY"
+7 -6
View File
@@ -418,10 +418,9 @@ jobs:
# a manual action that determinism made obsolete.
name: Canvas Deploy Status
runs-on: docker-host
# Job-level `if:` so ci-required-drift.py's ci_job_names() detects this as
# github.ref-gated and skips it from the required-context F1 set (mc#1982).
# Per-step no-op (not job-level `if:`) so the job reaches SUCCESS on PRs
# instead of skipped — skipped poisons the PR combined status (internal#817).
# Step-level exit 0 handles the "not a canvas main push" case.
if: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging' }}
needs: [changes, canvas-build]
steps:
- name: Record canvas ordered-deploy status
@@ -533,9 +532,8 @@ jobs:
# The `needs:` list MUST stay in lockstep with ci-required-drift.py's
# F1 check (`ci_job_names()` = every job MINUS the sentinel MINUS jobs
# whose `if:` gates on github.event_name/github.ref). canvas-deploy-
# reminder is event-gated (`if: github.ref == refs/heads/{main,staging}`)
# so it is intentionally EXCLUDED — it skips on PRs and a `needs:` on a
# skipped job would never let the sentinel run. If a new always-running
# status is per-step-gated (not job-level `if:`) so it reaches SUCCESS
# on PRs and is included here — internal#817. If a new always-running
# CI job is added, add it here too or ci-required-drift F1 will flag it.
#
# Stays on the dedicated `ci-meta` lane (no docker work, so the
@@ -549,6 +547,7 @@ jobs:
- canvas-build
- shellcheck
- python-lint
- canvas-deploy-status
continue-on-error: false
runs-on: ci-meta
timeout-minutes: 5
@@ -567,6 +566,7 @@ jobs:
CANVAS_RESULT: ${{ needs.canvas-build.result }}
SHELLCHECK_RESULT: ${{ needs.shellcheck.result }}
PYTHON_LINT_RESULT: ${{ needs.python-lint.result }}
CANVAS_DEPLOY_RESULT: ${{ needs.canvas-deploy-status.result }}
run: |
set -euo pipefail
fail=0
@@ -588,6 +588,7 @@ jobs:
check "Canvas (Next.js)" "$CANVAS_RESULT"
check "Shellcheck (E2E scripts)" "$SHELLCHECK_RESULT"
check "Python Lint & Test" "$PYTHON_LINT_RESULT"
check "Canvas Deploy Status" "$CANVAS_DEPLOY_RESULT"
if [ "$fail" -ne 0 ]; then
echo "::error::all-required: one or more aggregated CI jobs did not succeed"
exit 1
+3 -3
View File
@@ -131,9 +131,9 @@ jobs:
# on the per-runtime default ("sonnet" → routes to direct
# Anthropic, defeats the cost saving). Operators can override
# via workflow_dispatch by setting a different E2E_MODEL_SLUG
# input if they need to exercise a specific model. MiniMax-M2 is the
# stable staging MiniMax path used by the full-SaaS smoke.
E2E_MODEL_SLUG: ${{ github.event.inputs.model_slug || 'MiniMax-M2' }}
# input if they need to exercise a specific model. MiniMax-M2.7 is the
# stable staging MiniMax path used by the full-SaaS smoke (#1997).
E2E_MODEL_SLUG: ${{ github.event.inputs.model_slug || 'MiniMax-M2.7' }}
# Bound to 10 min so a stuck provision fails the run instead of
# holding up the next cron firing. 15-min default in the script
# is for the on-PR full lifecycle where we have more headroom.
+14
View File
@@ -250,6 +250,20 @@ jobs:
echo "CANVAS_PORT=${CANVAS_PORT}" >> "$GITHUB_ENV"
echo "Canvas host port: ${CANVAS_PORT}"
- name: Set deterministic admin token
if: needs.detect-changes.outputs.chat == 'true'
run: |
# PR #2291 made auth fail-closed everywhere (no dev-mode escape).
# The platform server requires ADMIN_TOKEN; the canvas requires the
# matching NEXT_PUBLIC_ADMIN_TOKEN or every API call 401s.
# We set a deterministic per-run value so the ephemeral platform
# and canvas are paired correctly.
E2E_ADMIN_TOKEN="e2e-chat-admin-${{ github.run_id }}-${{ github.run_attempt }}"
echo "ADMIN_TOKEN=${E2E_ADMIN_TOKEN}" >> "$GITHUB_ENV"
echo "MOLECULE_ADMIN_TOKEN=${E2E_ADMIN_TOKEN}" >> "$GITHUB_ENV"
echo "NEXT_PUBLIC_ADMIN_TOKEN=${E2E_ADMIN_TOKEN}" >> "$GITHUB_ENV"
echo "Admin token configured for e2e-chat platform + canvas."
- name: Start platform (background)
if: needs.detect-changes.outputs.chat == 'true'
working-directory: workspace-server
@@ -40,6 +40,7 @@ env:
GITHUB_SERVER_URL: https://git.moleculesai.app
jobs:
# bp-exempt: informational lint enforcing docker-host/publish pin convention (internal#512), not a merge gate
lint-docker-host-pin:
name: Lint docker-host pin on docker-touching workflows
runs-on: docker-host
+3 -3
View File
@@ -112,9 +112,9 @@ jobs:
E2E_RUNTIME: claude-code
# Pin the smoke to a specific MiniMax model rather than relying
# on the per-runtime default (which could resolve to "sonnet" →
# direct Anthropic and defeat the cost saving). MiniMax-M2 is the
# stable staging MiniMax path used by the full-SaaS smoke.
E2E_MODEL_SLUG: MiniMax-M2
# direct Anthropic and defeat the cost saving). MiniMax-M2.7 is the
# stable staging MiniMax path used by the full-SaaS smoke (#1997).
E2E_MODEL_SLUG: MiniMax-M2.7
E2E_RUN_ID: "smoke-${{ github.run_id }}"
# Debug-only: when an operator dispatches with keep_on_failure=true,
# the smoke script's E2E_KEEP_ORG=1 path skips teardown so the
+7 -4
View File
@@ -34,8 +34,10 @@ name: Sweep stale Cloudflare DNS records
# scripts/ops/test_sweep_cf_decide.py (#2027) cover the rule
# classifier.
#
# Secrets: CF_API_TOKEN, CF_ZONE_ID, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
# are confirmed existing per issue #425 §425 audit. CP_ADMIN_API_TOKEN and
# Secrets: CF_API_TOKEN (preferred CI-scoped name) or CLOUDFLARE_API_TOKEN
# (operator-host canonical name) are accepted — the workflow falls back
# automatically. Same for CF_ZONE_ID / CLOUDFLARE_ZONE_ID. Confirmed
# existing per issue #425 §425 audit. CP_ADMIN_API_TOKEN and
# CP_STAGING_ADMIN_API_TOKEN are unconfirmed — if missing, the verify step
# (schedule → hard-fail, dispatch → soft-skip) surfaces it clearly.
@@ -79,8 +81,8 @@ jobs:
# each individually capped at 10s by the script's curl -m flag.
timeout-minutes: 3
env:
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
CF_ZONE_ID: ${{ secrets.CF_ZONE_ID }}
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN || secrets.CLOUDFLARE_API_TOKEN }}
CF_ZONE_ID: ${{ secrets.CF_ZONE_ID || secrets.CLOUDFLARE_ZONE_ID }}
CP_ADMIN_API_TOKEN: ${{ secrets.CP_ADMIN_API_TOKEN }}
CP_STAGING_ADMIN_API_TOKEN: ${{ secrets.CP_STAGING_ADMIN_API_TOKEN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@@ -129,6 +131,7 @@ jobs:
fi
echo "::error::sweep cannot run — required secrets missing: ${missing[*]}"
echo "::error::set them at Settings → Secrets and Variables → Actions, or disable this workflow."
echo "::error::Cloudflare secrets accept either the CI-scoped name (CF_API_TOKEN / CF_ZONE_ID) or the operator-host canonical name (CLOUDFLARE_API_TOKEN / CLOUDFLARE_ZONE_ID)."
echo "::error::a silent skip masked an active CF DNS leak (152/200 zone records) caught only by a manual audit on 2026-04-28; this gate exists to make the gap visible."
exit 1
fi
+8 -6
View File
@@ -29,10 +29,12 @@ name: Sweep stale Cloudflare Tunnels
# the DNS sweep's 50% because tenant-shaped tunnels are mostly
# orphans by design) refuses to nuke past the threshold.
#
# Secrets: CF_API_TOKEN, CF_ACCOUNT_ID are confirmed existing per
# issue #425 §425 audit. CP_ADMIN_API_TOKEN and CP_STAGING_ADMIN_API_TOKEN
# are unconfirmed — if missing, the verify step (schedule → hard-fail,
# dispatch → soft-skip) surfaces it clearly.
# Secrets: CF_API_TOKEN (preferred CI-scoped name) or CLOUDFLARE_API_TOKEN
# (operator-host canonical name) are accepted — the workflow falls back
# automatically. Same for CF_ACCOUNT_ID / CLOUDFLARE_ACCOUNT_ID. Confirmed
# existing per issue #425 §425 audit. CP_ADMIN_API_TOKEN and
# CP_STAGING_ADMIN_API_TOKEN are unconfirmed — if missing, the verify step
# (schedule → hard-fail, dispatch → soft-skip) surfaces it clearly.
on:
schedule:
@@ -74,8 +76,8 @@ jobs:
# the sweep-cf-orphans companion job).
timeout-minutes: 30
env:
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN || secrets.CLOUDFLARE_API_TOKEN }}
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID || secrets.CLOUDFLARE_ACCOUNT_ID }}
CP_ADMIN_API_TOKEN: ${{ secrets.CP_ADMIN_API_TOKEN }}
CP_STAGING_ADMIN_API_TOKEN: ${{ secrets.CP_STAGING_ADMIN_API_TOKEN }}
MAX_DELETE_PCT: ${{ github.event.inputs.max_delete_pct || '90' }}
+67
View File
@@ -0,0 +1,67 @@
# umbrella-reaper — auto-recovery for stale CI umbrella statuses on open PRs.
#
# Tracking: molecule-core#1780.
#
# Problem: when `CI / all-required (pull_request)` reports failure due to
# a propagation/timing race despite all required sub-jobs being success,
# branch protection blocks the merge. Operators currently recover manually
# per docs/runbooks/ci-umbrella-stale-compensating-status.md.
#
# This workflow automates that recovery: it scans open PRs and posts a
# compensating success status when the umbrella is stale but all sub-jobs
# are verified green.
#
# Trust boundary: the script only reads PR lists + statuses and POSTs to
# /statuses/{sha}. It never checks out PR HEAD code. The Gitea token has
# write:repository scope for statuses only.
#
# Sibling: .gitea/workflows/status-reaper.yml (default-branch push-suffix
# compensation). Same persona provisioning model.
name: umbrella-reaper
# IMPORTANT — Schedule moved to operator-config:
# /etc/cron.d/molecule-core-umbrella-reaper ->
# /usr/local/bin/molecule-core-cron-bot.sh umbrella-reaper
#
# This keeps the compensation cadence but stops a maintenance bot from
# consuming Gitea Actions runner slots during PR merge waves.
# Gitea 1.22.6 parser quirk per
# `feedback_gitea_workflow_dispatch_inputs_unsupported`: do NOT add an
# `inputs:` block here. Gitea 1.22.6 rejects the whole workflow as
# "unknown on type" when `workflow_dispatch.inputs.X` is present.
on:
workflow_dispatch:
permissions:
contents: read
# NOTE: NO `concurrency:` block is intentional — same reasoning as
# status-reaper.yml. Gitea 1.22.6 doesn't honor cancel-in-progress for
# queued ticks; the POST is idempotent so concurrent ticks are safe.
jobs:
reap:
runs-on: ubuntu-latest
timeout-minutes: 8
steps:
- name: Check out repo at default-branch HEAD
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
ref: ${{ github.event.repository.default_branch }}
- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: '3.12'
- name: Install PyYAML
run: python -m pip install --quiet 'PyYAML==6.0.2'
- name: Compensate stale PR umbrella statuses
env:
GITEA_TOKEN: ${{ secrets.UMBRELLA_REAPER_TOKEN }}
GITEA_HOST: git.moleculesai.app
REPO: ${{ github.repository }}
PR_LIMIT: "50"
run: python3 .gitea/scripts/umbrella-reaper.py
+5 -1
View File
@@ -27,9 +27,13 @@ export async function seedWorkspace(echoURL: string): Promise<SeededWorkspace> {
// 1. Create external workspace pointing at the in-process echo runtime.
const runId = Math.random().toString(36).slice(2, 8);
const wsName = `Chat E2E Agent ${runId}`;
const adminToken = process.env.E2E_ADMIN_TOKEN ?? process.env.ADMIN_TOKEN;
const createRes = await fetch(`${PLATFORM_URL}/workspaces`, {
method: "POST",
headers: { "Content-Type": "application/json" },
headers: {
"Content-Type": "application/json",
...(adminToken ? { Authorization: `Bearer ${adminToken}` } : {}),
},
body: JSON.stringify({
name: wsName,
tier: 1,
+51 -31
View File
@@ -234,30 +234,44 @@ export default async function globalSetup(_config: FullConfig): Promise<void> {
"Authorization": `Bearer ${tenantToken}`,
"X-Molecule-Org-Id": orgID,
};
const ws = await jsonFetch(`${tenantURL}/workspaces`, {
method: "POST",
headers: tenantAuth,
body: JSON.stringify({
name: "E2E Canvas Test",
runtime: "hermes",
tier: 2,
// Provider-registry SSOT (internal#718) registers ONLY Kimi models for
// the hermes runtime — `moonshot/kimi-k2.6` is the platform-managed
// entry (workspace-server/internal/providers/providers.yaml, hermes ->
// platform). The old `gpt-4o` was never a registered hermes model and
// now 422s UNREGISTERED_MODEL_FOR_RUNTIME (core#2225). This workspace
// defaults closed to platform_managed (see the boot-shape note below),
// so a platform-namespaced model id is the registry-correct choice.
model: "moonshot/kimi-k2.6",
}),
});
if (ws.status >= 400 || !ws.body?.id) {
throw new Error(`Workspace create ${ws.status}: ${JSON.stringify(ws.body)}`);
// Retry workspace creation on transient 5xx / timeout — staging CP can
// return 502/503/504 under load and a single-shot failure kills the
// entire E2E run. 3 attempts with 3s exponential backoff (3s, 6s, 12s)
// gives ~21s total budget, well inside the 20-min provision envelope.
let workspaceId = "";
for (let attempt = 1; attempt <= 3; attempt++) {
const ws = await jsonFetch(`${tenantURL}/workspaces`, {
method: "POST",
headers: tenantAuth,
body: JSON.stringify({
name: "E2E Canvas Test",
runtime: "hermes",
tier: 2,
// Provider-registry SSOT (internal#718) registers ONLY Kimi models for
// the hermes runtime — `moonshot/kimi-k2.6` is the platform-managed
// entry (workspace-server/internal/providers/providers.yaml, hermes ->
// platform). The old `gpt-4o` was never a registered hermes model and
// now 422s UNREGISTERED_MODEL_FOR_RUNTIME (core#2225). This workspace
// defaults closed to platform_managed (see the boot-shape note below),
// so a platform-namespaced model id is the registry-correct choice.
model: "moonshot/kimi-k2.6",
}),
});
if (ws.status >= 200 && ws.status < 300 && ws.body?.id) {
workspaceId = ws.body.id as string;
break;
}
const isTransient = ws.status >= 500 || ws.status === 0;
if (!isTransient || attempt === 3) {
throw new Error(`Workspace create ${ws.status} (attempt ${attempt}): ${JSON.stringify(ws.body)}`);
}
const backoff = 3000 * Math.pow(2, attempt - 1);
console.log(`[staging-setup] Workspace create transient ${ws.status}, retrying in ${backoff}ms...`);
await new Promise((r) => setTimeout(r, backoff));
}
const workspaceId = ws.body.id as string;
console.log(`[staging-setup] Workspace created: ${workspaceId}`);
// 6. Wait for workspace RENDERABLE.
// 6. Wait for workspace online
//
// This harness exists to verify the canvas *tab UI* renders (staging-
// tabs.spec.ts: open each of the 13 workspace-panel tabs, assert no hard
@@ -266,6 +280,16 @@ export default async function globalSetup(_config: FullConfig): Promise<void> {
// it needs is a workspace ROW that the canvas lists so the node renders
// and the side-panel tabs open. A fully-`online` agent is NOT required.
//
// Hermes cold-boot takes 10-13 min on slow apt days (apt + uv + hermes
// install + npm browser-tools). The controlplane bootstrap-watcher
// deadline fires at 5 min and sets status=failed prematurely; heartbeat
// then transitions failed → online after install.sh finishes. The ONLY
// failed shape we tolerate is the pre-start credential-abort
// (uptime_seconds=0, no last_sample_error) — the agent never ran. Real
// boot regressions (image pull error, panic, PYTHONPATH, etc.) still
// hard-throw immediately so triage gets detail without waiting for a
// polling timeout. See test_staging_full_saas.sh step 7/11 and issue #2632.
//
// That distinction became load-bearing on 2026-06-03: workspace-server
// #2162 (fix(provision): platform-managed workspace must fail-closed when
// CP proxy env absent) made a platform_managed workspace ABORT AT BOOT
@@ -287,8 +311,10 @@ export default async function globalSetup(_config: FullConfig): Promise<void> {
// the node + tabs render, proceed. We do NOT mask a real boot regression:
// any `failed` carrying a last_sample_error, OR a non-zero uptime (the
// agent started then crashed — image pull, panic, PYTHONPATH, etc.),
// still hard-throws. Genuine *infra* provision failure is already caught
// loud one step earlier at the org level (instance_status === "failed").
// still hard-throws immediately so triage gets boot_stage / last_error /
// image fields without waiting for a polling timeout.
// Genuine *infra* provision failure is already caught loud one step
// earlier at the org level (instance_status === "failed").
await waitFor<boolean>(
async () => {
const r = await jsonFetch(`${tenantURL}/workspaces/${workspaceId}`, {
@@ -315,13 +341,7 @@ export default async function globalSetup(_config: FullConfig): Promise<void> {
);
return true;
}
// last_sample_error is often empty when the failure happens before
// the agent emits a sample (e.g. boot crash, image pull error,
// missing PYTHONPATH, OpenAI quota at startup). Dumping the full
// body gives triage the boot_stage / last_error / image fields it
// needs without a second probe. Otherwise this propagates as a
// bare "Workspace failed: " — the exact useless message that
// sent #2632 to the issue tracker.
// Real boot regression — hard-throw immediately with full detail.
const detail = sampleErr
? sampleErr
: `(no last_sample_error) full body: ${JSON.stringify(r.body)}`;
@@ -333,7 +353,7 @@ export default async function globalSetup(_config: FullConfig): Promise<void> {
10_000,
"workspace online",
);
console.log(`[staging-setup] Workspace renderable`);
console.log(`[staging-setup] Workspace online`);
// 7. Hand state off to tests + teardown — overwrite the slug-only
// bootstrap state with the full state spec tests need.
+1 -1
View File
@@ -370,7 +370,7 @@ test.describe("staging canvas tabs", () => {
// The tablist appears once the side panel mounts. Condition-based
// wait — no fixed delay.
const tablist = page.locator('[role="tablist"]');
const tablist = page.getByRole("tablist", { name: "Workspace panel tabs" });
await expect(
tablist,
"side panel tablist never appeared after clicking the workspace node",
+2 -2
View File
@@ -172,7 +172,7 @@ export function ContextMenu() {
const nodeId = contextMenu.nodeId;
closeContextMenu();
try {
await api.post(`/workspaces/${nodeId}/pause`, {});
await api.post(`/workspaces/${nodeId}/pause?cascade=true`, {});
updateNodeData(nodeId, { status: "paused" });
} catch (e) {
showToast("Pause failed", "error");
@@ -184,7 +184,7 @@ export function ContextMenu() {
const nodeId = contextMenu.nodeId;
closeContextMenu();
try {
await api.post(`/workspaces/${nodeId}/resume`, {});
await api.post(`/workspaces/${nodeId}/resume?cascade=true`, {});
updateNodeData(nodeId, { status: "provisioning" });
} catch (e) {
showToast("Resume failed", "error");
@@ -385,7 +385,7 @@ describe("ContextMenu — item actions", () => {
render(<ContextMenu />);
fireEvent.click(screen.getByRole("menuitem", { name: /pause/i }));
await act(async () => { /* flush */ });
expect(mockPost).toHaveBeenCalledWith("/workspaces/n1/pause", {});
expect(mockPost).toHaveBeenCalledWith("/workspaces/n1/pause?cascade=true", {});
expect(mockStoreState.updateNodeData).toHaveBeenCalledWith("n1", { status: "paused" });
});
@@ -395,7 +395,7 @@ describe("ContextMenu — item actions", () => {
render(<ContextMenu />);
fireEvent.click(screen.getByRole("menuitem", { name: /resume/i }));
await act(async () => { /* flush */ });
expect(mockPost).toHaveBeenCalledWith("/workspaces/n1/resume", {});
expect(mockPost).toHaveBeenCalledWith("/workspaces/n1/resume?cascade=true", {});
});
});
+1 -1
View File
@@ -324,7 +324,7 @@ export const useCanvasStore = create<CanvasState>((set, get) => ({
batchPause: async () => {
const ids = Array.from(get().selectedNodeIds);
const results = await Promise.allSettled(
ids.map((id) => api.post(`/workspaces/${id}/pause`))
ids.map((id) => api.post(`/workspaces/${id}/pause?cascade=true`))
);
const failed: string[] = [];
results.forEach((r, i) => {
+3 -3
View File
@@ -2,7 +2,7 @@
**Status:** living document — update when you ship a feature that touches one backend.
**Owner:** workspace-server + controlplane teams.
**Last audit:** 2026-05-07 (plugin install/uninstall closed for EC2 backend via EIC SSH push to the bind-mounted `/configs/plugins/<name>/`, mirroring the Files API PR #1702 pattern).
**Last audit:** 2026-05-31 (Claude agent — drift risk #6 verified resolved; nil guards present, contract tests run without Skip).
## Why this exists
@@ -93,12 +93,12 @@ For "do we have any backend?", use `HasProvisioner()`, never bare `h.provisioner
3. **Restart divergence on runtime changes.** Docker re-reads `/configs/config.yaml` from the container before stop, so a changed `runtime:` survives a restart even if the DB isn't synced. EC2 trusts the DB only. If you change the runtime via the Config tab and the handler races the restart, Docker will land on the new runtime, EC2 will land on the old one. **Fix path:** make the Config-tab save explicitly flush to DB before kicking off a restart, not deferred.
4. **Console-output asymmetry.** Users debugging a stuck workspace on Docker see `docker logs`; on EC2 they see `GetConsoleOutput`. The two outputs look nothing alike. **Fix path:** expose a unified `GET /workspaces/:id/boot-log` that proxies to whichever backend serves the data. Already partly there via `cp_provisioner.Console`.
5. **Template script drift.** `install.sh` and `start.sh` in each template repo do the same high-level work (install hermes-agent, write .env, write config.yaml, start gateway) but must be kept byte-level consistent on the provider-key forwarding block. Easy to forget. Enforced now by `tools/check-template-parity.sh` (see below) — run it in each template repo's CI.
6. **Both backends panic when underlying client is nil.****Resolved** (`fix/provisioner-nil-guards-1813`). `Provisioner.{Stop,IsRunning}` and `CPProvisioner.{Stop,IsRunning}` now guard against nil clients with `ErrNoBackend`, so the contract-test runner executes scenarios against zero-valued backends without panic.
6. ~~**Both backends panic when underlying client is nil.**~~ **RESOLVED**nil guards landed in `Provisioner` (`Start`, `Stop`, `IsRunning`, `ExecRead`, `RemoveVolume`, `VolumeHasFile`, `WriteAuthTokenToVolume`) and `CPProvisioner` (`Stop`, `IsRunning`), all returning `ErrNoBackend`. Contract tests (`TestDockerBackend_Contract`, `TestCPProvisionerBackend_Contract`, `TestZeroValuedBackends_NoPanic`) run in CI without `t.Skip`.
## Enforcement
- **`tools/check-template-parity.sh`** (this repo) — ensures `install.sh` and `start.sh` in a template repo forward identical sets of provider keys. Wire into each template repo's CI as `bash $MONOREPO/tools/check-template-parity.sh install.sh start.sh`.
- **Contract tests** — `workspace-server/internal/provisioner/backend_contract_test.go` defines the behaviors every `provisioner.Provisioner` implementation must satisfy. Fails compile when a method drifts between `Docker` and `CPProvisioner`. Scenario-level runs execute against zero-valued backends since drift risk #6 was resolved (`fix/provisioner-nil-guards-1813`).
- **Contract tests** — `workspace-server/internal/provisioner/backend_contract_test.go` defines the behaviors every `provisioner.Provisioner` implementation must satisfy. Fails compile when a method drifts between `Docker` and `CPProvisioner`. Scenario-level runs (`TestDockerBackend_Contract`, `TestCPProvisionerBackend_Contract`, `TestZeroValuedBackends_NoPanic`) execute in CI — drift risk #6 resolved.
- **Source-level dispatcher pins** — `workspace_provision_auto_test.go` enforces the SoT pattern documented above:
- `TestNoCallSiteCallsDirectProvisionerExceptAuto` — no handler calls `.provisionWorkspace(` or `.provisionWorkspaceCP(` directly outside the dispatcher's allowlist.
- `TestNoCallSiteCallsBareStop` — no handler calls `.provisioner.Stop(` or `.cpProv.Stop(` directly outside the dispatcher's allowlist (strips Go comments before substring match so archaeology in code comments doesn't trip the gate).
+10 -1
View File
@@ -19,7 +19,10 @@
#
# Env vars required:
# CF_API_TOKEN — Cloudflare token with zone:dns:edit
# (falls back to CLOUDFLARE_API_TOKEN if CF_API_TOKEN is unset;
# the workflow YAML maps both secret names into CF_API_TOKEN)
# CF_ZONE_ID — the zone (moleculesai.app)
# (falls back to CLOUDFLARE_ZONE_ID if CF_ZONE_ID is unset)
# CP_ADMIN_API_TOKEN — CP admin bearer for api.moleculesai.app
# CP_STAGING_ADMIN_API_TOKEN — CP admin bearer for staging-api.moleculesai.app
# AWS_* — standard AWS creds (default region us-east-2)
@@ -56,6 +59,12 @@ need() {
exit 1
fi
}
# Fallback: operator-host canonical names → CI-scoped names.
# The workflow YAML already maps both, but direct script invocation
# (e.g. local ops) may only have the canonical names set.
CF_API_TOKEN="${CF_API_TOKEN:-${CLOUDFLARE_API_TOKEN:-}}"
CF_ZONE_ID="${CF_ZONE_ID:-${CLOUDFLARE_ZONE_ID:-}}"
need CF_API_TOKEN
need CF_ZONE_ID
need CP_ADMIN_API_TOKEN
@@ -121,7 +130,7 @@ if not payload.get("success", False) or not isinstance(payload.get("result"), li
print(f"ERROR: Cloudflare DNS list failed: {detail}", file=sys.stderr)
raise SystemExit(1)
'; then
log "Cloudflare DNS list failed; verify CF_API_TOKEN has Zone:DNS:Edit and CF_ZONE_ID is the moleculesai.app zone."
log "Cloudflare DNS list failed; verify CF_API_TOKEN (or CLOUDFLARE_API_TOKEN) has Zone:DNS:Edit and CF_ZONE_ID (or CLOUDFLARE_ZONE_ID) is the moleculesai.app zone."
exit 1
fi
TOTAL_CF=$(echo "$CF_JSON" | python3 -c "import json,sys; print(len(json.load(sys.stdin)['result']))")
+9
View File
@@ -29,8 +29,11 @@
# account:cloudflare_tunnel:edit scope.
# (Same secret as sweep-cf-orphans, but the
# token must include the tunnel scope.)
# (falls back to CLOUDFLARE_API_TOKEN if CF_API_TOKEN is unset;
# the workflow YAML maps both secret names into CF_API_TOKEN)
# CF_ACCOUNT_ID — the account that owns the tunnels (visible
# in dash.cloudflare.com URL path)
# (falls back to CLOUDFLARE_ACCOUNT_ID if CF_ACCOUNT_ID is unset)
# CP_ADMIN_API_TOKEN — CP admin bearer for api.moleculesai.app
# CP_STAGING_ADMIN_API_TOKEN — CP admin bearer for staging-api.moleculesai.app
#
@@ -70,6 +73,12 @@ need() {
exit 1
fi
}
# Fallback: operator-host canonical names → CI-scoped names.
# The workflow YAML already maps both, but direct script invocation
# (e.g. local ops) may only have the canonical names set.
CF_API_TOKEN="${CF_API_TOKEN:-${CLOUDFLARE_API_TOKEN:-}}"
CF_ACCOUNT_ID="${CF_ACCOUNT_ID:-${CLOUDFLARE_ACCOUNT_ID:-}}"
need CF_API_TOKEN
need CF_ACCOUNT_ID
need CP_ADMIN_API_TOKEN
+299
View File
@@ -0,0 +1,299 @@
#!/usr/bin/env bash
# cp#455 — Minimal-cell boot-to-registration harness.
# CTO directive 14eb4f07: "build the minimal claude-code+kimi cell,
# it should now go GREEN since the fix is live."
#
# Stage 1 of 5-stage rollout. Reduced to the minimum boot-to-
# registration surface so each cell run is ~3-5 min wall-clock.
#
# Four assertions (per Researcher Task #79 spec):
# 1. Provision request accepted; workspace transitions to booting/running
# 2. Controlplane receives /registry/register for that workspace_id
# 3. JSON-RPC/completion route returns successful minimal response
# 4. Teardown terminates workspace even on failure (trap)
#
# Cost controls (mandatory):
# - SPOT instances (via the dispatch-only EC2 provisioning path;
# we don't set instance type — that's the provisioner's call)
# - Fast teardown ~3-5 min wall-clock
# - Structured per-cell results JSON output
#
# Auth model (mirrors test_staging_full_saas.sh):
# Single MOLECULE_ADMIN_TOKEN drives everything.
# - POST /cp/admin/orgs to provision
# - GET /cp/admin/orgs/:slug/admin-token for per-tenant token
# - DELETE /cp/admin/tenants/:slug for teardown
# Per-tenant admin token drives tenant API calls (workspaces,
# /registry/register, JSON-RPC completion).
#
# Required env:
# MOLECULE_CP_URL default: https://staging-api.moleculesai.app
# MOLECULE_ADMIN_TOKEN CP admin bearer
#
# Optional env (passed from workflow_dispatch inputs):
# E2E_RUNTIME default claude-code
# E2E_BILLING_MODE default platform_managed
# E2E_PROVIDER default platform
# E2E_MODEL default moonshot/kimi-k2.6
# E2E_RUN_ID Slug suffix; CI: cp455-${GITHUB_RUN_ID}
# E2E_PROVISION_TIMEOUT_SECS default 300 (5 min — fast teardown budget)
# E2E_KEEP_ORG 1 → skip teardown (debugging only)
#
# Exit codes:
# 0 happy path
# 1 generic failure
# 2 missing required env
# 3 provisioning timed out (assertion 1)
# 4 register timeout (assertion 2)
# 5 completion failure (assertion 3)
# 6 teardown left orphan (assertion 4)
set -uo pipefail
CP_URL="${MOLECULE_CP_URL:-https://staging-api.moleculesai.app}"
ADMIN_TOKEN="${MOLECULE_ADMIN_TOKEN:?MOLECULE_ADMIN_TOKEN required — Railway staging CP_ADMIN_API_TOKEN}"
RUNTIME="${E2E_RUNTIME:-claude-code}"
BILLING_MODE="${E2E_BILLING_MODE:-platform_managed}"
PROVIDER="${E2E_PROVIDER:-platform}"
MODEL="${E2E_MODEL:-moonshot/kimi-k2.6}"
PROVISION_TIMEOUT_SECS="${E2E_PROVISION_TIMEOUT_SECS:-300}"
KEEP_ORG="${E2E_KEEP_ORG:-}"
RUN_ID_SUFFIX="${E2E_RUN_ID:-$(date +%H%M%S)-$$}"
SLUG="cp455-${RUNTIME}-${RUN_ID_SUFFIX}"
WORKSPACE_ID=""
TENANT_TOKEN=""
RESULT_JSON="/tmp/cell-result.json"
PROVISION_START_EPOCH=""
PROVISION_END_EPOCH=""
REGISTER_STATUS="not_attempted"
COMPLETION_STATUS="not_attempted"
TEARDOWN_STATUS="not_attempted"
EXIT_CODE=0
# Structured per-cell results writer. Emits JSON with all 4
# assertion statuses + elapsed timing. Called from EXIT trap so
# results are captured even on early failure.
write_result() {
local elapsed="${1:-0}"
cat > "${RESULT_JSON}" <<JSON
{
"runtime": "${RUNTIME}",
"billing_mode": "${BILLING_MODE}",
"provider": "${PROVIDER}",
"model": "${MODEL}",
"workspace_id": "${WORKSPACE_ID}",
"register_status": "${REGISTER_STATUS}",
"completion_status": "${COMPLETION_STATUS}",
"teardown_status": "${TEARDOWN_STATUS}",
"elapsed_seconds": ${elapsed},
"exit_code": ${EXIT_CODE},
"ts": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
}
JSON
}
# EXIT trap — ALWAYS run. Writes structured results, tears down
# workspace if we have one, never lets the script exit without
# emitting /tmp/cell-result.json.
on_exit() {
local exit_code=$?
EXIT_CODE=${exit_code}
local now
now=$(date +%s)
local elapsed=0
if [ -n "${PROVISION_START_EPOCH:-}" ] && [ "${PROVISION_START_EPOCH}" -gt 0 ] 2>/dev/null; then
elapsed=$(( now - PROVISION_START_EPOCH ))
fi
# Assertion 4: teardown terminates workspace even on failure.
if [ -z "${KEEP_ORG}" ] && [ -n "${SLUG:-}" ]; then
if [ -n "${WORKSPACE_ID:-}" ] || [ -n "${SLUG:-}" ]; then
echo "::group::Teardown (trap)"
echo "DELETE ${CP_URL}/cp/admin/tenants/${SLUG}"
local teardown_http_code
teardown_http_code=$(curl -sS -o /dev/null -w '%{http_code}' \
-X DELETE \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
--max-time 60 \
"${CP_URL}/cp/admin/tenants/${SLUG}" || echo "000")
if [ "${teardown_http_code}" = "200" ] || [ "${teardown_http_code}" = "204" ] || [ "${teardown_http_code}" = "404" ]; then
TEARDOWN_STATUS="ok"
echo "Teardown OK (HTTP ${teardown_http_code})"
else
TEARDOWN_STATUS="leak_risk_http_${teardown_http_code}"
echo "::error::Teardown returned HTTP ${teardown_http_code} — orphan risk"
# Bump exit code to 6 if teardown is the failure source.
if [ "${EXIT_CODE}" -eq 0 ]; then
EXIT_CODE=6
fi
fi
echo "::endgroup::"
fi
else
TEARDOWN_STATUS="skipped_keep_org"
fi
write_result "${elapsed}"
echo "Structured results written to ${RESULT_JSON}"
cat "${RESULT_JSON}"
exit "${EXIT_CODE}"
}
trap on_exit EXIT
trap 'echo "::error::Script aborted on signal"; exit 130' INT TERM
PROVISION_START_EPOCH=$(date +%s)
# Assertion 1: Provision request accepted; workspace transitions to
# booting/running.
echo "::group::Assertion 1: Provision"
echo "POST ${CP_URL}/cp/admin/orgs slug=${SLUG} runtime=${RUNTIME} billing_mode=${BILLING_MODE} provider=${PROVIDER} model=${MODEL}"
PROVISION_HTTP_CODE=$(curl -sS -o /tmp/provision-resp.json -w '%{http_code}' \
-X POST \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
-H "Content-Type: application/json" \
--max-time 30 \
-d "$(cat <<JSON
{
"slug": "${SLUG}",
"runtime": "${RUNTIME}",
"billing_mode": "${BILLING_MODE}",
"provider": "${PROVIDER}",
"model": "${MODEL}",
"tier": "spot",
"tags": {
"cp455_minimal_cell": "1",
"run_id": "${RUN_ID_SUFFIX}"
}
}
JSON
)" \
"${CP_URL}/cp/admin/orgs" || echo "000")
echo "HTTP ${PROVISION_HTTP_CODE}"
if [ "${PROVISION_HTTP_CODE}" != "202" ] && [ "${PROVISION_HTTP_CODE}" != "200" ]; then
echo "::error::Provision failed (HTTP ${PROVISION_HTTP_CODE})"
cat /tmp/provision-resp.json 2>/dev/null || true
EXIT_CODE=1
exit "${EXIT_CODE}"
fi
echo "::endgroup::"
# Wait for org to reach running + retrieve per-tenant token. Bounded
# at PROVISION_TIMEOUT_SECS. We poll the admin token endpoint; once
# the org is up, the endpoint returns 200 with the token, and the
# workspace_id is in the same response or in a follow-up /orgs/:slug
# call.
echo "::group::Wait for org to be ready (max ${PROVISION_TIMEOUT_SECS}s)"
WAIT_START=$(date +%s)
WAIT_DEADLINE=$(( WAIT_START + PROVISION_TIMEOUT_SECS ))
TENANT_TOKEN=""
while [ "$(date +%s)" -lt "${WAIT_DEADLINE}" ]; do
TOKEN_HTTP_CODE=$(curl -sS -o /tmp/token-resp.json -w '%{http_code}' \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
--max-time 10 \
"${CP_URL}/cp/admin/orgs/${SLUG}/admin-token" || echo "000")
if [ "${TOKEN_HTTP_CODE}" = "200" ]; then
TENANT_TOKEN=$(jq -r '.admin_token // .token // empty' /tmp/token-resp.json 2>/dev/null || echo "")
if [ -n "${TENANT_TOKEN}" ]; then
WORKSPACE_ID=$(jq -r '.workspace_id // .default_workspace_id // empty' /tmp/token-resp.json 2>/dev/null || echo "")
if [ -z "${WORKSPACE_ID}" ]; then
# Fallback: list orgs and find by slug
WORKSPACE_ID=$(curl -sS -H "Authorization: Bearer ${ADMIN_TOKEN}" \
"${CP_URL}/cp/admin/orgs/${SLUG}" | jq -r '.workspace_id // .default_workspace_id // empty' 2>/dev/null || echo "")
fi
if [ -n "${WORKSPACE_ID}" ]; then
PROVISION_END_EPOCH=$(date +%s)
echo "Org ready in $(( PROVISION_END_EPOCH - WAIT_START ))s — workspace_id=${WORKSPACE_ID}"
break
fi
fi
fi
sleep 5
done
if [ -z "${TENANT_TOKEN}" ] || [ -z "${WORKSPACE_ID}" ]; then
echo "::error::Provision timed out (org never reached running within ${PROVISION_TIMEOUT_SECS}s)"
EXIT_CODE=3
exit "${EXIT_CODE}"
fi
echo "::endgroup::"
# Assertion 2: Controlplane receives /registry/register for that
# workspace_id. The harness doesn't POST to /registry/register
# directly — that's the workspace-server's own job on boot. We
# verify the registration was received by polling the registry
# endpoint (or by checking that a /workspaces/:id call returns
# the expected fields).
echo "::group::Assertion 2: /registry/register for workspace_id=${WORKSPACE_ID}"
REGISTER_DEADLINE=$(( $(date +%s) + 60 ))
while [ "$(date +%s)" -lt "${REGISTER_DEADLINE}" ]; do
REG_HTTP_CODE=$(curl -sS -o /tmp/reg-resp.json -w '%{http_code}' \
-H "Authorization: Bearer ${TENANT_TOKEN}" \
--max-time 10 \
"${CP_URL}/cp/registry/workspaces/${WORKSPACE_ID}" || echo "000")
if [ "${REG_HTTP_CODE}" = "200" ]; then
REGISTERED=$(jq -r '.registered // .workspace_id // empty' /tmp/reg-resp.json 2>/dev/null || echo "")
if [ -n "${REGISTERED}" ]; then
REGISTER_STATUS="ok"
echo "Registry confirms workspace_id=${WORKSPACE_ID} registered"
break
fi
fi
sleep 3
done
if [ "${REGISTER_STATUS}" != "ok" ]; then
echo "::error::Registry did not confirm registration within 60s"
cat /tmp/reg-resp.json 2>/dev/null || true
EXIT_CODE=4
exit "${EXIT_CODE}"
fi
echo "::endgroup::"
# Assertion 3: JSON-RPC/completion route returns successful minimal
# response. One minimal completion call — keep payload small.
echo "::group::Assertion 3: JSON-RPC completion"
COMPLETION_HTTP_CODE=$(curl -sS -o /tmp/completion-resp.json -w '%{http_code}' \
-X POST \
-H "Authorization: Bearer ${TENANT_TOKEN}" \
-H "Content-Type: application/json" \
--max-time 30 \
-d "$(cat <<JSON
{
"jsonrpc": "2.0",
"id": 1,
"method": "completion",
"params": {
"workspace_id": "${WORKSPACE_ID}",
"model": "${MODEL}",
"messages": [{"role": "user", "content": "ping"}],
"max_tokens": 1
}
}
JSON
)" \
"${CP_URL}/cp/rpc" || echo "000")
echo "HTTP ${COMPLETION_HTTP_CODE}"
if [ "${COMPLETION_HTTP_CODE}" != "200" ]; then
echo "::error::Completion failed (HTTP ${COMPLETION_HTTP_CODE})"
cat /tmp/completion-resp.json 2>/dev/null || true
EXIT_CODE=5
exit "${EXIT_CODE}"
fi
# Verify JSON-RPC 2.0 success envelope
RPC_ERROR=$(jq -r '.error // empty' /tmp/completion-resp.json 2>/dev/null || echo "")
if [ -n "${RPC_ERROR}" ]; then
echo "::error::Completion returned JSON-RPC error: ${RPC_ERROR}"
cat /tmp/completion-resp.json 2>/dev/null || true
EXIT_CODE=5
exit "${EXIT_CODE}"
fi
RPC_RESULT=$(jq -r '.result // empty' /tmp/completion-resp.json 2>/dev/null || echo "")
if [ -z "${RPC_RESULT}" ] || [ "${RPC_RESULT}" = "null" ]; then
echo "::error::Completion response missing result field"
cat /tmp/completion-resp.json 2>/dev/null || true
EXIT_CODE=5
exit "${EXIT_CODE}"
fi
COMPLETION_STATUS="ok"
echo "Completion OK"
echo "::endgroup::"
echo "All 4 assertions passed for ${SLUG} (workspace_id=${WORKSPACE_ID})"
+10 -11
View File
@@ -53,7 +53,9 @@
# PV_RUNTIMES space list; default "hermes openclaw claude-code"
# E2E_PROVISION_TIMEOUT_SECS default 1800 (hermes/openclaw cold EC2 budget)
# E2E_MINIMAX_API_KEY / E2E_ANTHROPIC_API_KEY / E2E_OPENAI_API_KEY
# LLM provider key injected so the runtime can boot
# DEPRECATED for this script — platform-managed models
# use the CP LLM proxy; direct vendor keys are blocked
# by PR #2291. Kept in workflow env for other E2Es.
# PV_TOKEN_DIAGNOSTIC_ONLY
# 1 -> stop after create/token acquisition. Useful
# to classify Hermes-only vs shared auth-route issues.
@@ -222,17 +224,14 @@ else
fi
# ─── 4. Provision the parent + one sibling per runtime under test ──────
# Inject the LLM provider key so each runtime can authenticate at boot.
# Priority: MiniMax → direct-Anthropic → OpenAI (mirrors
# test_staging_full_saas.sh's secrets-injection chain).
# Platform-managed models: Molecule owns billing via the CP LLM proxy, so
# the workspace needs NO tenant key. PR #2291 blocks direct vendor key writes
# (ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, MINIMAX_API_KEY, etc.) for
# platform-managed workspaces. We intentionally keep SECRETS_JSON empty so a
# stray E2E_*_API_KEY in the runner env cannot silently convert this into a
# BYOK run and mask the platform-managed path (mirrors
# test_staging_full_saas.sh's E2E_LLM_PATH=platform branch).
SECRETS_JSON='{}'
if [ -n "${E2E_MINIMAX_API_KEY:-}" ]; then
SECRETS_JSON=$(python3 -c "import json,os;k=os.environ['E2E_MINIMAX_API_KEY'];print(json.dumps({'ANTHROPIC_BASE_URL':'https://api.minimax.io/anthropic','ANTHROPIC_AUTH_TOKEN':k,'MINIMAX_API_KEY':k}))")
elif [ -n "${E2E_ANTHROPIC_API_KEY:-}" ]; then
SECRETS_JSON=$(python3 -c "import json,os;k=os.environ['E2E_ANTHROPIC_API_KEY'];print(json.dumps({'ANTHROPIC_API_KEY':k}))")
elif [ -n "${E2E_OPENAI_API_KEY:-}" ]; then
SECRETS_JSON=$(python3 -c "import json,os;k=os.environ['E2E_OPENAI_API_KEY'];print(json.dumps({'OPENAI_API_KEY':k,'OPENAI_BASE_URL':'https://api.openai.com/v1','MODEL_PROVIDER':'openai:gpt-4o','HERMES_INFERENCE_PROVIDER':'custom','HERMES_CUSTOM_BASE_URL':'https://api.openai.com/v1','HERMES_CUSTOM_API_KEY':k,'HERMES_CUSTOM_API_MODE':'chat_completions'}))")
fi
# Workspace-create now enforces the MODEL_REQUIRED contract: there is NO
# platform-side default model for a runtime (feedback_workspace_model_required_
+48
View File
@@ -584,6 +584,54 @@ def test_find_open_issue_raises_on_transient_error(drift_module, monkeypatch):
drift_module.find_open_issue("[ci-drift] foo")
# --------------------------------------------------------------------------
# Pagination: search beyond page 1 so an existing issue on any page is found
# --------------------------------------------------------------------------
def test_find_open_issue_paginates_to_page_2(drift_module, monkeypatch):
"""Issue exists on page 2 → paginate and find it."""
target = {"number": 99, "title": "[ci-drift] foo"}
filler = [{"number": i, "title": f"other-{i}"} for i in range(1, 51)]
class PaginatedStub:
def __init__(self):
self.calls = []
def __call__(self, method, path, *, body=None, query=None, expect_json=True):
self.calls.append((method, path, body, query))
page = int((query or {}).get("page", "1"))
if page == 1:
return 200, filler
if page == 2:
return 200, [target]
return 200, []
stub = PaginatedStub()
monkeypatch.setattr(drift_module, "api", stub)
assert drift_module.find_open_issue("[ci-drift] foo") == target
assert len(stub.calls) == 2
def test_find_open_issue_stops_at_last_page(drift_module, monkeypatch):
"""No match across pages → stop when a page has <50 results."""
filler = [{"number": i, "title": f"other-{i}"} for i in range(1, 51)]
class PaginatedStub:
def __init__(self):
self.calls = []
def __call__(self, method, path, *, body=None, query=None, expect_json=True):
self.calls.append((method, path, body, query))
page = int((query or {}).get("page", "1"))
if page == 1:
return 200, filler
return 200, []
stub = PaginatedStub()
monkeypatch.setattr(drift_module, "api", stub)
assert drift_module.find_open_issue("[ci-drift] foo") is None
assert len(stub.calls) == 2
# --------------------------------------------------------------------------
# Idempotent path: existing issue is PATCHed, NOT duplicated
# --------------------------------------------------------------------------
+10 -1
View File
@@ -351,8 +351,17 @@ func main() {
// (true, err) on any transient error, so a CP blip never flips a healthy
// workspace.
if cpProv != nil {
// Guard against double-reprovision thrash (internal#544): the restart
// debounce window must cover the reconciler interval so a workspace
// flipped offline by one reconcile tick isn't immediately reprovisioned
// again by the next tick before the debounce drops it. If the interval
// ever shrinks below the debounce window, the coupling silently breaks.
reconcileInterval := 60 * time.Second
if handlers.RestartDebounceWindow < reconcileInterval {
log.Fatalf("RestartDebounceWindow (%s) must be >= CP instance reconciler interval (%s) to prevent double-reprovision thrash (internal#544)", handlers.RestartDebounceWindow, reconcileInterval)
}
go supervised.RunWithRecover(ctx, "cp-instance-reconciler", func(c context.Context) {
registry.StartCPInstanceReconciler(c, cpProv, onWorkspaceOffline, 60*time.Second)
registry.StartCPInstanceReconciler(c, cpProv, onWorkspaceOffline, reconcileInterval)
})
}
@@ -271,6 +271,11 @@ func (m *Manager) Reload(ctx context.Context) {
ch.Config["_channel_id"] = ch.ID
go func(a ChannelAdapter, c ChannelRow, pCtx context.Context) {
defer func() {
if r := recover(); r != nil {
log.Printf("PANIC recovered in channel polling goroutine: %v", r)
}
}()
if err := a.StartPolling(pCtx, c.Config, m.onInboundMessage); err != nil {
log.Printf("Channels: polling error for %s/%s: %v", c.ChannelType, truncID(c.ID), err)
}
@@ -354,6 +359,11 @@ func (m *Manager) HandleInbound(ctx context.Context, ch ChannelRow, msg *Inbound
typingCtx, typingCancel := context.WithCancel(fireCtx)
defer typingCancel()
go func() {
defer func() {
if r := recover(); r != nil {
log.Printf("PANIC recovered in typing indicator goroutine: %v", r)
}
}()
typer.SendTyping(ch.Config, msg.ChatID)
ticker := time.NewTicker(4 * time.Second)
defer ticker.Stop()
@@ -29,6 +29,7 @@ import (
"fmt"
"log"
"net/http"
"os"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/approvals"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/db"
@@ -50,7 +51,7 @@ func approvalRequestHash(workspaceID, action string, contextMap map[string]inter
// requireApproval returns (approved=true, consumedID) when a matching approval
// exists and was just consumed; otherwise it creates/reuses a pending approval
// and returns (false, pendingID). A non-nil error is a server error.
func requireApproval(ctx context.Context, b *events.Broadcaster, workspaceID string, action approvals.Action, reason string, contextMap map[string]interface{}) (bool, string, error) {
func requireApproval(ctx context.Context, b events.EventEmitter, workspaceID string, action approvals.Action, reason string, contextMap map[string]interface{}) (bool, string, error) {
hash := approvalRequestHash(workspaceID, string(action), contextMap)
// 1. Atomically consume an approved + unconsumed request, if one exists.
@@ -103,18 +104,25 @@ func requireApproval(ctx context.Context, b *events.Broadcaster, workspaceID str
// Broadcast to the canvas (the user-facing signal). For a platform agent the
// parent_id is NULL, so the requested-event on its own workspace IS the user
// prompt; ordinary workspaces also escalate to their parent.
if bErr := b.RecordAndBroadcast(ctx, string(events.EventApprovalRequested), workspaceID, map[string]interface{}{
"approval_id": approvalID,
"action": string(action),
"reason": reason,
}); bErr != nil {
log.Printf("approval_gate: broadcast requested failed (ws=%s): %v", workspaceID, bErr)
//
// b may be nil: stateless handlers (e.g. org-token mint — OrgTokenHandler is
// an empty struct with no broadcaster) still gate; they just can't push a
// live canvas event. The pending approval row is persisted regardless, so
// the request is never lost — only the notification is skipped.
if b != nil {
if bErr := b.RecordAndBroadcast(ctx, string(events.EventApprovalRequested), workspaceID, map[string]interface{}{
"approval_id": approvalID,
"action": string(action),
"reason": reason,
}); bErr != nil {
log.Printf("approval_gate: broadcast requested failed (ws=%s): %v", workspaceID, bErr)
}
}
var parentID *string
if pErr := db.DB.QueryRowContext(ctx, `SELECT parent_id FROM workspaces WHERE id = $1`, workspaceID).Scan(&parentID); pErr != nil {
log.Printf("approval_gate: parent lookup failed (ws=%s): %v", workspaceID, pErr)
}
if parentID != nil {
if parentID != nil && b != nil {
if bErr := b.RecordAndBroadcast(ctx, string(events.EventApprovalEscalated), *parentID, map[string]interface{}{
"approval_id": approvalID,
"from_workspace_id": workspaceID,
@@ -130,10 +138,26 @@ func requireApproval(ctx context.Context, b *events.Broadcaster, workspaceID str
// gateDestructive runs requireApproval for a gated action and, when approval is
// still pending, writes the 202 response and returns false (caller must stop).
// Returns true when the caller may proceed (action consumed an approval).
func gateDestructive(c *gin.Context, b *events.Broadcaster, workspaceID string, action approvals.Action, reason string, contextMap map[string]interface{}) bool {
func gateDestructive(c *gin.Context, b events.EventEmitter, workspaceID string, action approvals.Action, reason string, contextMap map[string]interface{}) bool {
if !approvals.IsGated(action) {
return true
}
// Scope (RFC platform-agent Phase 4b). Wiring is a one-liner in each
// destructive handler; the activation policy lives here, centrally, so it is
// uniform and testable:
// - default-OFF rollout flag, so the wiring is inert until an operator
// enables it (mirrors the 3a/3c default-off design and protects existing
// org-token automation from a surprise async-approval behaviour change);
// - only callers holding an ORG token are gated. The platform agent runs
// with MOLECULE_API_KEY=<org-admin token>, so the auth middleware sets
// org_token_id. Ordinary workspace-token agents and human CP-session
// operators (cp_session_actor — the approvers themselves) are NOT gated,
// so normal operation is byte-identical. This realises the file-header
// trust boundary ("anything holding an org-admin token still goes
// through the gate") without gating everyone.
if !destructiveGateEnabled() || !callerHoldsOrgToken(c) {
return true
}
approved, approvalID, err := requireApproval(c.Request.Context(), b, workspaceID, action, reason, contextMap)
if err != nil {
log.Printf("gateDestructive: %v (ws=%s action=%s)", err, workspaceID, action)
@@ -151,3 +175,22 @@ func gateDestructive(c *gin.Context, b *events.Broadcaster, workspaceID string,
}
return true
}
// destructiveGateEnabled is the default-off rollout flag for the org-level
// destructive-op approval gate. Inert until an operator sets
// MOLECULE_PLATFORM_APPROVAL_GATE=1 (or "true") — typically when the platform
// agent is deployed to the org. Keeps 4b's wiring shipped-but-dormant, matching
// the platform-agent feature's default-off posture (3a/3c).
func destructiveGateEnabled() bool {
v := os.Getenv("MOLECULE_PLATFORM_APPROVAL_GATE")
return v == "1" || v == "true"
}
// callerHoldsOrgToken reports whether the request authenticated with an org
// token (the auth middleware sets org_token_id, see middleware/wsauth_middleware.go).
// The platform agent uses an org-admin token; ordinary workspace-token agents
// and human CP sessions do not, so they bypass the gate entirely.
func callerHoldsOrgToken(c *gin.Context) bool {
_, ok := c.Get("org_token_id")
return ok
}
@@ -0,0 +1,76 @@
package handlers
// Phase 4b — unit coverage for the gate's activation SCOPE: the default-off
// rollout flag + org-token-only targeting. These exercise the short-circuit
// paths that return "proceed" BEFORE requireApproval, so they need no DB. The
// full flag-on + org-token + gated → 202 path is covered by the real-Postgres
// approval_gate_integration_test.go.
import (
"net/http/httptest"
"os"
"testing"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/approvals"
"github.com/gin-gonic/gin"
)
func TestDestructiveGateEnabled_DefaultOff(t *testing.T) {
os.Unsetenv("MOLECULE_PLATFORM_APPROVAL_GATE")
if destructiveGateEnabled() {
t.Fatal("gate must be OFF by default (no env)")
}
for _, v := range []string{"1", "true"} {
t.Setenv("MOLECULE_PLATFORM_APPROVAL_GATE", v)
if !destructiveGateEnabled() {
t.Errorf("%q must enable the gate", v)
}
}
t.Setenv("MOLECULE_PLATFORM_APPROVAL_GATE", "0")
if destructiveGateEnabled() {
t.Error(`"0" must keep the gate off`)
}
}
func TestCallerHoldsOrgToken(t *testing.T) {
gin.SetMode(gin.TestMode)
c, _ := gin.CreateTestContext(httptest.NewRecorder())
if callerHoldsOrgToken(c) {
t.Error("no org_token_id in context → must be false (workspace/CP caller)")
}
c.Set("org_token_id", "tok-abc")
if !callerHoldsOrgToken(c) {
t.Error("org_token_id set → must be true (platform-agent / org-admin caller)")
}
}
// gateDestructive must return true (proceed, no 202, no DB touch) whenever the
// scope excludes the call: non-gated action, flag off, or non-org-token caller.
func TestGateDestructive_ScopeShortCircuits(t *testing.T) {
gin.SetMode(gin.TestMode)
newCtx := func(orgToken bool) *gin.Context {
c, _ := gin.CreateTestContext(httptest.NewRecorder())
c.Request = httptest.NewRequest("DELETE", "/x", nil)
if orgToken {
c.Set("org_token_id", "tok")
}
return c
}
// flag OFF (default) + org-token + gated action → proceed.
os.Unsetenv("MOLECULE_PLATFORM_APPROVAL_GATE")
if !gateDestructive(newCtx(true), nil, "ws", approvals.ActionDeleteWorkspace, "r", nil) {
t.Error("flag off must proceed (gate dormant)")
}
// flag ON + NO org token (workspace agent / human CP session) → proceed.
t.Setenv("MOLECULE_PLATFORM_APPROVAL_GATE", "1")
if !gateDestructive(newCtx(false), nil, "ws", approvals.ActionDeleteWorkspace, "r", nil) {
t.Error("non-org-token caller must proceed (normal operation unchanged)")
}
// flag ON + org token + NON-gated action → proceed (IsGated short-circuit).
if !gateDestructive(newCtx(true), nil, "ws", approvals.Action("not_a_gated_action"), "r", nil) {
t.Error("non-gated action must proceed")
}
}
@@ -173,20 +173,8 @@ func (h *DelegationHandler) Delegate(c *gin.Context) {
// check_task_status returned status='queued' forever even after a
// real reply landed). messageId mirrors delegation_id so the
// platform's idempotency-key extraction also keys off the same id.
a2aBody, marshalErr := json.Marshal(map[string]interface{}{
"method": "message/send",
"params": map[string]interface{}{
"message": map[string]interface{}{
"role": "user",
"messageId": delegationID,
// A2A v0.3 Part discriminator is `kind`, NOT `type` (#2251) —
// a `type`-keyed Part is dropped by the receiver's v0.3
// validator, silently losing the delegated task.
"parts": []map[string]interface{}{{"kind": "text", "text": body.Task}},
"metadata": map[string]interface{}{"delegation_id": delegationID},
},
},
})
// Build A2A payload via helper so contract tests can assert the envelope shape.
a2aBody, marshalErr := buildDelegateA2ABody(delegationID, body.Task)
if marshalErr != nil {
log.Printf("Delegation %s: json.Marshal a2aBody failed: %v", delegationID, marshalErr)
}
@@ -374,6 +362,27 @@ func insertDelegationRow(ctx context.Context, c *gin.Context, sourceID string, b
return insertTrackingUnavailable
}
// buildDelegateA2ABody constructs the A2A JSON-RPC envelope for a delegation.
// The returned shape is a schema-valid SendMessageRequest with role="user",
// messageId, parts, and delegation metadata. Extracted to a pure function so
// unit tests can assert the envelope contract without standing up HTTP or DB.
func buildDelegateA2ABody(delegationID, task string) ([]byte, error) {
return json.Marshal(map[string]interface{}{
"method": "message/send",
"params": map[string]interface{}{
"message": map[string]interface{}{
"role": "user",
"messageId": delegationID,
// A2A v0.3 Part discriminator is `kind`, NOT `type` (#2251) —
// a `type`-keyed Part is dropped by the receiver's v0.3
// validator, silently losing the delegated task.
"parts": []map[string]interface{}{{"kind": "text", "text": task}},
"metadata": map[string]interface{}{"delegation_id": delegationID},
},
},
})
}
// executeDelegation runs in a goroutine — sends A2A and stores the result.
// Updates delegation status through: pending → dispatched → received → completed/failed
// delegationRetryDelay is the pause between the first failed proxy attempt
@@ -1762,3 +1762,74 @@ func TestListDelegations_LedgerFailedIncludesErrorDetail(t *testing.T) {
t.Errorf("unmet sqlmock expectations: %v", err)
}
}
// ---------- buildDelegateA2ABody: schema-valid SendMessageRequest ----------
// TestBuildDelegateA2ABody_SchemaValidSendMessageRequest pins the contract
// requested by issue #2251: delegate_task must produce a schema-valid A2A
// SendMessageRequest with role="user", messageId, parts, and metadata.
func TestBuildDelegateA2ABody_SchemaValidSendMessageRequest(t *testing.T) {
delegationID := "del-2251-test"
task := "write a contract test"
body, err := buildDelegateA2ABody(delegationID, task)
if err != nil {
t.Fatalf("buildDelegateA2ABody failed: %v", err)
}
var envelope map[string]interface{}
if err := json.Unmarshal(body, &envelope); err != nil {
t.Fatalf("body is not valid JSON: %v", err)
}
// Top-level envelope shape
if envelope["method"] != "message/send" {
t.Errorf("method = %v, want message/send", envelope["method"])
}
params, ok := envelope["params"].(map[string]interface{})
if !ok {
t.Fatalf("params missing or not a map: %T", envelope["params"])
}
msg, ok := params["message"].(map[string]interface{})
if !ok {
t.Fatalf("message missing or not a map: %T", params["message"])
}
// Issue #2251: role is required
if msg["role"] != "user" {
t.Errorf("message.role = %v, want \"user\"", msg["role"])
}
// messageId must be present and match delegationID
if msg["messageId"] != delegationID {
t.Errorf("message.messageId = %v, want %s", msg["messageId"], delegationID)
}
// parts must be a non-empty list with a text part
parts, ok := msg["parts"].([]interface{})
if !ok || len(parts) == 0 {
t.Fatalf("message.parts missing or empty: %T", msg["parts"])
}
firstPart, ok := parts[0].(map[string]interface{})
if !ok {
t.Fatalf("first part is not a map: %T", parts[0])
}
// A2A v0.3 Part discriminator is `kind`, NOT `type` (#2251)
if firstPart["kind"] != "text" {
t.Errorf("first part kind = %v, want text", firstPart["kind"])
}
if firstPart["text"] != task {
t.Errorf("first part text = %v, want %q", firstPart["text"], task)
}
// metadata.delegation_id must match
meta, ok := msg["metadata"].(map[string]interface{})
if !ok {
t.Fatalf("metadata missing or not a map: %T", msg["metadata"])
}
if meta["delegation_id"] != delegationID {
t.Errorf("metadata.delegation_id = %v, want %s", meta["delegation_id"], delegationID)
}
}
+53 -9
View File
@@ -54,6 +54,55 @@ func mcpPost(t *testing.T, h *MCPHandler, workspaceID string, body interface{})
return w
}
// assertA2ASendMessageSchema validates that body is a schema-valid A2A
// SendMessageRequest with role="user", messageId, and non-empty parts.
// Issue #2251 contract test: delegate_task must always produce this shape.
func assertA2ASendMessageSchema(t *testing.T, body []byte, wantTask string) {
t.Helper()
var envelope map[string]interface{}
if err := json.Unmarshal(body, &envelope); err != nil {
t.Fatalf("A2A body is not valid JSON: %v", err)
}
if envelope["jsonrpc"] != "2.0" {
t.Errorf("jsonrpc = %v, want 2.0", envelope["jsonrpc"])
}
if envelope["method"] != "message/send" {
t.Errorf("method = %v, want message/send", envelope["method"])
}
params, ok := envelope["params"].(map[string]interface{})
if !ok {
t.Fatalf("params missing or not a map: %T", envelope["params"])
}
msg, ok := params["message"].(map[string]interface{})
if !ok {
t.Fatalf("message missing or not a map: %T", params["message"])
}
if msg["role"] != "user" {
t.Errorf("message.role = %v, want \"user\"", msg["role"])
}
if msg["messageId"] == "" {
t.Error("message.messageId is empty")
}
parts, ok := msg["parts"].([]interface{})
if !ok || len(parts) == 0 {
t.Fatalf("message.parts missing or empty: %T", msg["parts"])
}
firstPart, ok := parts[0].(map[string]interface{})
if !ok {
t.Fatalf("first part is not a map: %T", parts[0])
}
// A2A v0.3 Part discriminator is `kind`, NOT `type` (#2251)
if firstPart["kind"] != "text" {
t.Errorf("first part kind = %v, want text", firstPart["kind"])
}
if firstPart["text"] != wantTask {
t.Errorf("first part text = %v, want %q", firstPart["text"], wantTask)
}
}
func expectCanCommunicateSiblings(mock sqlmock.Sqlmock, callerID, targetID, parentID string) {
mock.ExpectQuery(`SELECT id, parent_id FROM workspaces WHERE id = \$1`).
WithArgs(callerID).
@@ -209,9 +258,7 @@ func TestMCPHandler_DelegateTask_RoutesThroughPlatformA2AProxy(t *testing.T) {
if !logActivity {
t.Fatal("delegate_task should log through platform A2A proxy")
}
if !strings.Contains(string(body), "do work") {
t.Fatalf("A2A body missing task text: %s", string(body))
}
assertA2ASendMessageSchema(t, body, "do work")
return 200, []byte(`{"result":{"message":{"parts":[{"text":"done"}]}}}`), nil
}
@@ -252,9 +299,7 @@ func TestMCPHandler_DelegateTaskAsync_RoutesThroughPlatformA2AProxy(t *testing.T
if workspaceID != targetID || proxyCallerID != callerID {
t.Fatalf("unexpected proxy route target=%q caller=%q", workspaceID, proxyCallerID)
}
if !strings.Contains(string(body), "async work") {
t.Fatalf("A2A body missing task text: %s", string(body))
}
assertA2ASendMessageSchema(t, body, "async work")
called <- struct{}{}
return 200, []byte(`{"result":{"message":{"parts":[{"text":"accepted"}]}}}`), nil
}
@@ -304,10 +349,8 @@ func TestMCPHandler_DelegateTask_WithAttachments(t *testing.T) {
if workspaceID != targetID || proxyCallerID != callerID {
t.Fatalf("unexpected proxy route target=%q caller=%q", workspaceID, proxyCallerID)
}
assertA2ASendMessageSchema(t, body, "review this video")
bodyStr := string(body)
if !strings.Contains(bodyStr, `"text":"review this video"`) {
t.Fatalf("A2A body missing task text: %s", bodyStr)
}
if !strings.Contains(bodyStr, `"kind":"video"`) {
t.Fatalf("A2A body missing video attachment kind: %s", bodyStr)
}
@@ -386,6 +429,7 @@ func TestMCPHandler_DelegateTaskAsync_WithAttachments(t *testing.T) {
waitGlobalAsyncForTest()
select {
case body := <-called:
assertA2ASendMessageSchema(t, body, "async work with image")
bodyStr := string(body)
if !strings.Contains(bodyStr, `"kind":"image"`) {
t.Fatalf("A2A body missing image attachment kind: %s", bodyStr)
+12 -1
View File
@@ -226,7 +226,18 @@ func (h *MemoriesHandler) Commit(c *gin.Context) {
Source: contract.MemorySourceUser,
})
if err != nil {
log.Printf("Commit memory error (plugin): %v", err)
// Server-side log ONLY. The client response below is the generic
// 500 — the underlying plugin error must NOT leak to the HTTP
// response body (clients have no business seeing the memory
// plugin's internal error class, message, or stack; the same
// discipline as the #2392 leak fix). We include enough context
// here for an operator to diagnose the failure from the server
// log: workspace id, requested scope, the resolved v2 namespace,
// the concrete Go error type (for log-aggregator filtering via
// `err_class=...`), and the quoted error message (preserves
// trailing whitespace / special chars that %v would munge).
log.Printf("Commit memory plugin error: workspace=%s scope=%s namespace=%s err_class=%T err=%q",
workspaceID, body.Scope, nsName, err, err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to store memory"})
return
}
@@ -177,7 +177,7 @@ func isEnvIdentPart(c byte) bool {
return isEnvIdentStart(c) || (c >= '0' && c <= '9')
}
// loadWorkspaceEnv reads the org root .env and the workspace-specific .env
// loadWorkspaceEnv reads the org root .env and the workspace-specific .env files.
// (workspace overrides org root). Used by both secret injection and channel
// config expansion.
//
@@ -0,0 +1,135 @@
package handlers
// platform_agent.go — installs the org-level platform agent as the org root.
// (RFC docs/design/rfc-platform-agent.md)
//
// The platform agent IS the org root: an org is the subtree under the single
// parent_id IS NULL row (org_scope.go), so making the concierge the user's
// universal A2A peer means making it that root. Installing it therefore:
//
// 1. upserts the platform-agent row (kind='platform', parent_id NULL);
// 2. re-parents the org's existing root(s) under it;
// 3. moves the org-anchor references — org_api_tokens.org_id and
// org_plugin_allowlist.org_id, both of which key off the root workspace id
// (see migrations 035/036 + 026) — from each old root to the platform agent.
//
// All of that happens in ONE transaction so a tenant's auth tokens and plugin
// allowlist never point at a stale anchor. The operation is idempotent: a second
// call finds the platform agent already the sole root and does nothing.
//
// Routing (CanCommunicate/sameOrg in registry/access.go + org_scope.go) needs NO
// change — once the platform agent is the root, the existing ancestor/descendant
// rules already give it universal in-org reach and keep tenant isolation intact.
import (
"context"
"database/sql"
"fmt"
"log"
"net/http"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/db"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/models"
"github.com/gin-gonic/gin"
)
type installPlatformAgentPayload struct {
// ID is the platform agent's workspace id (a deterministic uuidv5 the
// control plane derives per org). Required.
ID string `json:"id" binding:"required"`
// Name is the display name; defaults to "Org Concierge" when omitted.
Name string `json:"name"`
}
// InstallPlatformAgent handles POST /admin/org/platform-agent (AdminAuth).
//
// Idempotently installs the platform agent as the org root for THIS tenant. The
// control plane calls it at org-provision time (new orgs) and during the
// existing-org backfill rollout. Safe to call repeatedly.
func InstallPlatformAgent(c *gin.Context) {
var p installPlatformAgentPayload
if err := c.ShouldBindJSON(&p); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body"})
return
}
name := p.Name
if name == "" {
name = "Org Concierge"
}
if err := installPlatformAgent(c.Request.Context(), db.DB, p.ID, name); err != nil {
log.Printf("InstallPlatformAgent: %v (id=%s)", err, p.ID)
c.JSON(http.StatusInternalServerError, gin.H{"error": "install failed"})
return
}
c.JSON(http.StatusOK, gin.H{
"status": "installed",
"platform_agent_id": p.ID,
"kind": models.KindPlatform,
})
}
// installPlatformAgent performs the idempotent, transactional install described
// in the file header. Separated from the gin handler so integration tests can
// exercise it directly against a real Postgres (the org-anchor migration cannot
// be proven with sqlmock).
func installPlatformAgent(ctx context.Context, database *sql.DB, platformID, name string) error {
tx, err := database.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("begin: %w", err)
}
defer func() { _ = tx.Rollback() }() // no-op after Commit
// 1. Ensure the platform-agent row exists as a kind='platform' root.
// ON CONFLICT keeps it a platform root if it was pre-seeded; the row is
// tier 0 and never billed/provisioned as an ordinary workspace EC2.
if _, err := tx.ExecContext(ctx, `
INSERT INTO workspaces (id, name, kind, tier, status, runtime, parent_id)
VALUES ($1, $2, 'platform', 0, 'online', 'claude-code', NULL)
ON CONFLICT (id) DO UPDATE SET kind = 'platform', parent_id = NULL
`, platformID, name); err != nil {
return fmt.Errorf("upsert platform agent: %w", err)
}
// 2. Capture the org's other current roots (everything at parent_id IS NULL
// except the platform agent itself). In a one-org tenant DB this is the
// single team root; the query tolerates 0 (already installed) or N.
rows, err := tx.QueryContext(ctx,
`SELECT id FROM workspaces WHERE parent_id IS NULL AND id <> $1`, platformID)
if err != nil {
return fmt.Errorf("select old roots: %w", err)
}
var oldRoots []string
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
rows.Close()
return fmt.Errorf("scan old root: %w", err)
}
oldRoots = append(oldRoots, id)
}
rows.Close()
if err := rows.Err(); err != nil {
return fmt.Errorf("iterate old roots: %w", err)
}
// 3 + 4. Re-parent each old root under the platform agent and move its
// org-anchor references in the same transaction. A non-root old root
// is kind='workspace', so it does not trip workspaces_platform_root_check.
for _, root := range oldRoots {
if _, err := tx.ExecContext(ctx,
`UPDATE workspaces SET parent_id = $1, updated_at = now() WHERE id = $2`,
platformID, root); err != nil {
return fmt.Errorf("re-parent %s: %w", root, err)
}
if _, err := tx.ExecContext(ctx,
`UPDATE org_api_tokens SET org_id = $1 WHERE org_id = $2`, platformID, root); err != nil {
return fmt.Errorf("migrate org_api_tokens for %s: %w", root, err)
}
if _, err := tx.ExecContext(ctx,
`UPDATE org_plugin_allowlist SET org_id = $1 WHERE org_id = $2`, platformID, root); err != nil {
return fmt.Errorf("migrate org_plugin_allowlist for %s: %w", root, err)
}
}
return tx.Commit()
}
@@ -0,0 +1,188 @@
//go:build integration
// +build integration
// platform_agent_integration_test.go — REAL Postgres gate for installPlatformAgent.
//
// Run with:
//
// INTEGRATION_DB_URL="postgres://postgres:test@localhost:55432/molecule?sslmode=disable" \
// go test -tags=integration ./internal/handlers/ -run Integration_PlatformAgentInstall -v
//
// CI: handlers-postgres-integration workflow (handlers + migrations path filter).
//
// Why this is NOT a sqlmock test
// ------------------------------
// The install re-parents the org's existing root under the platform agent AND
// moves the org-anchor references (org_api_tokens.org_id, org_plugin_allowlist.
// org_id) from old root to platform agent, atomically. The whole point is the
// post-transaction row state: orgRootID() must resolve every node to the platform
// agent, sameOrg() must still hold, and the auth/allowlist anchors must point at
// the new root. Only a real Postgres can prove that; sqlmock cannot.
package handlers
import (
"context"
"database/sql"
"fmt"
"testing"
"github.com/google/uuid"
_ "github.com/lib/pq"
)
func integrationDB_PlatformAgentInstall(t *testing.T) *sql.DB {
t.Helper()
url := requireIntegrationDBURL(t)
conn, err := sql.Open("postgres", url)
if err != nil {
t.Fatalf("open: %v", err)
}
if err := conn.Ping(); err != nil {
t.Fatalf("ping: %v", err)
}
t.Cleanup(func() { conn.Close() })
return conn
}
// TestIntegration_PlatformAgentInstall_ReparentsRootAndMovesAnchors builds a
// real org in Postgres:
//
// root (parent_id NULL, kind=workspace)
// └── child
// + an org_api_token anchored to root
// + an org_plugin_allowlist entry anchored to root
//
// then installs the platform agent and asserts:
// - the platform agent is the new sole root (kind=platform, parent_id NULL);
// - the old root is re-parented under it; the child is untouched;
// - both org-anchor references now point at the platform agent;
// - a second install is a no-op (idempotent).
func TestIntegration_PlatformAgentInstall_ReparentsRootAndMovesAnchors(t *testing.T) {
conn := integrationDB_PlatformAgentInstall(t)
ctx := context.Background()
tag := uuid.New().String()[:8]
prefix := fmt.Sprintf("itest-pinstall-%s", tag)
rootID := uuid.New().String()
childID := uuid.New().String()
platformID := uuid.New().String()
cleanup := func() {
_, _ = conn.ExecContext(ctx, `DELETE FROM org_plugin_allowlist WHERE plugin_name = $1`, prefix+"-plugin")
_, _ = conn.ExecContext(ctx, `DELETE FROM org_api_tokens WHERE prefix = $1`, tag)
// child + old root (prefixed names) first, then the platform agent by id
// (root.parent_id references it, so it must go last).
_, _ = conn.ExecContext(ctx, `DELETE FROM workspaces WHERE name LIKE $1`, prefix+"%")
_, _ = conn.ExecContext(ctx, `DELETE FROM workspaces WHERE id = $1`, platformID)
}
t.Cleanup(cleanup)
cleanup()
// Seed org tree.
if _, err := conn.ExecContext(ctx, `
INSERT INTO workspaces (id, name, tier, runtime, status, parent_id)
VALUES ($1, $2, 2, 'claude-code', 'online', NULL)`, rootID, prefix+"-root"); err != nil {
t.Fatalf("seed root: %v", err)
}
if _, err := conn.ExecContext(ctx, `
INSERT INTO workspaces (id, name, tier, runtime, status, parent_id)
VALUES ($1, $2, 2, 'claude-code', 'online', $3)`, childID, prefix+"-child", rootID); err != nil {
t.Fatalf("seed child: %v", err)
}
// Org-anchor rows keyed to the OLD root.
if _, err := conn.ExecContext(ctx, `
INSERT INTO org_api_tokens (token_hash, prefix, name, org_id)
VALUES ($1, $2, $3, $4)`,
[]byte("hash-"+tag), tag, prefix+"-tok", rootID); err != nil {
t.Fatalf("seed org_api_token: %v", err)
}
if _, err := conn.ExecContext(ctx, `
INSERT INTO org_plugin_allowlist (org_id, plugin_name, enabled_by)
VALUES ($1, $2, $3)`, rootID, prefix+"-plugin", childID); err != nil {
t.Fatalf("seed allowlist: %v", err)
}
// Install.
if err := installPlatformAgent(ctx, conn, platformID, "Org Concierge"); err != nil {
t.Fatalf("install: %v", err)
}
assertState := func(stage string) {
// platform agent is a kind=platform root.
var kind string
var parent sql.NullString
if err := conn.QueryRowContext(ctx,
`SELECT kind, parent_id FROM workspaces WHERE id = $1`, platformID).Scan(&kind, &parent); err != nil {
t.Fatalf("[%s] read platform agent: %v", stage, err)
}
if kind != "platform" || parent.Valid {
t.Fatalf("[%s] platform agent kind=%q parent=%v, want platform/NULL", stage, kind, parent)
}
// old root re-parented under the platform agent.
var rootParent sql.NullString
if err := conn.QueryRowContext(ctx,
`SELECT parent_id FROM workspaces WHERE id = $1`, rootID).Scan(&rootParent); err != nil {
t.Fatalf("[%s] read old root: %v", stage, err)
}
if !rootParent.Valid || rootParent.String != platformID {
t.Fatalf("[%s] old root parent=%v, want %s", stage, rootParent, platformID)
}
// child untouched.
var childParent sql.NullString
if err := conn.QueryRowContext(ctx,
`SELECT parent_id FROM workspaces WHERE id = $1`, childID).Scan(&childParent); err != nil {
t.Fatalf("[%s] read child: %v", stage, err)
}
if !childParent.Valid || childParent.String != rootID {
t.Fatalf("[%s] child parent=%v, want %s (unchanged)", stage, childParent, rootID)
}
// org-anchor references moved to the platform agent.
var tokOrg, alOrg string
if err := conn.QueryRowContext(ctx,
`SELECT org_id FROM org_api_tokens WHERE prefix = $1`, tag).Scan(&tokOrg); err != nil {
t.Fatalf("[%s] read token org_id: %v", stage, err)
}
if tokOrg != platformID {
t.Fatalf("[%s] org_api_tokens.org_id=%s, want %s", stage, tokOrg, platformID)
}
if err := conn.QueryRowContext(ctx,
`SELECT org_id FROM org_plugin_allowlist WHERE plugin_name = $1`, prefix+"-plugin").Scan(&alOrg); err != nil {
t.Fatalf("[%s] read allowlist org_id: %v", stage, err)
}
if alOrg != platformID {
t.Fatalf("[%s] org_plugin_allowlist.org_id=%s, want %s", stage, alOrg, platformID)
}
// orgRootID + sameOrg now resolve everything to the platform agent.
got, err := orgRootID(ctx, conn, childID)
if err != nil {
t.Fatalf("[%s] orgRootID(child): %v", stage, err)
}
if got != platformID {
t.Fatalf("[%s] orgRootID(child)=%s, want %s", stage, got, platformID)
}
same, err := sameOrg(ctx, conn, childID, platformID)
if err != nil || !same {
t.Fatalf("[%s] sameOrg(child, platform)=%v err=%v, want true", stage, same, err)
}
}
assertState("first install")
// Idempotent: second install must not error or change state.
if err := installPlatformAgent(ctx, conn, platformID, "Org Concierge"); err != nil {
t.Fatalf("second install (idempotent): %v", err)
}
assertState("second install")
// Neither seeded team node is a root any more — the platform agent is.
var nRoots int
if err := conn.QueryRowContext(ctx,
`SELECT count(*) FROM workspaces WHERE parent_id IS NULL AND id IN ($1, $2)`,
rootID, childID).Scan(&nRoots); err != nil {
t.Fatalf("count roots: %v", err)
}
if nRoots != 0 {
t.Fatalf("team roots after install = %d, want 0 (old root re-parented under platform agent)", nRoots)
}
}
@@ -0,0 +1,27 @@
package handlers
import (
"bytes"
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
)
// TestInstallPlatformAgent_BadJSON rejects a payload missing the required id
// before touching the DB (binding:"required" on ID).
func TestInstallPlatformAgent_BadJSON(t *testing.T) {
gin.SetMode(gin.TestMode)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("POST", "/admin/org/platform-agent",
bytes.NewBufferString(`{"name":"Org Concierge"}`)) // no id
c.Request.Header.Set("Content-Type", "application/json")
InstallPlatformAgent(c)
if w.Code != http.StatusBadRequest {
t.Errorf("missing id: expected 400, got %d: %s", w.Code, w.Body.String())
}
}
@@ -161,7 +161,7 @@ func (h *PluginsHandler) uninstallViaDocker(ctx context.Context, c *gin.Context,
// 1. Strip plugin's rule/fragment markers from CLAUDE.md (mirrors
// AgentskillsAdaptor.uninstall lines 184-188). Best-effort: if
// the user edited CLAUDE.md, our marker stays untouched.
h.stripPluginMarkersFromMemory(ctx, containerName, pluginName)
h.stripPluginMarkersFromMemory(ctx, workspaceID, containerName, pluginName)
// 2. Remove copied skill dirs declared in the plugin's plugin.yaml.
for _, skill := range skillNames {
@@ -171,9 +171,11 @@ func (h *PluginsHandler) uninstallViaDocker(ctx context.Context, c *gin.Context,
log.Printf("Plugin uninstall: skipping invalid skill name %q in %s: %v", skill, pluginName, err)
continue
}
_, _ = h.execAsRoot(ctx, containerName, []string{
if _, rmErr := h.execAsRoot(ctx, containerName, []string{
"rm", "-rf", "/configs/skills/" + skill,
})
}); rmErr != nil {
log.Printf("Plugin uninstall: failed to remove skill %s from %s: %v", skill, workspaceID, rmErr)
}
}
// 3. Delete the plugin directory itself (as root to handle file ownership).
@@ -393,7 +393,7 @@ func (h *PluginsHandler) readPluginSkillsFromContainer(ctx context.Context, cont
// `# Plugin: <name> /` — mirrors AgentskillsAdaptor.uninstall's stripping
// logic so install/uninstall are symmetric. Best-effort: silent on read or
// write failure, since the rest of uninstall must still succeed.
func (h *PluginsHandler) stripPluginMarkersFromMemory(ctx context.Context, containerName, pluginName string) {
func (h *PluginsHandler) stripPluginMarkersFromMemory(ctx context.Context, workspaceID, containerName, pluginName string) {
// Use sed via bash -c for atomic in-place delete: drop the marker line
// and the blank line that follows it (install adds a leading blank line
// before the marker via append_to_memory). Three sed passes mirror the
@@ -417,7 +417,9 @@ func (h *PluginsHandler) stripPluginMarkersFromMemory(ctx context.Context, conta
`awk 'BEGIN{skip=0; blanks=0} /^%s/{skip=1; blanks=0; next} skip==1 && /^[[:space:]]*$/{blanks++; if(blanks>=2){skip=0; print; next} next} /^# Plugin: /{if(skip==1)skip=0} skip==1{next} {print}' /configs/CLAUDE.md > /tmp/claude.new && mv /tmp/claude.new /configs/CLAUDE.md`,
regexpEscapeForAwk(marker),
)
_, _ = h.execAsRoot(ctx, containerName, []string{"bash", "-c", script})
if _, awkErr := h.execAsRoot(ctx, containerName, []string{"bash", "-c", script}); awkErr != nil {
log.Printf("Plugin uninstall: failed to strip markers from CLAUDE.md for %s in %s: %v", pluginName, workspaceID, awkErr)
}
}
// regexpEscapeForAwk escapes characters that have special meaning inside an
@@ -9,6 +9,7 @@ import (
"regexp"
"strings"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/approvals"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/audit"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/crypto"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/db"
@@ -320,6 +321,18 @@ func (h *SecretsHandler) Set(c *gin.Context) {
return
}
// RFC platform-agent Phase 4b: gate org-token (platform-agent) secret writes
// behind human approval. The context includes the key so an approval for one
// secret cannot authorise writing another. No-op for ordinary callers and
// when the rollout flag is off (scoping lives in gateDestructive).
// SecretsHandler has no broadcaster, so pass nil — requireApproval persists
// the pending row regardless; only the live canvas push is skipped.
if !gateDestructive(c, nil, workspaceID, approvals.ActionSecretWrite,
"write secret "+body.Key,
map[string]interface{}{"workspace_id": workspaceID, "key": body.Key}) {
return
}
// Encrypt the value (AES-256-GCM if SECRETS_ENCRYPTION_KEY is set, plaintext otherwise)
encrypted, err := crypto.Encrypt([]byte(body.Value))
if err != nil {
@@ -14,6 +14,7 @@ import (
"net/http"
"os"
"path/filepath"
"runtime/debug"
"strings"
"sync"
"time"
@@ -113,6 +114,11 @@ func (h *WorkspaceHandler) goAsync(fn func()) {
h.asyncWG.Add(1)
go func() {
defer h.asyncWG.Done()
defer func() {
if r := recover(); r != nil {
log.Printf("PANIC recovered in goAsync goroutine: %v\n%s", r, debug.Stack())
}
}()
fn()
}()
}
@@ -151,6 +157,11 @@ func globalGoAsync(fn func()) {
globalAsync.Add(1)
go func() {
defer globalAsync.Done()
defer func() {
if r := recover(); r != nil {
log.Printf("PANIC recovered in globalGoAsync goroutine: %v\n%s", r, debug.Stack())
}
}()
fn()
}()
}
@@ -16,6 +16,7 @@ import (
"strings"
"time"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/approvals"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/db"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/events"
"git.moleculesai.app/molecule-ai/molecule-core/workspace-server/internal/models"
@@ -356,6 +357,16 @@ func (h *WorkspaceHandler) Delete(c *gin.Context) {
return
}
// RFC platform-agent Phase 4b: gate org-token (platform-agent) deletes behind
// human approval. No-op for ordinary workspace/CP-session callers and when
// the rollout flag is off (scoping lives in gateDestructive). Placed after
// the synchronous X-Confirm-Name guard, before any destruction.
if !gateDestructive(c, h.broadcaster, id, approvals.ActionDeleteWorkspace,
"delete workspace "+workspaceName,
map[string]interface{}{"workspace_id": id, "name": workspaceName}) {
return
}
// Check for children
rows, err := db.DB.QueryContext(ctx,
`SELECT id, name FROM workspaces WHERE parent_id = $1 AND status != 'removed'`, id)
@@ -45,7 +45,7 @@ type restartState struct {
// flipped running=true. Used by the self-fire debounce (internal#544,
// the ws-server self-fire restart feedback loop seen in prod-Reviewer/
// Researcher 2026-05-19 ~00:05Z 4x reprov thrash): any RestartByID
// arriving within restartDebounceWindow of this timestamp is silently
// arriving within RestartDebounceWindow of this timestamp is silently
// dropped so a probe firing during the EC2-pending window can't
// re-trigger a fresh full cycle on the just-launched instance.
restartStartedAt time.Time
@@ -55,13 +55,19 @@ type restartState struct {
// its own entry so unrelated workspaces don't serialize on each other.
var restartStates sync.Map // map[workspaceID]*restartState
// restartDebounceWindow is the silent-drop window for successive RestartByID
// RestartDebounceWindow is the silent-drop window for successive RestartByID
// calls. Sized to cover the typical EC2 pending → online interval (20-30s)
// with a margin so a probe firing during the just-after-online but still-
// flaky heartbeat window also gets dropped. Bigger than that would block
// legitimate "Restart failed, retry" recoveries; smaller would let the
// 4x thrash class through. Package-level so tests can shrink it.
var restartDebounceWindow = 60 * time.Second
//
// COUPLING: this window MUST be >= the CP instance reconciler interval
// (cmd/server/main.go:355, currently 60s). If the interval ever shrinks
// below this window, a workspace flipped offline by one reconcile tick can
// be reprovisioned again by the next tick before the debounce drops it,
// reopening the double-reprovision thrash class (internal#544).
var RestartDebounceWindow = 60 * time.Second
// restartByIDDropCounter is incremented every time RestartByID drops a call
// inside the debounce window. Exposed as a package-level atomic counter so
@@ -536,7 +542,7 @@ func (h *WorkspaceHandler) RestartByID(workspaceID string) {
return
}
// Self-fire debounce: drop (not coalesce) successive RestartByID calls
// within restartDebounceWindow of the most recent cycle's start. This
// within RestartDebounceWindow of the most recent cycle's start. This
// is the load-bearing protection against the 4x reprov thrash class —
// coalesceRestart's pending-flag would otherwise drain by running
// ANOTHER full cycle of stop+provision on the just-launched EC2 (still
@@ -550,14 +556,14 @@ func (h *WorkspaceHandler) RestartByID(workspaceID string) {
if shouldDebounceRestart(workspaceID) {
restartByIDDropCounter.Add(1)
log.Printf("RestartByID: %s — dropped (within %s self-fire debounce window; total dropped=%d)",
workspaceID, restartDebounceWindow, restartByIDDropCounter.Load())
workspaceID, RestartDebounceWindow, restartByIDDropCounter.Load())
return
}
coalesceRestart(workspaceID, func() { h.runRestartCycle(workspaceID) })
}
// shouldDebounceRestart reports whether the most recent cycle for this
// workspace started within restartDebounceWindow. Read-only on
// workspace started within RestartDebounceWindow. Read-only on
// restartState; the actual restartStartedAt stamp is written in
// coalesceRestart when running flips false→true.
func shouldDebounceRestart(workspaceID string) bool {
@@ -571,7 +577,7 @@ func shouldDebounceRestart(workspaceID string) bool {
if state.restartStartedAt.IsZero() {
return false
}
return time.Since(state.restartStartedAt) < restartDebounceWindow
return time.Since(state.restartStartedAt) < RestartDebounceWindow
}
// coalesceRestart implements the pending-flag gate around an arbitrary cycle
@@ -594,7 +600,7 @@ func coalesceRestart(workspaceID string, cycle func()) {
}
state.running = true
// Stamp the start time so the RestartByID debounce can drop any
// self-fire probe that hits within restartDebounceWindow. Only the
// self-fire probe that hits within RestartDebounceWindow. Only the
// false→true edge stamps; the drain-loop's inner cycles re-use the
// same start (they're effectively one "restart event" from the
// debounce's POV).
@@ -203,9 +203,9 @@ func TestRestartByID_DebounceExpiresAfterWindow(t *testing.T) {
const wsID = "self-fire-ws-debounce-release"
resetSelfFireState(wsID)
orig := restartDebounceWindow
restartDebounceWindow = 5 * time.Millisecond
defer func() { restartDebounceWindow = orig }()
orig := RestartDebounceWindow
RestartDebounceWindow = 5 * time.Millisecond
defer func() { RestartDebounceWindow = orig }()
// Stamp inside the window.
sv, _ := restartStates.LoadOrStore(wsID, &restartState{})
@@ -56,6 +56,11 @@ func TestINSERTworkspacesAllowlist(t *testing.T) {
// workspace; UUID is server-generated. Caller intent IS to
// create, so no idempotency check is needed.
"workspace.go:Create": "single-workspace POST, server-generated UUID",
// platform_agent.installPlatformAgent: single platform-agent row,
// caller-supplied deterministic UUID; INSERT is idempotent via
// ON CONFLICT (id) DO UPDATE and runs inside the install transaction.
// Pinned by TestIntegration_PlatformAgentInstall_ReparentsRootAndMovesAnchors.
"platform_agent.go:installPlatformAgent": "ON CONFLICT (id) DO UPDATE, single row in tx",
}
actual := map[string]string{}
@@ -426,6 +426,12 @@ func Setup(hub *ws.Hub, broadcaster *events.Broadcaster, prov *provisioner.Provi
adminTokH := handlers.NewAdminWorkspaceTokenHandler()
r.POST("/admin/workspaces/:id/tokens", middleware.AdminAuth(db.DB), adminTokH.Create)
// Platform agent install — idempotently makes the org-level concierge
// the org root (re-parents the existing root + moves org-anchor refs).
// Called by the control plane at org provision + existing-org backfill.
// (RFC docs/design/rfc-platform-agent.md)
r.POST("/admin/org/platform-agent", middleware.AdminAuth(db.DB), handlers.InstallPlatformAgent)
// Memory
memh := handlers.NewMemoryHandler()
wsAuth.GET("/memory", memh.List)
@@ -199,6 +199,11 @@ func (s *Scheduler) Start(ctx context.Context) {
// entry/exit — those are kept as redundant signals but this pulse is the
// one that guarantees liveness freshness regardless of tick state.
go func() {
defer func() {
if r := recover(); r != nil {
log.Printf("PANIC recovered in scheduler heartbeat goroutine: %v", r)
}
}()
pulseTicker := time.NewTicker(10 * time.Second)
defer pulseTicker.Stop()
for {
@@ -638,6 +643,11 @@ func (s *Scheduler) fireSchedule(ctx context.Context, sched scheduleRow) {
summary := s.extractResponseSummary(respBody)
if summary != "" {
go func(wsID, text string) {
defer func() {
if r := recover(); r != nil {
log.Printf("PANIC recovered in broadcast summary goroutine: %v", r)
}
}()
postCtx, postCancel := context.WithTimeout(context.Background(), 30*time.Second)
defer postCancel()
s.channels.BroadcastToWorkspaceChannels(postCtx, wsID, text)