Three defects left the deployment frozen on an Aug-06 image while five
RBAC merges landed on main:
1. The job-level `hashFiles('Dockerfile')` condition evaluates BEFORE
checkout, against an empty workspace — always '', so the job was
silently skipped on every push to main.
2. Had it run, it pushed only sha-* and env-stage tags; orca deploys
:latest, which nothing ever updated.
3. The final step ran `orca apply --env=stage` against a stage
environment this cluster does not have.
Now: condition without hashFiles (the Dockerfile is not optional),
:latest tagged alongside sha-*, and the deploy step replaced with the
HMAC-signed orca webhook the other repos use (registered on the master;
ORCA_WEBHOOK_SECRET set as a repo Actions secret).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
internal/keycloak Adapter (HTTPAdapter + Mock). POST /v1/tenants now provisions a KC organization + IT_ADMIN invite when admin_email is set; KC failures emit keycloak.provision_failed but don't roll back. POST /v1/internal/keycloak/claims resolves the current claim bundle for any (tenant_id|tenant_slug|user_attrs.*) lookup. Mock used in tests + when KEYCLOAK_ADMIN_URL is empty. HTTPAdapter tested against an in-process stub KC (httptest.Server).
Refs: M4.3
Full M4.2 deliverable: 16 endpoints (tenants CRUD + lifecycle, catalog, entitlements, API keys with argon2 hashing, audit append + filter), Store interface with pgx-backed Postgres + in-memory parallel implementations exercised by the same eachStore harness, openapi.yaml at 3.1 with kin-openapi contract test. M4.3 adds auth.
Refs: M4.2
Minimal Go service: /healthz + /v1/tenants/by-slug/:slug + /v1/tenants/:id with an in-memory store seeded with the acme tenant. Stdlib-only; pgx + JWT validation land in M4.1 follow-up.