fix(#2433): restore data consistency guard in EnsureOrgInMint#2436
fix(#2433): restore data consistency guard in EnsureOrgInMint#2436fullsend-ai-coder[bot] wants to merge 1 commit into
Conversation
PR #2331 removed the defense-in-depth cross-check that prevented silent clobbering of ALLOWED_ORGS on stale reads because it relied on org-scoped ROLE_APP_IDS keys which no longer exist in the role-only model. No replacement was added. Restore the guard adapted for the role-only model: if ALLOWED_ORGS is empty but mintcore.RoleOnlyAppIDs() finds role-only entries in ROLE_APP_IDS, the mint has been bootstrapped and empty ALLOWED_ORGS indicates env var data loss. Return an error instead of silently writing only the new org (which would unenroll all existing orgs). First-enrollment (both empty) and legacy-only keys (no role-only entries) proceed normally. Updated TestEnsureOrgInMint_DerivesAllowedRolesWhenEmpty to set ALLOWED_ORGS to a non-empty value, since the test's purpose is verifying ALLOWED_ROLES derivation, not the empty-ALLOWED_ORGS path which is now correctly guarded. Note: pre-commit could not run in sandbox (shellcheck download blocked by network policy). Post-script runs it authoritatively. Closes #2433
E2E tests did not runE2E tests run automatically for org/repo members and collaborators on pull requests. For other contributors, a maintainer must add the See E2E testing guide for details. |
Site previewPreview: https://59e94622-site.fullsend-ai.workers.dev Commit: |
|
🤖 Finished Review · ✅ Success · Started 4:47 PM UTC · Completed 4:58 PM UTC |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
ReviewFindingsMedium
Low
|
| // data loss (e.g., stale read from a diverged revision), not a first | ||
| // enrollment. Abort to prevent silently unenrolling all existing orgs. | ||
| if allowedOrgs == "" { | ||
| var roleAppIDMap map[string]string |
There was a problem hiding this comment.
[medium] fail-open
json.Unmarshal error is silently discarded. If ROLE_APP_IDS contains malformed JSON, roleAppIDMap stays nil, RoleOnlyAppIDs returns nil, and the guard is bypassed. This is a fail-open on parse failure in a guard designed to detect data corruption.
Suggested fix: Check the error from json.Unmarshal. If ROLE_APP_IDS is non-empty but fails to parse, return an error (fail closed).
| // Defense-in-depth: if ALLOWED_ORGS is empty but ROLE_APP_IDS has | ||
| // role-only entries, the mint has been bootstrapped and should have | ||
| // enrolled orgs. Empty ALLOWED_ORGS in this state indicates env var | ||
| // data loss (e.g., stale read from a diverged revision), not a first |
There was a problem hiding this comment.
[low] error-message-consistency
Error message uses multi-line string concatenation with '+' operator, inconsistent with other fmt.Errorf calls in this file which use single-line format strings.
Suggested fix: Consolidate into a single-line format string.
PR #2331 removed the defense-in-depth cross-check that prevented silent clobbering of ALLOWED_ORGS on stale reads because it relied on org-scoped ROLE_APP_IDS keys which no longer exist in the role-only model. No replacement was added.
Restore the guard adapted for the role-only model: if ALLOWED_ORGS is empty but mintcore.RoleOnlyAppIDs() finds role-only entries in ROLE_APP_IDS, the mint has been bootstrapped and empty ALLOWED_ORGS indicates env var data loss. Return an error instead of silently writing only the new org (which would unenroll all existing orgs).
First-enrollment (both empty) and legacy-only keys (no role-only entries) proceed normally.
Updated TestEnsureOrgInMint_DerivesAllowedRolesWhenEmpty to set ALLOWED_ORGS to a non-empty value, since the test's purpose is verifying ALLOWED_ROLES derivation, not the empty-ALLOWED_ORGS path which is now correctly guarded.
Note: pre-commit could not run in sandbox (shellcheck download blocked by network policy). Post-script runs it authoritatively.
Closes #2433
Post-script verification
agent/2433-restore-data-consistency-guard)8271187d48c6a25688945cbcdec4c8a7dabf800c..HEAD)