{"info":{"description":"Anonymous hosted public API profile for automatic GroupMixer scenario solving. Solver configuration and solver-family selection are intentionally not exposed.","title":"GroupMixer Public Auto-Solve API","version":"v1"},"openapi":"3.1.0","paths":{"/v1/auto-solve":{"post":{"description":"Accept a scenario plus optional objectives and constraints, apply the hosted public auto-solve policy server-side, and return a solution with explicit anonymous quota metadata. This operation intentionally does not accept solver configuration, solver-family selection, warm starts, or stop-condition controls.","operationId":"autoSolve","requestBody":{"content":{"application/json":{"examples":{"minimal":{"summary":"Tiny two-person scenario","value":{"constraints":[],"objectives":[{"type":"maximize_unique_contacts","weight":1.0}],"scenario":{"groups":[{"id":"team-1","size":2}],"num_sessions":1,"people":[{"attributes":{},"id":"alice"},{"attributes":{},"id":"bob"}]},"schema_version":"v1"}}},"schema":{"$defs":{"ApiSchemaVersionContract":{"description":"Explicit schema-version discriminator for hosted public API payloads.","enum":["v1"],"type":"string"},"AttributeBalanceMode":{"description":"Mode for evaluating attribute balance targets.","oneOf":[{"const":"exact","description":"Penalize absolute deviation from the desired count (current behavior)","type":"string"},{"const":"at_least","description":"Penalize only when actual < desired; overshooting is allowed without penalty","type":"string"}]},"AttributeBalanceParams":{"description":"Parameters for the AttributeBalance constraint.\n\nThis constraint maintains desired distributions of person attributes within\nspecific groups. For example, it can ensure gender balance or department\nrepresentation within teams.\n\n# Example\n\n```no_run\nuse gm_core::models::AttributeBalanceParams;\nuse gm_core::models::AttributeBalanceMode;\nuse std::collections::HashMap;\n\n// Maintain 2 males and 2 females in \"Team1\"\nlet params = AttributeBalanceParams {\n    groups: Some(vec![\"Team1\".to_string()]),\n    attribute_key: \"gender\".to_string(),\n    desired_values: {\n        let mut values = HashMap::new();\n        values.insert(\"male\".to_string(), 2);\n        values.insert(\"female\".to_string(), 2);\n        values\n    },\n    penalty_weight: 50.0,\n    sessions: None,\n    mode: AttributeBalanceMode::Exact,\n};\n```","properties":{"attribute_key":{"description":"The attribute key to balance (e.g., \"gender\", \"department\")","type":"string"},"desired_values":{"additionalProperties":{"format":"uint32","minimum":0,"type":"integer"},"description":"Desired count for each attribute value (e.g., {\"male\": 2, \"female\": 2})","type":"object"},"groups":{"default":null,"description":"Group IDs where this balance constraint applies. If `None`, applies to all groups.","items":{"type":"string"},"type":["array","null"]},"mode":{"$ref":"#/$defs/AttributeBalanceMode","default":"exact","description":"How to interpret desired counts. `Exact` penalizes deviation in either direction,\n`AtLeast` penalizes only shortfalls (overshoot is not penalized)."},"penalty_weight":{"description":"Weight of the penalty applied for balance violations","format":"double","type":"number"},"sessions":{"default":null,"description":"Optional list of session indices in which this constraint is active. If `None`, the constraint applies to all sessions.","items":{"format":"uint32","minimum":0,"type":"integer"},"type":["array","null"]}},"required":["attribute_key","desired_values","penalty_weight"],"type":"object"},"AttributeSumParams":{"description":"Parameters for the AttributeSum constraint.\n\nThis constraint maintains a desired numeric attribute sum within specific\ngroup/session slots. Attribute values are parsed as finite `f64` values;\nmissing, empty, unparseable, or non-finite values contribute `0.0`.\nBounds are authored in original attribute units and compiled into normalized\nunits before search.","properties":{"attribute_key":{"description":"The numeric attribute key to aggregate (e.g., \"skill\", \"seniority\", \"budget\")","type":"string"},"groups":{"default":null,"description":"Group IDs where this sum constraint applies. If `None`, applies to all groups.","items":{"type":"string"},"type":["array","null"]},"lower":{"default":null,"description":"Optional lower bound for the slot sum, in original attribute units.","format":"double","type":["number","null"]},"penalty_function":{"$ref":"#/$defs/AttributeSumPenaltyFunction","default":"linear","description":"Linear or squared penalty over normalized violation units."},"penalty_weight":{"default":1000.0,"description":"Weight of one normalized violation unit.","format":"double","type":"number"},"sessions":{"default":null,"description":"Optional list of session indices in which this constraint is active. If `None`, the constraint applies to all sessions.","items":{"format":"uint32","minimum":0,"type":"integer"},"type":["array","null"]},"upper":{"default":null,"description":"Optional upper bound for the slot sum, in original attribute units.","format":"double","type":["number","null"]}},"required":["attribute_key"],"type":"object"},"AttributeSumPenaltyFunction":{"description":"Penalty curve for normalized AttributeSum violations.","oneOf":[{"const":"linear","description":"Penalize linearly: `weight * violation`.","type":"string"},{"const":"squared","description":"Penalize quadratically: `weight * violation²`.","type":"string"}]},"Constraint":{"description":"Represents a constraint that must be satisfied or penalized during optimization.\n\nConstraints define rules that the scheduler should follow. They can be either\nhard constraints (with very high penalty weights) or soft constraints (with\nlower penalty weights that represent preferences).\n\nAll constraints support optional session-specific application, meaning they\ncan be applied to all sessions or only to specific sessions.\n\n# Constraint Types\n\n- **RepeatEncounter**: Limits how often people can be paired together\n- **AttributeBalance**: Maintains desired attribute distributions within groups\n- **ImmovablePerson**: Fixes specific people to specific groups in specific sessions\n- **MustStayTogether**: Keeps certain people in the same group\n- **MustStayApart**: Requires certain people to be in different groups\n- **ShouldStayTogether**: Prefers certain people to be in the same group (soft)\n- **ShouldNotBeTogether**: Discourages certain people from being in the same group (soft)\n\n# Examples\n\n```no_run\nuse gm_core::models::*;\nuse std::collections::HashMap;\n\n// Limit repeat encounters\nlet repeat_constraint = Constraint::RepeatEncounter(RepeatEncounterParams {\n    max_allowed_encounters: 1,\n    penalty_function: \"squared\".to_string(),\n    penalty_weight: 100.0,\n});\n\n// Maintain gender balance in selected groups. `None` means all groups.\nlet balance_constraint = Constraint::AttributeBalance(AttributeBalanceParams {\n    groups: Some(vec![\"Team1\".to_string()]),\n    attribute_key: \"gender\".to_string(),\n    desired_values: {\n        let mut values = HashMap::new();\n        values.insert(\"male\".to_string(), 2);\n        values.insert(\"female\".to_string(), 2);\n        values\n    },\n    penalty_weight: 50.0,\n    sessions: None,\n    mode: AttributeBalanceMode::Exact,\n});\n\n// Keep two people together (only in sessions 0 and 1)\nlet together_constraint = Constraint::MustStayTogether {\n    people: vec![\"Alice\".to_string(), \"Bob\".to_string()],\n    sessions: Some(vec![0, 1]),\n};\n\n// Prevent two people from being together\nlet apart_constraint = Constraint::ShouldNotBeTogether {\n    people: vec![\"Charlie\".to_string(), \"Diana\".to_string()],\n    penalty_weight: 500.0,\n    sessions: None, // Applies to all sessions\n};\n```","oneOf":[{"$ref":"#/$defs/RepeatEncounterParams","description":"Limits how often people can encounter each other across sessions","properties":{"type":{"const":"RepeatEncounter","type":"string"}},"required":["type"],"type":"object"},{"$ref":"#/$defs/AttributeBalanceParams","description":"Maintains desired categorical attribute distributions within specific groups","properties":{"type":{"const":"AttributeBalance","type":"string"}},"required":["type"],"type":"object"},{"$ref":"#/$defs/AttributeSumParams","description":"Constrains the normalized sum of a numeric attribute within group/session slots","properties":{"type":{"const":"AttributeSum","type":"string"}},"required":["type"],"type":"object"},{"$ref":"#/$defs/PersonGroupVisitCountParams","description":"Constrains how often selected people visit selected group IDs across sessions","properties":{"type":{"const":"PersonGroupVisitCount","type":"string"}},"required":["type"],"type":"object"},{"$ref":"#/$defs/ImmovablePersonParams","description":"Fixes specific people to specific groups in specific sessions","properties":{"type":{"const":"ImmovablePerson","type":"string"}},"required":["type"],"type":"object"},{"description":"Keeps specified people in the same group","properties":{"people":{"description":"List of person IDs that must stay together","items":{"type":"string"},"type":"array"},"sessions":{"default":null,"description":"Optional list of session indices where this constraint applies.\nIf `None`, applies to all sessions.","items":{"format":"uint32","minimum":0,"type":"integer"},"type":["array","null"]},"type":{"const":"MustStayTogether","type":"string"}},"required":["type","people"],"type":"object"},{"description":"Requires specified people to be in different groups","properties":{"people":{"description":"List of person IDs that must stay apart pairwise","items":{"type":"string"},"type":"array"},"sessions":{"default":null,"description":"Optional list of session indices where this constraint applies.\nIf `None`, applies to all sessions.","items":{"format":"uint32","minimum":0,"type":"integer"},"type":["array","null"]},"type":{"const":"MustStayApart","type":"string"}},"required":["type","people"],"type":"object"},{"description":"Prefers specified people to be in the same group (soft constraint)","properties":{"penalty_weight":{"default":1000.0,"description":"Penalty weight when the people are not together","format":"double","type":"number"},"people":{"description":"List of person IDs that should be together","items":{"type":"string"},"type":"array"},"sessions":{"default":null,"description":"Optional list of session indices where this constraint applies.\nIf `None`, applies to all sessions.","items":{"format":"uint32","minimum":0,"type":"integer"},"type":["array","null"]},"type":{"const":"ShouldStayTogether","type":"string"}},"required":["type","people"],"type":"object"},{"description":"Discourages specified people from being in the same group (soft constraint)","properties":{"penalty_weight":{"default":1000.0,"description":"Penalty weight for violations (higher = more important)","format":"double","type":"number"},"people":{"description":"List of person IDs that should not be together","items":{"type":"string"},"type":"array"},"sessions":{"default":null,"description":"Optional list of session indices where this constraint applies.\nIf `None`, applies to all sessions.","items":{"format":"uint32","minimum":0,"type":"integer"},"type":["array","null"]},"type":{"const":"ShouldNotBeTogether","type":"string"}},"required":["type","people"],"type":"object"},{"$ref":"#/$defs/ImmovablePeopleParams","description":"Fixes a *set* of people to a specific group in specific sessions (hard constraint)","properties":{"type":{"const":"ImmovablePeople","type":"string"}},"required":["type"],"type":"object"},{"$ref":"#/$defs/PairMeetingCountParams","description":"Constrains a pair's meeting count across a fixed subset of sessions","properties":{"type":{"const":"PairMeetingCount","type":"string"}},"required":["type"],"type":"object"}]},"Group":{"description":"Represents a group that people can be assigned to.\n\nEach group has a unique identifier and a capacity that limits how many\npeople can be assigned to it in any single session.\n\n`size` remains the backwards-compatible default capacity for every session.\nWhen `session_sizes` is provided, it overrides that default on a\nper-session basis while keeping the same logical group ID across sessions.\n\n# Example\n\n```no_run\nuse gm_core::models::Group;\n\nlet team = Group {\n    id: \"Development Team\".to_string(),\n    size: 6, // Can hold up to 6 people\n    session_sizes: None,\n};\n```","properties":{"id":{"description":"Unique identifier for this group (must be unique across all groups)","type":"string"},"session_sizes":{"description":"Optional per-session capacities for this group.\n\nWhen present, this vector must have exactly `problem.num_sessions`\nentries. A value of `0` can be used to model a group that is closed in a\nspecific session while preserving stable group IDs across the whole\nproblem.","items":{"format":"uint32","minimum":0,"type":"integer"},"type":["array","null"]},"size":{"description":"Maximum number of people that can be assigned to this group in any session\nwhen `session_sizes` is not supplied.","format":"uint32","minimum":0,"type":"integer"}},"required":["id","size"],"type":"object"},"ImmovablePeopleParams":{"description":"Fixes multiple people to a specific group in specific sessions (hard constraint).\n\nThis is the multi-person analogue of `ImmovablePersonParams` and is now the\npreferred format. The solver treats these as hard constraints; therefore no\npenalty weight is necessary.","properties":{"group_id":{"description":"ID of the group where these people must be placed","type":"string"},"people":{"description":"IDs of the people who must be fixed in place","items":{"type":"string"},"type":"array"},"sessions":{"default":null,"description":"List of session indices where these people must be in the specified group.\nIf `None`, applies to all sessions.","items":{"format":"uint32","minimum":0,"type":"integer"},"type":["array","null"]}},"required":["people","group_id"],"type":"object"},"ImmovablePersonParams":{"description":"Parameters for the ImmovablePerson constraint.\n\nThis constraint fixes specific people to specific groups in specific sessions,\nensuring they cannot be moved during optimization. Useful for people with\nspecial roles or requirements.\n\n# Example\n\n```no_run\nuse gm_core::models::ImmovablePersonParams;\n\n// Fix \"TeamLeader\" to \"Team1\" for specific sessions\nlet params = ImmovablePersonParams {\n    person_id: \"TeamLeader\".to_string(),\n    group_id: \"Team1\".to_string(),\n    sessions: Some(vec![0, 1, 2]), // Sessions 0, 1, and 2\n};\n```","properties":{"group_id":{"description":"ID of the group where this person must be placed","type":"string"},"person_id":{"description":"ID of the person who must be fixed in place","type":"string"},"sessions":{"default":null,"description":"List of session indices where this person must be in the specified group.\nIf `None`, applies to all sessions.","items":{"format":"uint32","minimum":0,"type":"integer"},"type":["array","null"]}},"required":["person_id","group_id"],"type":"object"},"Objective":{"description":"Defines an optimization objective with its weight.\n\nObjectives specify what the solver should optimize for. Multiple objectives\ncan be specified with different weights to create a multi-objective optimization.\n\n# Supported Objective Types\n\n- `\"maximize_unique_contacts\"`: Maximize the number of unique person-to-person interactions\n\n# Example\n\n```no_run\nuse gm_core::models::Objective;\n\nlet objective = Objective {\n    r#type: \"maximize_unique_contacts\".to_string(),\n    weight: 1.0,\n};\n```","properties":{"type":{"description":"The type of objective to optimize for","type":"string"},"weight":{"description":"Weight of this objective in the overall optimization function","format":"double","type":"number"}},"required":["type","weight"],"type":"object"},"PairMeetingCountParams":{"description":"Soft constraint on how often a pair should meet within a subset of sessions.","properties":{"mode":{"$ref":"#/$defs/PairMeetingMode","default":"at_least","description":"Penalty mode: at_least (default), exact, or at_most"},"penalty_weight":{"default":1000.0,"description":"Linear penalty weight","format":"double","type":"number"},"people":{"description":"Exactly two person IDs involved in the constraint","items":{"type":"string"},"type":"array"},"sessions":{"description":"Sessions to consider for counting meetings (must be within problem.sessions)","items":{"format":"uint32","minimum":0,"type":"integer"},"type":"array"},"target_meetings":{"description":"Target number of meetings within the provided sessions (0..=sessions.len())","format":"uint32","minimum":0,"type":"integer"}},"required":["people","sessions","target_meetings"],"type":"object"},"PairMeetingMode":{"description":"Modes for how to penalize deviations from the target meeting count.","oneOf":[{"const":"at_least","description":"Penalize only shortfalls: weight * max(0, target - actual)","type":"string"},{"const":"exact","description":"Penalize absolute deviation: weight * |target - actual|","type":"string"},{"const":"at_most","description":"Penalize only excess: weight * max(0, actual - target)","type":"string"}]},"Person":{"description":"Represents a person who can be scheduled into groups.\n\nEach person has a unique identifier, optional attributes for constraint\nhandling (e.g., gender, department), and can optionally specify which\nsessions they will participate in.\n\n# Example\n\n```no_run\nuse gm_core::models::Person;\nuse std::collections::HashMap;\n\n// Person participating in all sessions\nlet alice = Person {\n    id: \"Alice\".to_string(),\n    attributes: {\n        let mut attrs = HashMap::new();\n        attrs.insert(\"gender\".to_string(), \"female\".to_string());\n        attrs.insert(\"department\".to_string(), \"engineering\".to_string());\n        attrs\n    },\n    sessions: None, // Participates in all sessions\n};\n\n// Person with limited participation (late arrival/early departure)\nlet bob = Person {\n    id: \"Bob\".to_string(),\n    attributes: HashMap::new(),\n    sessions: Some(vec![1, 2]), // Only participates in sessions 1 and 2\n};\n```","properties":{"attributes":{"additionalProperties":{"type":"string"},"description":"Key-value attributes used for constraint evaluation (e.g., \"gender\" -> \"female\")","type":"object"},"id":{"description":"Unique identifier for this person (must be unique across all people)","type":"string"},"sessions":{"default":null,"description":"Optional list of session indices this person participates in.\nIf `None`, the person participates in all sessions.\nSession indices are 0-based (first session is 0).","items":{"format":"uint32","minimum":0,"type":"integer"},"type":["array","null"]}},"required":["id","attributes"],"type":"object"},"PersonGroupVisitCountParams":{"description":"Parameters for the PersonGroupVisitCount constraint.\n\nThis soft constraint counts, for each selected `(person, group)` pair, how\nmany selected sessions assign that person to that group ID. It is intended\nfor stable group-label use cases such as task rotation and exposure caps.","properties":{"groups":{"default":null,"description":"Group IDs to count as targets. If `None`, applies to all groups.","items":{"type":"string"},"type":["array","null"]},"lower":{"default":null,"description":"Optional inclusive lower bound for each selected `(person, group)` count.","format":"uint32","minimum":0,"type":["integer","null"]},"penalty_function":{"$ref":"#/$defs/PersonGroupVisitCountPenaltyFunction","default":"linear","description":"Linear or squared penalty over visit-count violation units."},"penalty_weight":{"default":1000.0,"description":"Weight of one violation unit.","format":"double","type":"number"},"people":{"default":null,"description":"Person IDs to evaluate. If `None`, applies to all people.","items":{"type":"string"},"type":["array","null"]},"sessions":{"default":null,"description":"Session indices to count. If `None`, applies to all sessions.","items":{"format":"uint32","minimum":0,"type":"integer"},"type":["array","null"]},"upper":{"default":null,"description":"Optional inclusive upper bound for each selected `(person, group)` count.","format":"uint32","minimum":0,"type":["integer","null"]}},"type":"object"},"PersonGroupVisitCountPenaltyFunction":{"description":"Penalty curve for PersonGroupVisitCount violations.","oneOf":[{"const":"linear","description":"Penalize linearly: `weight * violation`.","type":"string"},{"const":"squared","description":"Penalize quadratically: `weight * violation²`.","type":"string"}]},"RepeatEncounterParams":{"description":"Parameters for the RepeatEncounter constraint.\n\nThis constraint limits how often people can be paired together across sessions,\npromoting social diversity by ensuring people meet new individuals rather than\nalways being grouped with the same people.\n\n# Example\n\n```no_run\nuse gm_core::models::RepeatEncounterParams;\n\n// Allow at most 1 encounter, with squared penalty for violations\nlet params = RepeatEncounterParams {\n    max_allowed_encounters: 1,\n    penalty_function: \"squared\".to_string(),\n    penalty_weight: 100.0,\n};\n```","properties":{"max_allowed_encounters":{"description":"Maximum number of times two people can be in the same group","format":"uint32","minimum":0,"type":"integer"},"penalty_function":{"description":"Penalty function type: \"squared\" for quadratic penalties, \"linear\" for linear penalties","type":"string"},"penalty_weight":{"description":"Weight of the penalty applied for constraint violations","format":"double","type":"number"}},"required":["max_allowed_encounters","penalty_function","penalty_weight"],"type":"object"},"ScenarioDefinitionContract":{"description":"Public scenario-definition shape shared across solver-facing contract surfaces.","properties":{"groups":{"description":"List of all available groups with their capacity limits.","items":{"$ref":"#/$defs/Group"},"type":"array"},"num_sessions":{"description":"Total number of scheduling sessions.","format":"uint32","minimum":0,"type":"integer"},"people":{"description":"List of all people to be scheduled into groups.","items":{"$ref":"#/$defs/Person"},"type":"array"}},"required":["people","groups","num_sessions"],"type":"object"}},"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"description":"Narrow anonymous hosted API request for automatic solving.\n\nThis request intentionally omits solver-family selection, solver settings,\nwarm starts, and stop conditions. Hosted public policy chooses the `auto`\nconfiguration server-side.","properties":{"constraints":{"default":[],"description":"Constraints that must be satisfied or penalized (defaults to empty list).","items":{"$ref":"#/$defs/Constraint"},"type":"array"},"objectives":{"default":[],"description":"Optimization objectives. If omitted or empty, the public endpoint applies\nthe documented default objective and echoes that in response metadata.","items":{"$ref":"#/$defs/Objective"},"type":"array"},"scenario":{"$ref":"#/$defs/ScenarioDefinitionContract","description":"The scenario definition: people, groups, and sessions."},"schema_version":{"$ref":"#/$defs/ApiSchemaVersionContract","description":"Public hosted API schema version. Only `v1` is currently supported."}},"required":["schema_version","scenario"],"title":"AutoSolveRequest","type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"examples":{"success":{"summary":"Solved response with anonymous quota metadata","value":{"limits":{"daily_solve_time_ms_remaining":59958,"per_request_solve_time_ms":2000,"quota_scope":"anonymous_ip_and_global","solve_time_ms_charged":42},"policy":{"applied_default_objective":false,"applied_objectives":[{"type":"maximize_unique_contacts","weight":1.0}],"id":"free_auto_v1","solver_family":"auto"},"solution":{"attribute_balance_penalty":0.0,"constraint_penalty":0,"effective_seed":null,"final_score":1.0,"no_improvement_count":0,"repetition_penalty":0,"schedule":{"session_0":{"team-1":["alice","bob"]}},"stop_reason":"optimal_score_reached","unique_contacts":1,"weighted_constraint_penalty":0.0,"weighted_repetition_penalty":0.0},"status":"solved"}}},"schema":{"$defs":{"AutoSolveLimitsMetadata":{"description":"Limit and quota metadata echoed by hosted public automatic solves.","properties":{"daily_solve_time_ms_remaining":{"format":"uint64","minimum":0,"type":"integer"},"per_request_solve_time_ms":{"format":"uint64","minimum":0,"type":"integer"},"quota_scope":{"type":"string"},"solve_time_ms_charged":{"format":"uint64","minimum":0,"type":"integer"}},"required":["quota_scope","solve_time_ms_charged","daily_solve_time_ms_remaining","per_request_solve_time_ms"],"type":"object"},"AutoSolvePolicyMetadata":{"description":"Policy metadata echoed by hosted public automatic solves.","properties":{"applied_default_objective":{"type":"boolean"},"applied_objectives":{"default":[],"items":{"$ref":"#/$defs/Objective"},"type":"array"},"id":{"type":"string"},"solver_family":{"$ref":"#/$defs/SolverKind"}},"required":["id","solver_family","applied_default_objective"],"type":"object"},"AutoSolveSolution":{"description":"Public hosted automatic-solve solution payload.\n\nThis intentionally omits internal solver diagnostics and advanced solver\nconfiguration echoes. Hosted API callers get the schedule and stable scoring\nfields only.","properties":{"attribute_balance_penalty":{"description":"Penalty points for attribute balance and AttributeSum violations.","format":"double","type":"number"},"constraint_penalty":{"description":"Total penalty points for constraint violations.","format":"int32","type":"integer"},"effective_seed":{"default":null,"description":"Effective seed used for this run, when available.","format":"uint64","minimum":0,"type":["integer","null"]},"final_score":{"description":"Overall optimization score (higher is better).","format":"double","type":"number"},"no_improvement_count":{"description":"Number of iterations without improvement at the end of the run.","format":"uint64","minimum":0,"type":"integer"},"repetition_penalty":{"description":"Penalty points for exceeding repeat encounter limits.","format":"int32","type":"integer"},"schedule":{"additionalProperties":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object"},"description":"The optimized schedule: `schedule[session][group] = [people]`.","type":"object"},"stop_reason":{"anyOf":[{"$ref":"#/$defs/StopReason"},{"type":"null"}],"default":null,"description":"Explicit stop reason for this run, when available."},"unique_contacts":{"description":"Number of unique person-to-person contacts achieved.","format":"int32","type":"integer"},"weighted_constraint_penalty":{"description":"Weighted constraint penalty used in cost calculation.","format":"double","type":"number"},"weighted_repetition_penalty":{"description":"Weighted repetition penalty used in cost calculation.","format":"double","type":"number"}},"required":["final_score","schedule","unique_contacts","repetition_penalty","attribute_balance_penalty","constraint_penalty","no_improvement_count","weighted_repetition_penalty","weighted_constraint_penalty"],"type":"object"},"AutoSolveStatus":{"description":"Public status for a hosted automatic solve.","enum":["solved","time_limited"],"type":"string"},"Objective":{"description":"Defines an optimization objective with its weight.\n\nObjectives specify what the solver should optimize for. Multiple objectives\ncan be specified with different weights to create a multi-objective optimization.\n\n# Supported Objective Types\n\n- `\"maximize_unique_contacts\"`: Maximize the number of unique person-to-person interactions\n\n# Example\n\n```no_run\nuse gm_core::models::Objective;\n\nlet objective = Objective {\n    r#type: \"maximize_unique_contacts\".to_string(),\n    weight: 1.0,\n};\n```","properties":{"type":{"description":"The type of objective to optimize for","type":"string"},"weight":{"description":"Weight of this objective in the overall optimization function","format":"double","type":"number"}},"required":["type","weight"],"type":"object"},"SolverKind":{"description":"Typed solver-family identifier used internally by `gm-core`.\n\nThe repo is preparing for multiple solver families, but the wider public contract still uses\nthe legacy string field on `SolverConfiguration`. This enum is the explicit internal source of\ntruth used by the engine registry/factory layer.","oneOf":[{"const":"auto","description":"Automatic product default: solver3 with complexity-derived budgets, oracle-guided\nconstruction attempt, explicit baseline fallback, and runtime-scaled search stopping.","type":"string"},{"const":"solver1","description":"The current production solver family backed by the `solver1` simulated annealing engine.","type":"string"},{"const":"solver3","description":"Bootstrap scaffold for the `solver3` performance-oriented dense-state solver family.\nSolve paths are not yet implemented; registration is truthful metadata only.","type":"string"},{"const":"solver4","description":"Dedicated pure-SGP solver family implementing the Triska/Musliu paper: Section 5 complete\nbacktracking with patterns, plus Sections 6 and 7 randomized greedy initialization and\nconflict-position local search.","type":"string"},{"const":"solver5","description":"Construction-first pure-SGP solver family that routes instances through explicit\ndesign-theoretic construction families.","type":"string"},{"const":"solver6","description":"Hybrid pure-SGP repeat-minimization family seeded by solver5 exact designs.","type":"string"}]},"StopReason":{"description":"Explicit reason why a solver run stopped.","enum":["max_iterations_reached","time_limit_reached","no_improvement_limit_reached","no_improvement_time_limit_reached","progress_callback_requested_stop","optimal_score_reached"],"type":"string"}},"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Narrow anonymous hosted API response for automatic solving.","properties":{"limits":{"$ref":"#/$defs/AutoSolveLimitsMetadata"},"policy":{"$ref":"#/$defs/AutoSolvePolicyMetadata"},"solution":{"$ref":"#/$defs/AutoSolveSolution"},"status":{"$ref":"#/$defs/AutoSolveStatus"}},"required":["status","solution","policy","limits"],"title":"AutoSolveResponse","type":"object"}}},"description":"Auto solve completed or returned the best time-limited result."},"413":{"content":{"application/json":{"examples":{"example":{"summary":"request-too-large","value":{"error":{"code":"request-too-large","message":"The request payload exceeds the public API size limit.","recovery":null,"related_help":["/v1/help/auto-solve"],"retry_after_seconds":null,"valid_alternatives":[],"where_path":null,"why":null}}}},"schema":{"$defs":{"PublicError":{"description":"Canonical public error instance shape shared across CLI, HTTP, and WASM projections.","properties":{"code":{"type":"string"},"message":{"type":"string"},"recovery":{"default":null,"type":["string","null"]},"related_help":{"default":[],"items":{"type":"string"},"type":"array"},"retry_after_seconds":{"default":null,"format":"uint64","minimum":0,"type":["integer","null"]},"valid_alternatives":{"default":[],"items":{"type":"string"},"type":"array"},"where_path":{"default":null,"type":["string","null"]},"why":{"default":null,"type":["string","null"]}},"required":["code","message"],"type":"object"}},"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Envelope for public transport-level error responses.","properties":{"error":{"$ref":"#/$defs/PublicError"}},"required":["error"],"title":"PublicErrorEnvelope","type":"object"}}},"description":"Request payload exceeds the public API size limit."},"422":{"content":{"application/json":{"examples":{"example":{"summary":"unsupported-public-field","value":{"error":{"code":"unsupported-public-field","message":"The request includes a field that is intentionally unsupported by the hosted public API.","recovery":null,"related_help":["/v1/help/auto-solve"],"retry_after_seconds":null,"valid_alternatives":[],"where_path":null,"why":null}}}},"schema":{"$defs":{"PublicError":{"description":"Canonical public error instance shape shared across CLI, HTTP, and WASM projections.","properties":{"code":{"type":"string"},"message":{"type":"string"},"recovery":{"default":null,"type":["string","null"]},"related_help":{"default":[],"items":{"type":"string"},"type":"array"},"retry_after_seconds":{"default":null,"format":"uint64","minimum":0,"type":["integer","null"]},"valid_alternatives":{"default":[],"items":{"type":"string"},"type":"array"},"where_path":{"default":null,"type":["string","null"]},"why":{"default":null,"type":["string","null"]}},"required":["code","message"],"type":"object"}},"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Envelope for public transport-level error responses.","properties":{"error":{"$ref":"#/$defs/PublicError"}},"required":["error"],"title":"PublicErrorEnvelope","type":"object"}}},"description":"Request is invalid or includes unsupported public fields."},"429":{"content":{"application/json":{"examples":{"example":{"summary":"quota-exceeded","value":{"error":{"code":"quota-exceeded","message":"The anonymous per-client or global free quota is exhausted.","recovery":null,"related_help":["/v1/help/auto-solve"],"retry_after_seconds":3600,"valid_alternatives":[],"where_path":null,"why":null}}}},"schema":{"$defs":{"PublicError":{"description":"Canonical public error instance shape shared across CLI, HTTP, and WASM projections.","properties":{"code":{"type":"string"},"message":{"type":"string"},"recovery":{"default":null,"type":["string","null"]},"related_help":{"default":[],"items":{"type":"string"},"type":"array"},"retry_after_seconds":{"default":null,"format":"uint64","minimum":0,"type":["integer","null"]},"valid_alternatives":{"default":[],"items":{"type":"string"},"type":"array"},"where_path":{"default":null,"type":["string","null"]},"why":{"default":null,"type":["string","null"]}},"required":["code","message"],"type":"object"}},"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Envelope for public transport-level error responses.","properties":{"error":{"$ref":"#/$defs/PublicError"}},"required":["error"],"title":"PublicErrorEnvelope","type":"object"}}},"description":"Anonymous per-client or global request, solve-time, or concurrency quota is exhausted."}},"summary":"Run the hosted public automatic solver for a scenario."}}},"servers":[{"url":"https://api.groupmixer.app"}]}