Commit Graph

4614 Commits

Author SHA1 Message Date
b9d2786f45 fix(ci): e2e-api — parallel-safe postgres/redis containers + provisioner setup
Class B Hongming-owned CICD red sweep, e2e-api leg. Same substrate
hazard as PR #98 (handlers-postgres-integration) — Gitea act_runner
configures `container.network: host` operator-wide, so:

  * Two concurrent e2e-api runs both attempted to bind `-p 15432:5432`
    and `-p 16379:6379` on the operator host. Verified in run a7/2727
    on 2026-05-07: `docker: Error response from daemon: Conflict. The
    container name "/molecule-ci-redis" is already in use by container
    af10f438...` — exit 125, job fails before any test runs.
  * Hardcoded container names `molecule-ci-postgres` / `-redis` plus
    the leading `docker rm -f` step meant a second job's startup also
    KILLED the first job's still-running services.

Fix shape (mirrors PR #98 bridge-net pattern, adapted because the
platform-server is a Go binary on the host, not a containerised step):

  1. Per-run unique container names: `pg-e2e-api-${RUN_ID}-${RUN_ATTEMPT}`,
     `redis-e2e-api-${RUN_ID}-${RUN_ATTEMPT}`. Unique even across reruns
     of the same run_id.
  2. Ephemeral host port per run via `-p 0:5432` / `-p 0:6379` and
     `docker port` lookup, exported as `DATABASE_URL` / `REDIS_URL` to
     `$GITHUB_ENV`. No fixed host-port → no collision.
  3. `127.0.0.1` (NOT `localhost`) in URLs — IPv6 first-resolve flake
     fixed in #92 stays fixed.
  4. `if: always()` cleanup so containers don't leak when test steps
     fail.

Issue #94 items #2 + #3 also addressed:

  * Pre-pull `alpine:latest` (provisioner uses it for ephemeral
    token-write containers in `internal/handlers/container_files.go`).
  * Idempotent `docker network create molecule-monorepo-net` (the
    provisioner attaches workspace containers via that bridge —
    `internal/provisioner/provisioner.go::DefaultNetwork`).

Issue #94 item #1 (timeouts) NOT bumped — recent log evidence shows
postgres ready in 3s, redis in 1s, platform in 1s when they DO come
up. Timeouts are not the bottleneck on the current substrate.

NOT addressed here (out of scope, separate change required):

  * `Run E2E API tests` step has been failing on `Status back online`
    because the platform's langgraph workspace template image
    (`ghcr.io/molecule-ai/workspace-template-langgraph:latest`)
    returns 403 Forbidden post-2026-05-06 GitHub org suspension. That
    is a template-registry resolution issue (ADR-002 / local-build
    mode) and belongs in a workspace-server change, not this workflow
    file. This PR fixes the parallel-collision class and the workflow
    setup hygiene; the langgraph-403 failure will still surface on
    runs after this lands until template resolution is fixed
    separately.

Verified manually on operator host 2026-05-08: docker now hands out
ephemeral ports on `-p 0:5432`, two parallel runs land on different
ports, both reach pg_isready GREEN.

