Skip to content

ae_members

src.models.committees.ae_members

AE committee member schema.

Generated by generate_committee_stats.pyae_members.json. Variants: systems_ae_members.json, security_ae_members.json.

AEMembership

Bases: BaseModel

A single AE committee membership record.

Source code in src/models/committees/ae_members.py
12
13
14
15
16
17
18
19
class AEMembership(BaseModel):
    """A single AE committee membership record."""

    conference: str = Field(description="Conference abbreviation, e.g. 'OSDI', 'USENIXSEC', 'NDSS'.", examples=["OSDI"])
    year: int = Field(description="Calendar year of service, e.g. 2023.", examples=[2023])
    role: str = Field(description="Role on the committee. One of 'chair' or 'member'.", examples=["member"])

    model_config = {"extra": "forbid"}

AEMember

Bases: BaseModel

An Artifact Evaluation committee member with service history and institutional affiliation.

Source code in src/models/committees/ae_members.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
class AEMember(BaseModel):
    """An Artifact Evaluation committee member with service history and institutional affiliation."""

    name: str = Field(
        description="Full name, e.g. 'Mathias Payer'. May include DBLP disambiguation suffix.",
        examples=["Mathias Payer"],
    )
    display_name: str = Field(
        description="Human-readable name without disambiguation suffix, e.g. 'Mathias Payer'.",
        examples=["Mathias Payer"],
    )
    affiliation: str = Field(
        description="Current institutional affiliation, e.g. 'EPFL', 'MIT'.", examples=["ETH Zurich"]
    )
    country: str | None = Field(
        default=None,
        description="Country of the institution, e.g. 'Switzerland', 'United States'. Null if unresolved.",
        examples=["Switzerland"],
    )
    continent: str | None = Field(
        default=None,
        description="Continent of the institution, e.g. 'Europe', 'North America'. Null if unresolved.",
        examples=["Europe"],
    )
    total_memberships: int = Field(
        ge=0,
        description="Total number of AE committee memberships across all conferences and years.",
        examples=[4],
    )
    chair_count: int = Field(
        ge=0, description="Number of conference-years served as AE chair (versus regular member).", examples=[1]
    )
    conferences: list[AEMembership] = Field(
        description="List of AE committee memberships, one entry per conference-year served. Each has conference, year, role.",
        examples=[["OSDI", "ATC", "USENIXSEC"]],
    )
    years: dict[str, int] = Field(
        description="Year (as string key, e.g. '2023') → number of AE memberships that year. Example: {'2023': 5, '2024': 3}.",
        examples=[[2021, 2022, 2023]],
    )
    area: str = Field(
        description="Research area based on conferences served: 'systems', 'security', or 'both' if spanning both.",
        examples=["systems"],
    )
    first_year: int | None = Field(
        default=None, description="Earliest year of AE service, e.g. 2020. Null if unknown.", examples=[2019]
    )
    last_year: int | None = Field(
        default=None,
        description="Most recent year of AE service, e.g. 2026. Null if unknown.",
        examples=[2025],
    )

    @field_validator("conferences", mode="before")
    @classmethod
    def _coerce_conferences(cls, v: object) -> object:
        """Accept both [conf, year, role] lists and {conference, year, role} dicts."""
        if isinstance(v, list):
            return [
                {"conference": item[0], "year": item[1], "role": item[2]} if isinstance(item, (list, tuple)) else item
                for item in v
            ]
        return v

    model_config = {"extra": "forbid"}