Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .beads/issues.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,5 @@
{"id":"procella-7tc","title":"Cross-cutting: per-tenant CMK/KMS encryption (BYOK)","description":"Current encryption uses a single PROCELLA_ENCRYPTION_KEY master with HKDF per-env derivation. BYOK support (AWS KMS CMK per tenant) would allow regulated customers to manage their own root keys. Cross-cutting — affects stacks, esc, webhooks secrets, etc. Not ESC-specific.","status":"open","priority":4,"issue_type":"feature","owner":"omer@descope.com","created_at":"2026-04-23T14:59:12Z","created_by":"Omer","updated_at":"2026-04-23T14:59:12Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"id":"procella-a0a","title":"Cross-cutting: ticket-ID/justification required on privileged mutations (SOC2 audit)","description":"Enterprise audit requirement: all privileged mutations (stacks, webhooks, esc, oidc, github app) should require a ticketId + justification field, persisted to audit log for SOC2/SOX compliance. Cross-cutting refactor — touches every mutation handler. Not ESC-specific; flagged by cubic during procella-yj7 review.","status":"open","priority":4,"issue_type":"feature","owner":"omer@descope.com","created_at":"2026-04-23T14:59:11Z","created_by":"Omer","updated_at":"2026-04-23T14:59:11Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"id":"procella-rad","title":"AI Copilot — natural language infrastructure queries","description":"Natural language queries over infrastructure state.\n\n## What\n'Show me all Lambda functions using Python 3.8' — query infrastructure using natural language. Requires Insights (#13) as foundation.\n\n## Backend Requirements\n- Depends on Pulumi Insights (resource index)\n- LLM integration (OpenAI/Anthropic API)\n- Query translation: natural language → structured resource query\n- Response formatting: resource list with relevant properties\n- Chat interface in dashboard\n\n## Pulumi Cloud Tier\nEnterprise+\n\n## Complexity\nHIGH — depends on Insights + LLM integration. Lowest priority.","status":"open","priority":4,"issue_type":"feature","owner":"omer@descope.com","created_at":"2026-03-24T13:43:26Z","created_by":"Omer","updated_at":"2026-03-24T13:43:26Z","dependencies":[{"issue_id":"procella-rad","depends_on_id":"procella-alz","type":"relates-to","created_at":"2026-03-24T13:44:14Z","created_by":"Omer","metadata":"{}"},{"issue_id":"procella-rad","depends_on_id":"procella-gyi","type":"blocks","created_at":"2026-03-24T13:44:05Z","created_by":"Omer","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"memory","key":"oidc-ci-debugging-lessons-april-2026-lesson-1","value":"OIDC CI Debugging Lessons (April 2026)\n\n## Lesson 1: Diagnose Before Acting — Always Check What the CLI Sees\n\nWhen debugging Pulumi CLI failures against the Procella backend:\n1. FIRST run `pulumi whoami -v` to see what org/user the CLI sees\n2. FIRST run `pulumi org get-default` to see the default org\n3. FIRST check the /api/user response format matches what the CLI expects\n4. ONLY THEN attempt fixes\n\nThe CLI silently exits 0 when it can't resolve an org. No error message, no output.\nThis wasted 5+ commits of trial-and-error with different stack name formats.\n\n## Lesson 2: Pulumi CLI Silent Failures\n\nPulumi CLI v3.229.0 has multiple silent failure modes against service backends:\n- `stack init` exits 0 without creating/selecting if the org doesn't match\n- `stack select --create` exits 0 without creating/selecting for the same reason\n- No error message on stdout OR stderr — only detectable by checking `pulumi stack --show-name` afterward\n\nWorkaround: Create stacks via direct API calls (curl), then use `pulumi stack select` for CLI operations.\n\n## Lesson 3: The /api/user/organizations/default Endpoint\n\nThe Pulumi CLI calls GET /api/user/organizations/default to resolve the default org for stack operations.\nIf this endpoint doesn't return the correct org, the CLI silently fails on ALL stack operations.\nIn Hono, a parameterized route like /user/organizations/:orgName will catch 'default' as an orgName.\nHandle orgName==='default' explicitly inside the handler.\n\n## Lesson 4: Descope Tenant Name vs Trust Policy orgSlug\n\nThe Descope tenant name in JWT claims may differ from the orgSlug used in trust policies.\nWhen the OIDC exchange mints an access key, the JWT's tenant name comes from Descope,\nbut the trust policy's orgSlug comes from the policy creator. These can diverge.\nSolution: Store the orgSlug as an explicit custom claim (OidcClaims.orgSlug) in the minted access key,\nand prefer it in extractOrgSlug() over the Descope-derived tenant name.\n\n## Lesson 5: SST Concurrency Group Isolation\n\npreview.yml and preview-cleanup.yml MUST use different concurrency groups.\nIf they share the same group with cancel-in-progress: true, closing then reopening a PR\ncauses the deploy to cancel the running sst remove, leaving CloudFront half-destroyed.\nThe health check + drift recovery pattern (sst unlock → remove → redeploy) handles this gracefully.\n\n## Lesson 6: Don't Shotgun Debug — Ask 'What Does the Client See?'\n\nWhen a CLI tool fails silently against your API:\n1. Check what the tool's auth/identity endpoints return (not just healthz)\n2. Compare response format against the upstream source (Go types, OpenAPI spec)\n3. Add the tool's verbose/debug flags FIRST, not as a last resort\n4. Test API endpoints directly with curl before blaming the CLI\n\nThis applies to any CLI-to-API debugging, not just Pulumi."}
{"_type":"memory","key":"procella-64t-resolution","value":"PR #151 fix: lease-bound update-token middleware (apps/server/src/middleware/auth.ts) MUST look up the stack by trusted ctx.stackId (UUID PK from cryptographically-signed lease token), NOT by URL (org, project, stack) names. The URL org slug is the human-readable orgSlug in OIDC mode, while projects.tenantId is a Descope tenant UUID — they diverge. Filtering DB by tenantId=urlOrgSlug returns 0 rows in OIDC mode and breaks every Pulumi up/preview/destroy. Verify URL project+stack match the looked-up stack info, but skip URL org comparison entirely. New helper: getStackById_systemOnly(stackId)."}
{"_type":"memory","key":"oidc-ci-debugging-lessons-april-2026-lesson-1","value":"OIDC CI Debugging Lessons (April 2026)\n\n## Lesson 1: Diagnose Before Acting — Always Check What the CLI Sees\n\nWhen debugging Pulumi CLI failures against the Procella backend:\n1. FIRST run `pulumi whoami -v` to see what org/user the CLI sees\n2. FIRST run `pulumi org get-default` to see the default org\n3. FIRST check the /api/user response format matches what the CLI expects\n4. ONLY THEN attempt fixes\n\nThe CLI silently exits 0 when it can't resolve an org. No error message, no output.\nThis wasted 5+ commits of trial-and-error with different stack name formats.\n\n## Lesson 2: Pulumi CLI Silent Failures\n\nPulumi CLI v3.229.0 has multiple silent failure modes against service backends:\n- `stack init` exits 0 without creating/selecting if the org doesn't match\n- `stack select --create` exits 0 without creating/selecting for the same reason\n- No error message on stdout OR stderr — only detectable by checking `pulumi stack --show-name` afterward\n\nWorkaround: Create stacks via direct API calls (curl), then use `pulumi stack select` for CLI operations.\n\n## Lesson 3: The /api/user/organizations/default Endpoint\n\nThe Pulumi CLI calls GET /api/user/organizations/default to resolve the default org for stack operations.\nIf this endpoint doesn't return the correct org, the CLI silently fails on ALL stack operations.\nIn Hono, a parameterized route like /user/organizations/:orgName will catch 'default' as an orgName.\nHandle orgName==='default' explicitly inside the handler.\n\n## Lesson 4: Descope Tenant Name vs Trust Policy orgSlug\n\nThe Descope tenant name in JWT claims may differ from the orgSlug used in trust policies.\nWhen the OIDC exchange mints an access key, the JWT's tenant name comes from Descope,\nbut the trust policy's orgSlug comes from the policy creator. These can diverge.\nSolution: Store the orgSlug as an explicit custom claim (OidcClaims.orgSlug) in the minted access key,\nand prefer it in extractOrgSlug() over the Descope-derived tenant name.\n\n## Lesson 5: SST Concurrency Group Isolation\n\npreview.yml and preview-cleanup.yml MUST use different concurrency groups.\nIf they share the same group with cancel-in-progress: true, closing then reopening a PR\ncauses the deploy to cancel the running sst remove, leaving CloudFront half-destroyed.\nThe health check + drift recovery pattern (sst unlock → remove → redeploy) handles this gracefully.\n\n## Lesson 6: Don't Shotgun Debug — Ask 'What Does the Client See?'\n\nWhen a CLI tool fails silently against your API:\n1. Check what the tool's auth/identity endpoints return (not just healthz)\n2. Compare response format against the upstream source (Go types, OpenAPI spec)\n3. Add the tool's verbose/debug flags FIRST, not as a last resort\n4. Test API endpoints directly with curl before blaming the CLI\n\nThis applies to any CLI-to-API debugging, not just Pulumi."}
Comment thread
omercnet marked this conversation as resolved.
25 changes: 11 additions & 14 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,8 @@
"lint-staged": {
"*.{ts,tsx}": ["biome check --write --no-errors-on-unmatched"],
"*.{json,jsonl,css}": ["biome format --write --no-errors-on-unmatched"]
},
"overrides": {
"astro>vite": "^7.3.2"
}
}
Loading