Closes #94 (items #2 and #3; item #1 documented as not-bottleneck;
langgraph-template-403 referenced for follow-up).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:59:56 -07:00
068c968206 docs(hermes): hermes-agent fork moved to Gitea (#90)
Doc update reflecting #160 hermes-agent migration. Approved by security-auditor.
2026-05-08 01:17:03 +00:00
97c042f666 Merge branch 'main' into fix/hermes-agent-doc-gitea-migration 2026-05-08 00:54:30 +00:00
3d6303afcc fix(ci): rewrite retarget-main-to-staging for Gitea REST API (#79)
Closes #74. Approved by security-auditor.
2026-05-08 00:26:27 +00:00
3fcaa1fcc5 Merge branch 'main' into fix/hermes-agent-doc-gitea-migration 2026-05-08 00:21:17 +00:00
6c823cf673 Merge branch 'main' into fix/196-retarget-main-to-staging-gitea-rest 2026-05-08 00:20:49 +00:00
4193d54852 fix(ci): pin actions/upload-artifact + download-artifact to @v3 (#89)
Closes #210. Unblocks 5 stuck PRs (#53/#54/#69/#71/#76/#81). Approved by security-auditor.
2026-05-08 00:20:00 +00:00
devops-engineer
0bcf195fbc docs(hermes): hermes-agent fork moved to Gitea (post-suspension)
The `HongmingWang-Rabbit/hermes-agent` fork is no longer reachable on
github.com (account suspended 2026-05-06). The patched fork now lives
at https://git.moleculesai.app/molecule-ai/hermes-agent. Same SHAs,
same branches — pure URL flip.

See molecule-ai/internal#72 for the github.com fork shell decision.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 16:57:57 -07:00
8885f7cd12 fix(ci): pin actions/upload-artifact + download-artifact to @v3 for Gitea compatibility
actions/upload-artifact@v4+ and download-artifact@v4+ use the GHES 3.10+
artifact protocol that Gitea Actions (act_runner v0.6 / Gitea 1.22.x)
does NOT implement. Failure cite from PR #54 run 1325 jobs/2:

  ::error::@actions/artifact v2.0.0+, upload-artifact@v4+ and
  download-artifact@v4+ are not currently supported on GHES.

Pinned all 3 references to v3.2.2 (latest v3) at SHA-pinned form for
supply-chain hygiene, matching the existing `uses:` style in this repo.
Affected workflows:
  - ci.yml (Canvas Next.js coverage upload, blocks `CI / Canvas (Next.js)`
    required check on every PR — was the merge-queue blocker for #53,
    #54, #69, #71, #76, #81)
  - e2e-staging-canvas.yml (Playwright report + screenshots on failure)

No download-artifact callers in the repo, so v3-pin doesn't compose-break
anywhere. Drop these pins post-Gitea-1.23+ when the v4 artifact protocol
ships, or migrate to a Gitea-native action.

Closes #210.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 16:54:44 -07:00
cdbf28fd76 ci(canary): synthetic-check cron for AUTO_SYNC_TOKEN rotation drift (#77)
6h cron probes auth + scope + git-push --dry-run. Closes #72. Approved by security-auditor.
2026-05-07 23:45:25 +00:00
4b82db72a7 Merge branch 'main' into fix/issue-72-auto-sync-token-canary-v2 2026-05-07 23:44:22 +00:00
07bd91e436 fix(ci): replace gh run list with Gitea commit-status query (#83)
Class F of #75 sweep. /commits/{sha}/statuses replaces unavailable workflow-runs API. 4 mapping buckets verified against synthetic+real Gitea data. Approved by security-auditor.
2026-05-07 23:44:21 +00:00
ed0874504e Merge branch 'main' into fix/issue75-class-F-gh-run-list-to-statuses 2026-05-07 23:44:00 +00:00
e39fc92074 fix(ci): replace gh pr CLI with Gitea v1 REST in workflows + scripts (#80)
Class A of #75 sweep. 23 bash + 9 python tests pass. Live-integration verified against prod Gitea. Approved by security-auditor.
2026-05-07 23:39:22 +00:00
1819ac21f4 Merge branch 'main' into fix/issue75-class-A-gh-pr-to-gitea-rest 2026-05-07 23:37:57 +00:00
d84d88ad70 feat(workspace-server): local-dev provisioner builds from Gitea source (#70)
Hongming-locked Option C: MOLECULE_IMAGE_REGISTRY presence as mode marker. ADR-002 captures rationale. 30 new tests + 64 existing preserved. Hostile-review weakest 3 filed as #204/#205/#206 follow-ups. Closes #63 (Task #194). Approved by security-auditor.
2026-05-07 23:37:56 +00:00
6bb272360d Merge branch 'main' into feat/issue-63-local-build-from-gitea-v2 2026-05-07 23:33:03 +00:00
1f1ead1833 fix(ci): rewrite auto-promote-staging for Gitea (#78)
Removes ~60 lines polling+dispatch (Gitea fires on:push naturally on token-merge). Uses Gitea merge_when_checks_succeed; preserves required_approvals=1 on main. Closes #73. Approved by security-auditor.
2026-05-07 23:32:58 +00:00
c5f40de585 Merge branch 'main' into fix/195-auto-promote-staging-gitea-rest 2026-05-07 23:30:09 +00:00
330a5842ab Merge pull request 'feat(canvas): ActivityTab → ACTIVITY_LOGGED subscriber (#61 stage 3, final)' (#76) from feat/canvas-activity-tab-ws-subscribe into main 2026-05-07 23:27:32 +00:00
2505b36a2c Merge branch 'main' into fix/195-auto-promote-staging-gitea-rest 2026-05-07 23:22:24 +00:00
security-auditor
e0feae18f4 Merge remote-tracking branch 'origin/main' into feat/canvas-activity-tab-ws-subscribe 2026-05-07 16:18:34 -07:00
502aa082bc Merge pull request 'feat(canvas): A2ATopologyOverlay → ACTIVITY_LOGGED subscriber (#61 stage 2)' (#71) from feat/canvas-topology-overlay-ws-subscribe into main 2026-05-07 23:18:24 +00:00
security-auditor
8f732511b1 Merge remote-tracking branch 'origin/main' into feat/canvas-activity-tab-ws-subscribe 2026-05-07 16:04:39 -07:00
security-auditor
7d0df65474 Merge remote-tracking branch 'origin/main' into feat/canvas-topology-overlay-ws-subscribe 2026-05-07 16:04:29 -07:00
33327cf077 Merge pull request 'feat(canvas): CommunicationOverlay → ACTIVITY_LOGGED subscriber (#61 stage 1)' (#69) from feat/canvas-comm-overlay-ws-subscribe into main 2026-05-07 23:04:18 +00:00
fa27611e9c Merge branch 'main' into fix/196-retarget-main-to-staging-gitea-rest 2026-05-07 23:02:10 +00:00
security-auditor
865a366573 Merge remote-tracking branch 'origin/main' into feat/canvas-activity-tab-ws-subscribe 2026-05-07 15:56:56 -07:00
security-auditor
b73f599184 Merge remote-tracking branch 'origin/main' into feat/canvas-topology-overlay-ws-subscribe 2026-05-07 15:56:52 -07:00
security-auditor
5855be50b4 Merge remote-tracking branch 'origin/main' into feat/canvas-comm-overlay-ws-subscribe 2026-05-07 15:56:49 -07:00
e766061800 Merge pull request 'fix(ratelimit): tenant-aware bucket keying — close canvas 429 storm (#59)' (#60) from fix/canvas-429-tenant-aware-ratelimit into main 2026-05-07 22:56:38 +00:00
ca644134f2 Merge branch 'main' into fix/196-retarget-main-to-staging-gitea-rest 2026-05-07 22:54:31 +00:00
security-auditor
e909417224 Merge remote-tracking branch 'origin/main' into feat/canvas-activity-tab-ws-subscribe 2026-05-07 15:54:06 -07:00
security-auditor
9bb4bbdff7 Merge remote-tracking branch 'origin/main' into feat/canvas-topology-overlay-ws-subscribe 2026-05-07 15:54:03 -07:00
security-auditor
bec1cb3786 Merge remote-tracking branch 'origin/main' into feat/canvas-comm-overlay-ws-subscribe 2026-05-07 15:54:00 -07:00
security-auditor
1d6b09f2bd Merge remote-tracking branch 'origin/main' into fix/canvas-429-tenant-aware-ratelimit 2026-05-07 15:53:57 -07:00
0be89053e8 Merge pull request 'chore(observability): edge-429 probe + ratelimit runbook (unblocks #62, #64)' (#85) from chore/edge-429-probe-and-ratelimit-runbook into main 2026-05-07 22:53:48 +00:00
d81fb98163 Merge branch 'main' into fix/issue-72-auto-sync-token-canary-v2 2026-05-07 22:53:32 +00:00
4d5c9a6646 Merge branch 'main' into fix/issue75-class-F-gh-run-list-to-statuses 2026-05-07 22:53:26 +00:00
9ecee78782 Merge branch 'main' into fix/issue75-class-A-gh-pr-to-gitea-rest 2026-05-07 22:53:11 +00:00
141dfdae52 Merge branch 'main' into feat/issue-63-local-build-from-gitea-v2 2026-05-07 22:53:04 +00:00
d21c09babe Merge branch 'main' into fix/195-auto-promote-staging-gitea-rest 2026-05-07 22:53:00 +00:00
2b3a8f2e4d Merge branch 'main' into fix/196-retarget-main-to-staging-gitea-rest 2026-05-07 22:52:35 +00:00
security-auditor
9eb530bbf0 Merge remote-tracking branch 'origin/main' into chore/edge-429-probe-and-ratelimit-runbook 2026-05-07 15:52:29 -07:00
security-auditor
62e793040e chore(observability): edge-429 probe + ratelimit observability runbook
Two artifacts that unblock the parked follow-ups from #59:

  1. scripts/edge-429-probe.sh (closes the "operator-blocked" status of
     #62). An operator without CF/Vercel dashboard access can reproduce
     a canvas-sized burst against a tenant subdomain and read each 429's
     response shape — workspace-server bucket overflow (JSON body +
     X-RateLimit-* headers) is distinguishable from CF (cf-ray) and
     Vercel (x-vercel-id) by inspection of the report. Read-only,
     parallel via background subshells (no GNU parallel dependency),
     no credential use. Smoke-tested against example.com end-to-end.

  2. docs/engineering/ratelimit-observability.md (closes the
     "metric-blocked" status of #64). The existing
     molecule_http_requests_total{path,status} counter + X-RateLimit-*
     response headers already cover #64's acceptance criterion ("watch
     metrics for two weeks"). The runbook collects the PromQL queries,
     a decision tree for the re-tune (keep / per-tenant override /
     change default), an alert rule template, and a hard "do not roll
     ad-hoc per-bucket-key exposure" note (in-memory map includes
     SHA-256 of bearer tokens — exposing it is a security review
     surface, file a follow-up if needed).

Neither artifact changes runtime behaviour. Pure operational tooling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:48:34 -07:00
6946cd12c5 ci(branch-protection): check-name parity gate (#144) (#56)
Adds tools/branch-protection/check_name_parity.sh regression guard + 6 shell tests + branch-protection-drift.yml wire-up.

Closed #144. Approved by security-auditor.
2026-05-07 22:42:08 +00:00
e43bd7ceb0 chore: 2nd verification trigger for #75 class A (per Phase 4 ≥2 green runs)
Empty commit to trigger CI a second consecutive time per the SOP
'verify ≥1 representative workflow per class via workflow_dispatch
or push event ... ≥2 consecutive successful runs per class'.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:41:00 -07:00
85140f1c72 Merge branch 'main' into fix/issue-72-auto-sync-token-canary-v2 2026-05-07 22:40:56 +00:00
5b3ce5c818 fix(ci): replace gh run list with Gitea commit-status query (#75 class F)
Part of the post-#66 sweep to remove `gh` CLI dependencies that fail
silently against Gitea. Class F covers `gh run list --workflow=X
--commit=SHA` shapes — querying whether a specific workflow ran (and
how it finished) for a specific SHA.

Why this is the only call site in class F:

`gh run list` hits GitHub's `/repos/.../actions/runs` REST endpoint.
Gitea exposes ZERO endpoints under `/repos/.../actions/runs` —
verified 2026-05-07 via swagger inspection: only secrets, variables,
and runner-registration tokens live under /actions/. There's no way
to query workflow run state via the Gitea v1 API directly.

However, every Gitea Actions job DOES emit a commit status with
`context = "<Workflow Name> / <Job Name> (<event>)"` (verified
2026-05-07 by reading /repos/.../commits/{sha}/statuses on a recent
main SHA). That surface is exactly what we need: each workflow run
leg is one status row, the aggregate state encodes the run outcome,
and Gitea exposes it under `/api/v1/repos/.../commits/{sha}/statuses`
which IS available.

Affected:

`auto-promote-on-e2e.yml` (lines 172-180):
  Old: `gh run list --workflow e2e-staging-saas.yml --commit $SHA
       --json status,conclusion --jq ...` returning a 5-bucket string
       like `completed/success` | `in_progress/none` | `none/none` |
       `completed/failure` | `completed/cancelled`.
  New: `curl /api/v1/repos/.../commits/$SHA/statuses` + jq filter on
       contexts whose name starts with
       `"E2E Staging SaaS (full lifecycle) /"`. Mapping:
         0 matched contexts          → "none/none"      (E2E paths-
                                                          filtered out
                                                          — same as
                                                          before)
         any context = pending       → "in_progress/none" (defer)
         any context = error|failure → "completed/failure" (abort)
         all contexts = success      → "completed/success" (proceed)
  The `completed/cancelled` arm of the case statement becomes
  unreachable: Gitea status API doesn't expose a `cancelled` state
  (it has success/failure/error/pending/warning), so per-SHA
  concurrency cancellations now surface as `failure` and are handled
  by the failure branch. Documented in-place; the cancelled arm is
  kept as defense-in-depth for any future dual-host operation.

Verification:

- Live curl against the current main SHA returns `none/none` (E2E
  was paths-filtered for that change set — expected).
- Synthetic-input jq tests verify all four mapping buckets:
    no contexts                 → "none/none"
    one context = pending       → "in_progress/none"
    success + success           → "completed/success"
    success + failure           → "completed/failure"
- YAML syntax validates.

Token: continues to use act_runner's GITHUB_TOKEN (per-run, repo
read scope). The `/commits/{sha}/statuses` endpoint is repo-scoped,
no extra perms needed.

Closes part of #75. Master tracking issue at #75; companion PRs:
#80 (class A — `gh pr ...`), #81 (class D — `gh api ...`).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:38:57 -07:00
bcc72419ce Merge branch 'main' into fix/144-branch-protection-check-name-parity-audit 2026-05-07 22:35:33 +00:00