WIP: test(registry-auth): real-Postgres TestIntegration_ suite (#2148) #2156

Draft
molecule-code-reviewer wants to merge 2 commits from test/2148-registry-auth-real-postgres into main
Member

Closes #2148

What

Real-Postgres TestIntegration_ regression suite for the registry-auth + cross-tenant security boundary (SOP rule internal#765, test_layer: real-postgres). Filed from the 2026-06-02 platform-wide coverage audit — this package was sqlmock-only, asserting which SQL fired rather than that a real DB enforces the org non-leak.

New file: workspace-server/internal/handlers/registry_auth_integration_test.go (//go:build integration, INTEGRATION_DB_URL, skip-if-unset — same harness as delegation_ledger_integration_test.go / pending_uploads_integration_test.go). It reuses the package-global db.DB hot-swap so registry.CanCommunicate (which reads the global) sees the test connection.

Coverage (real functions, real rows)

  1. registry register/heartbeat row-state — the #73 tombstone guard. Replays the exact production upsert (registry.go:393) and heartbeat update (registry.go:604, reduced to migration-guaranteed columns) and SELECTs the row: a late register/heartbeat on a status='removed' workspace must NOT resurrect it to online, and must NOT bump last_heartbeat_at. Positive cases prove the guard does not over-block live rows.
  2. wsauth.ValidateToken A↔B binding. A token issued to workspace A must NOT authenticate workspace B; WorkspaceFromToken resolves the owning workspace only; a token whose workspace is soft-removed is rejected via the JOIN workspaces ... w.status != 'removed' filter; RevokeAllForWorkspace kills the token.
  3. registry.CanCommunicate parent_id hierarchy. Two distinct tenant trees (rootX→leadX→{engA,engB}; rootY→leadY). Asserts self/sibling/ancestor↔descendant allowed; cross-tenant leaf→leaf, leaf→other-root, root→root denied; two org roots (both parent_id NULL) are NOT treated as siblings.
  4. orgtoken revoke/validate row-state. Revoke flips live→revoked and a revoked org-admin token stops validating; re-revoke is idempotent (false); List excludes revoked and exercises the real COALESCE(org_id::text,'') cast sqlmock can't type-check; HasAnyLive flips with the last live token.

Watch-fail intent (would FAIL against a regression, PASS against current-correct)

  • Drop the WHERE status IS DISTINCT FROM 'removed' / AND status != 'removed' guard → tombstone-resurrection tests fail.
  • Drop the workspaceID != expectedWorkspaceID check (or the removed-workspace JOIN filter) → A↔B binding test fails.
  • Relax parent_id scoping → cross-tenant CanCommunicate cases fail.
  • Drop revoked_at IS NULL from Validate/Revoke → orgtoken tests fail.

CI wiring

.gitea/scripts/detect-changes.py handlers-postgres profile widened to also match internal/registry/ and internal/orgtoken/ so a regression in CanCommunicate or orgtoken.* actually triggers handlers-postgres-integration.yml (the workflow runs go test -tags=integration ./internal/handlers/ -run "^TestIntegration_", which already globs these). Without this, those two packages were outside the trigger set.

SOP Checklist

  • Comprehensive testing performed: New registry_auth_integration_test.go covers register/heartbeat tombstone guard, wsauth cross-workspace binding, CanCommunicate parent_id hierarchy, and orgtoken revoke/validate row-state. go vet -tags=integration clean; Handlers Postgres Integration job passes on this PR.
  • Local-postgres E2E run: Verified — Handlers Postgres Integration / Handlers Postgres Integration (pull_request) successful on this head.
  • Staging-smoke verified or pending: N/A — test-layer change with no runtime staging surface.
  • Root-cause not symptom: Existing sqlmock tests asserted which SQL fired, not that a real Postgres enforces the cross-tenant boundary. This suite closes that gap with real rows against a real DB.
  • Five-Axis review walked: Correctness (real DB enforces predicates), readability (documented harness mirroring existing integration suites), architecture (reuses handlers-postgres integration pattern), security (cross-tenant non-leak is the core value), performance (tests only run when handlers/registry/orgtoken/migrations change).
  • No backwards-compat shim / dead code added: Confirmed — only adds tests and widens the detect-changes trigger.
  • Memory consulted: Follows handlers-postgres integration harness pattern from delegation_ledger_integration_test.go and pending_uploads_integration_test.go.
Closes #2148 ## What Real-Postgres `TestIntegration_` regression suite for the **registry-auth + cross-tenant security boundary** (SOP rule internal#765, test_layer: real-postgres). Filed from the 2026-06-02 platform-wide coverage audit — this package was sqlmock-only, asserting *which SQL fired* rather than *that a real DB enforces the org non-leak*. New file: `workspace-server/internal/handlers/registry_auth_integration_test.go` (`//go:build integration`, `INTEGRATION_DB_URL`, skip-if-unset — same harness as `delegation_ledger_integration_test.go` / `pending_uploads_integration_test.go`). It reuses the package-global `db.DB` hot-swap so `registry.CanCommunicate` (which reads the global) sees the test connection. ### Coverage (real functions, real rows) 1. **registry register/heartbeat row-state — the #73 tombstone guard.** Replays the exact production upsert (`registry.go:393`) and heartbeat update (`registry.go:604`, reduced to migration-guaranteed columns) and SELECTs the row: a late register/heartbeat on a `status='removed'` workspace must NOT resurrect it to `online`, and must NOT bump `last_heartbeat_at`. Positive cases prove the guard does not over-block live rows. 2. **`wsauth.ValidateToken` A↔B binding.** A token issued to workspace A must NOT authenticate workspace B; `WorkspaceFromToken` resolves the owning workspace only; a token whose workspace is soft-`removed` is rejected via the `JOIN workspaces ... w.status != 'removed'` filter; `RevokeAllForWorkspace` kills the token. 3. **`registry.CanCommunicate` parent_id hierarchy.** Two distinct tenant trees (rootX→leadX→{engA,engB}; rootY→leadY). Asserts self/sibling/ancestor↔descendant allowed; cross-tenant leaf→leaf, leaf→other-root, root→root denied; two org roots (both `parent_id NULL`) are NOT treated as siblings. 4. **`orgtoken` revoke/validate row-state.** Revoke flips live→revoked and a revoked org-admin token stops validating; re-revoke is idempotent (`false`); `List` excludes revoked and exercises the real `COALESCE(org_id::text,'')` cast sqlmock can't type-check; `HasAnyLive` flips with the last live token. ### Watch-fail intent (would FAIL against a regression, PASS against current-correct) - Drop the `WHERE status IS DISTINCT FROM 'removed'` / `AND status != 'removed'` guard → tombstone-resurrection tests fail. - Drop the `workspaceID != expectedWorkspaceID` check (or the removed-workspace JOIN filter) → A↔B binding test fails. - Relax parent_id scoping → cross-tenant `CanCommunicate` cases fail. - Drop `revoked_at IS NULL` from Validate/Revoke → orgtoken tests fail. ### CI wiring `.gitea/scripts/detect-changes.py` `handlers-postgres` profile widened to also match `internal/registry/` and `internal/orgtoken/` so a regression in `CanCommunicate` or `orgtoken.*` actually triggers `handlers-postgres-integration.yml` (the workflow runs `go test -tags=integration ./internal/handlers/ -run "^TestIntegration_"`, which already globs these). Without this, those two packages were outside the trigger set. ## SOP Checklist - Comprehensive testing performed: New `registry_auth_integration_test.go` covers register/heartbeat tombstone guard, wsauth cross-workspace binding, CanCommunicate parent_id hierarchy, and orgtoken revoke/validate row-state. `go vet -tags=integration` clean; Handlers Postgres Integration job passes on this PR. - Local-postgres E2E run: Verified — Handlers Postgres Integration / Handlers Postgres Integration (pull_request) successful on this head. - Staging-smoke verified or pending: N/A — test-layer change with no runtime staging surface. - Root-cause not symptom: Existing sqlmock tests asserted which SQL fired, not that a real Postgres enforces the cross-tenant boundary. This suite closes that gap with real rows against a real DB. - Five-Axis review walked: Correctness (real DB enforces predicates), readability (documented harness mirroring existing integration suites), architecture (reuses handlers-postgres integration pattern), security (cross-tenant non-leak is the core value), performance (tests only run when handlers/registry/orgtoken/migrations change). - No backwards-compat shim / dead code added: Confirmed — only adds tests and widens the detect-changes trigger. - Memory consulted: Follows handlers-postgres integration harness pattern from `delegation_ledger_integration_test.go` and `pending_uploads_integration_test.go`.
molecule-code-reviewer marked the pull request as work in progress 2026-06-03 00:43:41 +00:00
agent-dev-a added 2 commits 2026-06-09 03:46:37 +00:00
register/heartbeat #73 tombstone-guard row-state, wsauth.ValidateToken
A↔B binding + removed-workspace JOIN filter, CanCommunicate parent_id
hierarchy cross-tenant isolation, orgtoken revoke/validate row-state.
Reuses the handlers-postgres integration harness (//go:build integration,
INTEGRATION_DB_URL, skip-if-unset).

Closes #2148

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ci(detect-changes): widen handlers-postgres profile to registry+orgtoken (#2148)
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 6s
CI / Detect changes (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
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 3s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
CI / Canvas (Next.js) (pull_request) Successful in 2s
Harness Replays / detect-changes (pull_request) Successful in 8s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 12s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
CI / Canvas Deploy Status (pull_request) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
Harness Replays / Harness Replays (pull_request) Successful in 2s
qa-review / approved (pull_request_target) Failing after 5s
security-review / approved (pull_request_target) Failing after 5s
E2E Chat / E2E Chat (pull_request) Successful in 10s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 13s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m7s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m27s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2m34s
CI / Platform (Go) (pull_request) Successful in 4m8s
CI / all-required (pull_request) Successful in 3s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Failing after 4m47s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 4m59s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Failing after 7m29s
sop-checklist / review-refire (pull_request_target) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Failing after 5s
sop-checklist / all-items-acked (pull_request_target) Successful in 7s
sop-checklist / all-items-acked (pull_request) acked: 7/7
sop-checklist / na-declarations (pull_request) N/A: (none)
24bbec0e71
The registry-auth integration suite covers CanCommunicate (internal/registry)
and org-admin token revoke/validate (internal/orgtoken); without this the
handlers-postgres workflow would not trigger on a regression in either
package, so the new tests would not gate.

Closes #2148

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
agent-dev-a force-pushed test/2148-registry-auth-real-postgres from 45c3b9ea7e to 24bbec0e71 2026-06-09 03:46:37 +00:00 Compare
Member

/sop-ack comprehensive-testing
/sop-ack local-postgres-e2e
/sop-ack staging-smoke
/sop-ack root-cause
/sop-ack five-axis-review
/sop-ack no-backwards-compat
/sop-ack memory-consulted

/sop-ack comprehensive-testing /sop-ack local-postgres-e2e /sop-ack staging-smoke /sop-ack root-cause /sop-ack five-axis-review /sop-ack no-backwards-compat /sop-ack memory-consulted
Some optional checks failed
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 6s
CI / Detect changes (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
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 3s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
CI / Canvas (Next.js) (pull_request) Successful in 2s
Harness Replays / detect-changes (pull_request) Successful in 8s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 12s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
CI / Canvas Deploy Status (pull_request) Successful in 2s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
Harness Replays / Harness Replays (pull_request) Successful in 2s
qa-review / approved (pull_request_target) Failing after 5s
security-review / approved (pull_request_target) Failing after 5s
E2E Chat / E2E Chat (pull_request) Successful in 10s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Successful in 13s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m7s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m27s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2m34s
Required
Details
CI / Platform (Go) (pull_request) Successful in 4m8s
CI / all-required (pull_request) Successful in 3s
Required
Details
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Failing after 4m47s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 4m59s
Required
Details
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Failing after 7m29s
sop-checklist / review-refire (pull_request_target) Has been skipped
gate-check-v3 / gate-check (pull_request_target) Failing after 5s
sop-checklist / all-items-acked (pull_request_target) Successful in 7s
sop-checklist / all-items-acked (pull_request) acked: 7/7
sop-checklist / na-declarations (pull_request) N/A: (none)
This pull request is marked as a work in progress.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin test/2148-registry-auth-real-postgres:test/2148-registry-auth-real-postgres
git checkout test/2148-registry-auth-real-postgres
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#2156