Skip to content

Conversation

@expede
Copy link
Member

@expede expede commented Oct 13, 2025

It's possible that my brain is breaking down the problem incorrectly, but here's why I think we should change this fixture:

Here's the existing fixture (laid out differently so that it more easily fits on one line in this tiny box)

args: {
    "newsletters": {
        "recipients": [
            { "email": "bob@example.com" },
            { "email": "alice@example.com" }
        ]
    }
},
"policies": [
    // Policy #1
    [
        ["all", ".newsletters",
            ["any", ".recipients", ["==", ".email", "bob@example.com"]]]
    ]
]

Let's break this down. I think the first step is where our understandings diverge:

// ["all", ".newsletters", ...]
args: {
    "newsletters": {
        "recipients": [                      // <= Outer map
            { "email": "bob@example.com" },  // <---- inner array
            { "email": "alice@example.com" } // <---- inner array
        ]                                    // <= Outer map
    }
},

newsletters has a single element, and running all on an array would grab each element in the array. For a map, it drops the keys and returns an array of the values. In this case, that would be the inner array (each email object).

I believe this behaviour to be consistent, since you can imagine cases like this:

args: {
    "newsletters": {
        "sale": { // Newsletter #1
            "recipients": [
                { "email": "bob@example.com" },
            ]
        },
        "hiring": {  // Newsletter #2
            "recipients": [
                { "email": "bob@example.com" },
                { "email": "alice@example.com" }
            ]
        },
        "fundraising": {  // Newsletter #3
            "recipients": [
                { "email": "bob@example.com" },
                { "email": "alice@example.com" },
                { "carol": "alice@example.com" }
            ]
        },
    }
}

Here, I think this more closely fits if we translate our predicate to English: "for all newsletters, ensure that some recipient has the email equal to bob@example.com".

["all", ".newsletters", // for all .newsletters,
  ["any", ".recipients", // ensure that some recipient
    ["==", ".email", "bob@example.com"]]] // has the .email equal to bob@example.com

My guess is that anyone who's tests pass on the current fixture treat the map as the first element of an array by wrapping it. Doing so would break the "for each newsletter" logic when you have many named newsletters.

It's possible that we previously discussed this case and I've simply forgotten, but the above is my current understanding.

Copy link
Contributor

@alanshaw alanshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this seems correct to me now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants