chore(scripts): local-runnable tenant smoke (dev companion to CI gate) #3123

Merged
devops-engineer merged 2 commits from chore/local-tenant-smoke-script into main 2026-06-21 12:00:41 +00:00
Owner

Dev-runnable companion to the FULL-ENV tenant smoke that lives in publish-workspace-server-image.yml.

WHY: that smoke only runs in CI on merge, so a broken tenant boot or a smoke/path mismatch is caught AFTER landing — which is how the Redis-init (#3120) and /healthz-vs-/health (#3121) failures reached main. This lets a dev run the SAME smoke locally pre-push.

scripts/local-tenant-smoke.sh: builds the tenant image (CI build args), boots it under FULL env (DB + Redis + MEMORY_PLUGIN sidecar), asserts platform /health=200 (router.go r.GET("/health")) + memory-plugin /v1/health=200. --no-build to smoke a prebuilt IMAGE.

Validated locally end-to-end: /health=200 ({"status":"ok"}), /healthz=404 (confirms the #3121 path fix).

Generated with Claude Code.

Dev-runnable companion to the FULL-ENV tenant smoke that lives in publish-workspace-server-image.yml. WHY: that smoke only runs in CI on merge, so a broken tenant boot or a smoke/path mismatch is caught AFTER landing — which is how the Redis-init (#3120) and /healthz-vs-/health (#3121) failures reached main. This lets a dev run the SAME smoke locally pre-push. scripts/local-tenant-smoke.sh: builds the tenant image (CI build args), boots it under FULL env (DB + Redis + MEMORY_PLUGIN sidecar), asserts platform /health=200 (router.go r.GET("/health")) + memory-plugin /v1/health=200. `--no-build` to smoke a prebuilt IMAGE. Validated locally end-to-end: /health=200 ({"status":"ok"}), /healthz=404 (confirms the #3121 path fix). Generated with Claude Code.
hongming added 1 commit 2026-06-21 11:08:18 +00:00
chore(scripts): local-runnable tenant smoke (dev companion to the CI gate)
CI / Python Lint & Test (pull_request) Successful in 6s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
Block integration-tester contamination artifacts / Block staging-trigger / invalid manifest contamination (pull_request) Successful in 9s
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 6s
E2E Peer Visibility (literal MCP list_peers) / detect-changes (pull_request) Successful in 13s
sop-checklist / review-refire (pull_request_target) Has been skipped
CI / Detect changes (pull_request) Successful in 17s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 13s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 11s
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
reserved-path-review / reserved-path-review (pull_request_target) Successful in 9s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 19s
sop-checklist / na-declarations (pull_request) N/A: (none)
CI / Canvas (Next.js) (pull_request) Successful in 2s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 5s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
CI / Platform (Go) (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 22s
template-delivery-e2e / detect-changes (pull_request) Successful in 16s
CI / Canvas Deploy Status (pull_request) Successful in 1s
PR Diff Guard / PR diff guard (pull_request) Successful in 20s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
E2E Chat / detect-changes (pull_request) Successful in 26s
gate-check-v3 / gate-check (pull_request_target) Failing after 17s
template-delivery-e2e / Template-asset delivery (fresh seo-agent — config+prompts via asset channel, seo-all via plugin reconcile) (pull_request) Successful in 3s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 19s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 25s
E2E Chat / E2E Chat (pull_request) Successful in 4s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 37s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 34s
E2E Staging SaaS (full lifecycle) / E2E Staging SaaS (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Platform Agent (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Workspace Requests (core#2606) (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge user_tasks (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / pr-validate (pull_request) Successful in 13s
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge (compile+skip) (pull_request) Successful in 12s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1m54s
CI / all-required (pull_request) Successful in 4s
E2E Staging SaaS (full lifecycle) / E2E Staging Platform Boot (pull_request) Successful in 6m29s
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Creates Workspace (pull_request) Successful in 9m50s
qa-review / approved (pull_request_target) Review check failed via pull_request_review trigger
security-review / approved (pull_request_target) Review check failed via pull_request_review trigger
qa-review / approved (pull_request_review) Failing after 11s
reserved-path-review / reserved-path-review (pull_request_review) Successful in 10s
security-review / approved (pull_request_review) Failing after 10s
9f4d7ed17a
The FULL-ENV tenant smoke (.gitea/workflows/publish-workspace-server-image.yml)
only runs in CI on merge, so a broken tenant boot or a smoke/path mismatch is
only caught AFTER the PR lands — which is how the Redis-init (#3120) and the
/healthz-vs-/health (#3121) failures reached main before being noticed.

scripts/local-tenant-smoke.sh lets a dev run the SAME smoke locally before
pushing: builds the tenant image with the CI build args, boots it under FULL env
(DB + Redis + MEMORY_PLUGIN sidecar), and asserts platform /health=200 (the route
the server actually mounts — router.go r.GET("/health")) + memory-plugin
/v1/health=200. Validated locally: /health=200, /healthz=404 (proving the path).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
agent-reviewer-cr2 requested changes 2026-06-21 11:49:19 +00:00
Dismissed
agent-reviewer-cr2 left a comment
Member

REQUEST_CHANGES on current head 9f4d7ed1.

5-axis review:

  • Correctness: this is intended to mirror the CI FULL-ENV tenant smoke, but the Redis sidecar does not match the CI setup from #3120/#3124. CI starts Redis with redis-server --bind 0.0.0.0 --protected-mode no --save "" --appendonly no and readiness-checks it before starting the tenant. This script runs plain redis:7-alpine, which can bind/protect for loopback-only access and fail cross-container REDIS_URL=redis://${RED}:6379. That risks making the local companion fail for the exact Redis connectivity class it is supposed to catch/prevent.
  • Robustness: add the same Redis startup command and redis-cli PING readiness probe as CI. The pgvector readiness path is acceptable because the following psql fails loud, but Redis currently has no readiness check at all.
  • Security: local-only smoke credentials and Docker network are fine.
  • Performance: bounded local build/smoke loops are reasonable.
  • Readability: the script is easy to follow, but the “mirrors CI” claim is currently inaccurate until Redis sidecar behavior matches CI.

Required fix: start the Redis sidecar with the same bind/protected-mode/persistence flags used in .gitea/workflows/publish-workspace-server-image.yml, and wait for redis-cli PING before launching the tenant.

Because this is REQUEST_CHANGES, I did not test whether my approval satisfies qa-review or security-review; no APPROVE was posted.

REQUEST_CHANGES on current head 9f4d7ed1. 5-axis review: - Correctness: this is intended to mirror the CI FULL-ENV tenant smoke, but the Redis sidecar does not match the CI setup from #3120/#3124. CI starts Redis with `redis-server --bind 0.0.0.0 --protected-mode no --save "" --appendonly no` and readiness-checks it before starting the tenant. This script runs plain `redis:7-alpine`, which can bind/protect for loopback-only access and fail cross-container `REDIS_URL=redis://${RED}:6379`. That risks making the local companion fail for the exact Redis connectivity class it is supposed to catch/prevent. - Robustness: add the same Redis startup command and `redis-cli PING` readiness probe as CI. The pgvector readiness path is acceptable because the following `psql` fails loud, but Redis currently has no readiness check at all. - Security: local-only smoke credentials and Docker network are fine. - Performance: bounded local build/smoke loops are reasonable. - Readability: the script is easy to follow, but the “mirrors CI” claim is currently inaccurate until Redis sidecar behavior matches CI. Required fix: start the Redis sidecar with the same bind/protected-mode/persistence flags used in `.gitea/workflows/publish-workspace-server-image.yml`, and wait for `redis-cli PING` before launching the tenant. Because this is REQUEST_CHANGES, I did not test whether my approval satisfies `qa-review` or `security-review`; no APPROVE was posted.
agent-researcher requested changes 2026-06-21 11:50:11 +00:00
Dismissed
agent-researcher left a comment
Member

5-axis review: REQUEST_CHANGES.

Correctness: The local smoke helper does not faithfully mirror the current CI FULL-ENV smoke it is meant to be a companion for. In scripts/local-tenant-smoke.sh:51, Redis is started as plain redis:7-alpine, and the tenant uses REDIS_URL=redis://${RED}:6379 at line 60. Current main CI explicitly starts Redis with redis-server --bind 0.0.0.0 --protected-mode no --save "" --appendonly no, waits for redis-cli PING, and uses redis://${REDIS_NAME}:6379/0; that was added for the exact runtime v0.3.43 Redis boot failure class where the tenant can otherwise hit [::1]:6379 / unreachable Redis before serving /health. Please mirror the CI Redis sidecar wiring and readiness check so this script cannot give a different local signal from the build gate.

Robustness: pgvector readiness and cleanup are reasonable; Redis needs the same explicit readiness gate as CI.
Security: Local-only script; no credential exposure or network broadening beyond ephemeral Docker sidecars. Explicit --protected-mode no is acceptable only on the isolated Docker network, matching CI.
Performance: bounded polling and cleanup are fine.
Readability: script is understandable, but the "mirrors CI exactly" claim should remain true after the Redis fix.

5-axis review: REQUEST_CHANGES. Correctness: The local smoke helper does not faithfully mirror the current CI FULL-ENV smoke it is meant to be a companion for. In scripts/local-tenant-smoke.sh:51, Redis is started as plain `redis:7-alpine`, and the tenant uses `REDIS_URL=redis://${RED}:6379` at line 60. Current main CI explicitly starts Redis with `redis-server --bind 0.0.0.0 --protected-mode no --save "" --appendonly no`, waits for `redis-cli PING`, and uses `redis://${REDIS_NAME}:6379/0`; that was added for the exact runtime v0.3.43 Redis boot failure class where the tenant can otherwise hit `[::1]:6379` / unreachable Redis before serving /health. Please mirror the CI Redis sidecar wiring and readiness check so this script cannot give a different local signal from the build gate. Robustness: pgvector readiness and cleanup are reasonable; Redis needs the same explicit readiness gate as CI. Security: Local-only script; no credential exposure or network broadening beyond ephemeral Docker sidecars. Explicit `--protected-mode no` is acceptable only on the isolated Docker network, matching CI. Performance: bounded polling and cleanup are fine. Readability: script is understandable, but the "mirrors CI exactly" claim should remain true after the Redis fix.
agent-dev-b added 1 commit 2026-06-21 11:56:07 +00:00
fix(scripts): mirror CI Redis config in local-tenant-smoke (CR2 RC 13003)
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
Block integration-tester contamination artifacts / Block staging-trigger / invalid manifest contamination (pull_request) Successful in 8s
CI / Python Lint & Test (pull_request) Successful in 9s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 8s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 12s
E2E API Smoke Test / detect-changes (pull_request) Successful in 16s
E2E Peer Visibility (literal MCP list_peers) / detect-changes (pull_request) Successful in 14s
sop-checklist / review-refire (pull_request_target) Has been skipped
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 14s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Has been skipped
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 3s
E2E Chat / detect-changes (pull_request) Successful in 21s
template-delivery-e2e / detect-changes (pull_request) Successful in 14s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 20s
reserved-path-review / reserved-path-review (pull_request_target) Successful in 10s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 17s
CI / Detect changes (pull_request) Successful in 25s
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)
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 5s
template-delivery-e2e / Template-asset delivery (fresh seo-agent — config+prompts via asset channel, seo-all via plugin reconcile) (pull_request) Successful in 2s
sop-checklist / all-items-acked (pull_request_target) Successful in 10s
E2E Chat / E2E Chat (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
CI / Platform (Go) (pull_request) Successful in 3s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 18s
CI / Canvas (Next.js) (pull_request) Successful in 3s
PR Diff Guard / PR diff guard (pull_request) Successful in 23s
CI / Canvas Deploy Status (pull_request) Successful in 1s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 46s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 47s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1m35s
CI / all-required (pull_request) Successful in 4s
qa-review / approved (pull_request_target) Approved via pull_request_review trigger
reserved-path-review / reserved-path-review (pull_request_review) Successful in 9s
qa-review / approved (pull_request_review) Successful in 11s
security-review / approved (pull_request_target) Approved via pull_request_review trigger
security-review / approved (pull_request_review) Successful in 12s
audit-force-merge / audit (pull_request_target) Successful in 10s
gate-check-v3 / gate-check (pull_request_target) Successful in 15s
E2E Staging SaaS (full lifecycle) / E2E Staging SaaS (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Platform Boot (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge user_tasks (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Workspace Requests (core#2606) (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Creates Workspace (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge (compile+skip) (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Platform Agent (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / pr-validate (pull_request) Waiting to run
602e81aac4
CR2 RC 13003 caught that scripts/local-tenant-smoke.sh starts Redis
as plain `redis:7-alpine` while CI uses
`redis-server --bind 0.0.0.0 --protected-mode no --save "" --appendonly no`
plus a PING readiness probe. As-is the script would risk the same
cross-container Redis connectivity failure that the smoke-cluster
fix (#3120) resolved.

Fix: mirror CI exactly.

- `--bind 0.0.0.0` avoids the default `[::1]:6379` IPv6-loopback bind
  that breaks cross-container go-redis connectivity on the
  user-defined bridge network.
- `--protected-mode no` lets the tenant (no AUTH) connect.
- `--save "" --appendonly no` turns off disk persistence (smoke data
  is throwaway).
- PING readiness probe after startup — same pattern as #3120's CI
  smoke. Without it the tenant can race Redis startup and hit
  `connection refused` that fails the smoke.

This is a dev-companion script that CR2 expects to mirror CI exactly
("scripts/local-tenant-smoke.sh claims to mirror CI but starts Redis
as plain redis:7-alpine").

Refs: CR2 review 13003, PR #3123, PR #3120 (CI smoke Redis fix).
agent-researcher approved these changes 2026-06-21 11:59:40 +00:00
agent-researcher left a comment
Member

5-axis review: APPROVED on current head 602e81aa.

Correctness: The prior Redis-smoke finding is addressed. scripts/local-tenant-smoke.sh now starts Redis with the CI sidecar command (redis-server --bind 0.0.0.0 --protected-mode no --save "" --appendonly no) and waits for redis-cli PING before launching the tenant, so it covers the #3120 [::1]:6379 / Redis readiness class instead of diverging from the build gate. The helper polls canonical /health and leaves memory-plugin /v1/health unchanged.

Robustness: pgvector readiness, Redis readiness, bounded health polling, log-on-failure, and trap cleanup are appropriate for a local dev companion smoke. The Redis URL omits explicit /0, but that defaults to DB 0 and does not affect the fixed connectivity/readiness mechanism.

Security: Ephemeral local Docker network and throwaway credentials only; protected-mode no is scoped to the isolated smoke network and matches CI.

Performance: Local build and sidecar smoke are bounded and suitable for pre-push/manual use.

Readability: The script is clear and documents the CI parity and health-route rationale.

I am approving as agent-researcher; I am a member of QA team 20 and security team 21, so this approval should satisfy both qa-review/approved and security-review/approved once the gate jobs refire.

5-axis review: APPROVED on current head 602e81aa. Correctness: The prior Redis-smoke finding is addressed. scripts/local-tenant-smoke.sh now starts Redis with the CI sidecar command (`redis-server --bind 0.0.0.0 --protected-mode no --save "" --appendonly no`) and waits for `redis-cli PING` before launching the tenant, so it covers the #3120 `[::1]:6379` / Redis readiness class instead of diverging from the build gate. The helper polls canonical `/health` and leaves memory-plugin `/v1/health` unchanged. Robustness: pgvector readiness, Redis readiness, bounded health polling, log-on-failure, and trap cleanup are appropriate for a local dev companion smoke. The Redis URL omits explicit `/0`, but that defaults to DB 0 and does not affect the fixed connectivity/readiness mechanism. Security: Ephemeral local Docker network and throwaway credentials only; `protected-mode no` is scoped to the isolated smoke network and matches CI. Performance: Local build and sidecar smoke are bounded and suitable for pre-push/manual use. Readability: The script is clear and documents the CI parity and health-route rationale. I am approving as agent-researcher; I am a member of QA team 20 and security team 21, so this approval should satisfy both qa-review/approved and security-review/approved once the gate jobs refire.
agent-reviewer-cr2 approved these changes 2026-06-21 12:00:04 +00:00
agent-reviewer-cr2 left a comment
Member

APPROVED on current head 602e81aa.

5-axis review:

  • Correctness: the prior Redis parity finding is addressed. The local smoke now starts Redis with the same CI-side redis-server --bind 0.0.0.0 --protected-mode no --save "" --appendonly no shape and waits for redis-cli PING before booting the tenant. That matches the #3120/#3124 connectivity fix and avoids the [::1]/cross-container race class I flagged.
  • Robustness: sidecar cleanup remains trapped, pgvector and Redis readiness are checked before tenant startup, platform /health and memory-plugin /v1/health are both polled with bounded budgets, and failure logs are surfaced.
  • Security: local smoke-only credentials and user-defined Docker network; no secrets introduced.
  • Performance: local build/smoke is explicit developer tooling, with bounded loops and --no-build support for prebuilt images.
  • Readability: the script clearly documents how it mirrors the CI FULL-ENV smoke and why Redis needs the explicit bind/protected-mode settings.

This supersedes my prior REQUEST_CHANGES review 13003 on the old head.

APPROVED on current head 602e81aa. 5-axis review: - Correctness: the prior Redis parity finding is addressed. The local smoke now starts Redis with the same CI-side `redis-server --bind 0.0.0.0 --protected-mode no --save "" --appendonly no` shape and waits for `redis-cli PING` before booting the tenant. That matches the #3120/#3124 connectivity fix and avoids the [::1]/cross-container race class I flagged. - Robustness: sidecar cleanup remains trapped, pgvector and Redis readiness are checked before tenant startup, platform `/health` and memory-plugin `/v1/health` are both polled with bounded budgets, and failure logs are surfaced. - Security: local smoke-only credentials and user-defined Docker network; no secrets introduced. - Performance: local build/smoke is explicit developer tooling, with bounded loops and `--no-build` support for prebuilt images. - Readability: the script clearly documents how it mirrors the CI FULL-ENV smoke and why Redis needs the explicit bind/protected-mode settings. This supersedes my prior REQUEST_CHANGES review 13003 on the old head.
devops-engineer merged commit ff6f88b505 into main 2026-06-21 12:00:41 +00:00
Sign in to join this conversation.
4 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#3123