PolityKit is an open-source simulation framework for exploring how governance, allocation, and institutional systems behave under stress, scarcity, and changing assumptions.
PolityKit does not attempt to prove which political, economic, or social system is best. It is an assumption laboratory:
Given these assumptions, how does this system behave when conditions change?
The current implementation is a small deterministic simulation stack for comparing starter allocation models against shared scenarios, shocks, and metrics.
PolityKit includes:
- A .NET 10 solution with separate projects for core domain types, engine logic, allocation models, metrics, scenarios, CLI, and API.
- A deterministic simulation engine with seeded world generation, scheduled shocks, world-rule application, metric recording, and per-model run results.
- Core world/domain types for citizens, resources, institutions, environment, scenarios, shocks, system decisions, events, metrics, and seeded random sources.
- Three starter allocation models:
NeedBasedAllocationMarketBasedAllocationHierarchyBasedAllocation
- Five starter metrics:
Needs MetInequalityTrustSevere FailuresAdministrative Load
- Built-in and JSON-loaded scenarios, including the built-in
Village Food Crisis. - Example scenario files under
examples/. - A golden interpreted run bundle under
examples/golden-interpreted-run. - A CLI runner that writes run bundles to disk.
- An ASP.NET Core API for listing models, metrics, scenarios, creating/querying persisted simulation runs, and retrieving dashboard-ready run data.
- Optional fake-provider AI-assisted exploration commands and API endpoints for run summaries, scenario suggestions, model critique, and stress anomaly review.
- Documented AI boundaries that keep AI analysis optional, advisory, and separate from authoritative simulation data.
- Automated unit and integration tests for the simulation libraries and API.
Still early / not built yet:
- Frontend dashboards or visualization tools.
- Production AI provider integrations beyond the local fake provider.
- Real-world calibration or policy-grade validation. The models remain intentionally simplified.
PolityKit/
PolityKit.slnx
README.md
LICENSE
docs/
politykit/
add-metric.md
add-model.md
add-scenario.md
contributing.md
governance-presets.md
scenarios.md
scenario.schema.json
implementation/
politykit-roadmap.md
v0.6-implementation-plan.md
v0.7-implementation-plan.md
v0.8-implementation-plan.md
charterfall/
implementation/
examples/
README.md
corruption-stress.json
golden-interpreted-run/
housing-displacement.json
interpretability-demo.json
medicine-shortage.json
village-food-crisis.json
src/
PolityKit.Sim.Api/
PolityKit.Sim.Cli/
PolityKit.Sim.Core/
PolityKit.Sim.Engine/
PolityKit.Sim.Metrics/
PolityKit.Sim.Models/
PolityKit.Sim.Scenarios/
tests/
PolityKit.Sim.Api.Tests/
PolityKit.Sim.Tests/
PolityKit.Sim.Core: shared domain types and contracts, including world state, citizens, resources, decisions, events, metrics, scenarios, and random sources.PolityKit.Sim.Engine: deterministic simulation orchestration, world creation, tick execution, shock handling, world-rule application, and run results.PolityKit.Sim.Models: starter allocation model implementations and model catalog.PolityKit.Sim.Metrics: metric calculators and metric catalog.PolityKit.Sim.Scenarios: built-in scenarios, scenario validation, JSON loading, name resolution, and cloning helpers.PolityKit.Sim.Cli: command-line runner for local simulations and run-output files.PolityKit.Sim.Api: ASP.NET Core HTTP API for simulation metadata, file-backed run storage, and dashboard-ready run inspection.PolityKit.Sim.Tests: unit tests for core, engine, metrics, models, scenarios, and example files.PolityKit.Sim.Api.Tests: API integration tests plus run service, mapper, store, and test-host tests.
Prerequisite:
- .NET 10 SDK.
Build the solution:
dotnet build PolityKit.slnxRun the tests:
dotnet test PolityKit.slnxRun the API:
dotnet run --project src/PolityKit.Sim.ApiThe API launch profile uses:
http://localhost:5020
https://localhost:7058
Run the CLI help:
dotnet run --project src/PolityKit.Sim.Cli -- --helpList available models:
dotnet run --project src/PolityKit.Sim.Cli -- list-modelsRun the default built-in scenario:
dotnet run --project src/PolityKit.Sim.Cli -- runRun an example scenario with selected models:
dotnet run --project src/PolityKit.Sim.Cli -- run \
--scenario examples/village-food-crisis.json \
--models need-based-allocation,market-based-allocation,hierarchy-based-allocation \
--seed 12345 \
--ticks 120 \
--out runs/village-food-crisis-12345On Windows PowerShell:
dotnet run --project src/PolityKit.Sim.Cli -- run `
--scenario examples/village-food-crisis.json `
--models need-based-allocation,market-based-allocation,hierarchy-based-allocation `
--seed 12345 `
--ticks 120 `
--out runs/village-food-crisis-12345CLI run output:
runs/village-food-crisis-12345/
config.json
ai-analysis.json
metrics.csv
events.jsonl
citizens-final.csv
summary.json
You can use PolityKit either from the CLI for local run bundles or from the API for programmatic experiments.
List the available allocation models:
dotnet run --project src/PolityKit.Sim.Cli -- list-modelsRun the built-in Village Food Crisis scenario with all models:
dotnet run --project src/PolityKit.Sim.Cli -- runRun a specific example scenario:
dotnet run --project src/PolityKit.Sim.Cli -- run --scenario examples/medicine-shortage.jsonCompare two models with a fixed seed and shorter duration:
dotnet run --project src/PolityKit.Sim.Cli -- run \
--scenario examples/village-food-crisis.json \
--models need-based-allocation,market-based-allocation \
--seed 20260614 \
--ticks 60 \
--out runs/food-crisis-compareCompare a governance preset against the three mechanical baseline models:
dotnet run --project src/PolityKit.Sim.Cli -- run \
--scenario examples/village-food-crisis.json \
--models need-based-allocation,market-based-allocation,hierarchy-based-allocation,participatory-commons \
--seed 20260614 \
--ticks 60 \
--out runs/food-crisis-baseline-preset-comparePowerShell version:
dotnet run --project src/PolityKit.Sim.Cli -- run `
--scenario examples/village-food-crisis.json `
--models need-based-allocation,market-based-allocation `
--seed 20260614 `
--ticks 60 `
--out runs/food-crisis-compareChange model assumptions with --param:
dotnet run --project src/PolityKit.Sim.Cli -- run \
--scenario examples/corruption-stress.json \
--models need-based-allocation \
--param needPriorityWeight=1.25 \
--param vulnerabilityPriorityWeight=0.75 \
--out runs/corruption-need-weightedRun a local parameter sweep and write report files:
dotnet run --project src/PolityKit.Sim.Cli -- sweep \
--scenario examples/village-food-crisis.json \
--models need-based-allocation \
--seed 12345 \
--ticks 60 \
--sweep needPriorityWeight=0.75,1.0,1.25 \
--sweep vulnerabilityPriorityWeight=0.25,0.5 \
--out runs/food-crisis-need-sweepPowerShell version:
dotnet run --project src/PolityKit.Sim.Cli -- sweep `
--scenario examples/village-food-crisis.json `
--models need-based-allocation `
--seed 12345 `
--ticks 60 `
--sweep needPriorityWeight=0.75,1.0,1.25 `
--sweep vulnerabilityPriorityWeight=0.25,0.5 `
--out runs/food-crisis-need-sweepAfter a run, inspect:
summary.jsonfor final per-model metrics, event counts, and notable metric changes with breadcrumb text and nearby events.ai-analysis.jsonfor whether advisory AI analysis was used. Default simulation runs recordused: false.ai-summary.jsonafter running the optionalai-summarycommand for an advisory generated interpretation of the run.ai-scenario-suggestions.jsonafter running the optionalai-suggest-scenariocommand for a validated scenario suggestion draft.ai-model-critique.jsonafter running the optionalai-critique-modelcommand for advisory model critique fields.ai-anomalies.jsonafter running the optionalai-anomaliescommand against a stress summary.metrics.csvfor metric values by tick.events.jsonlfor the event stream, including model, resource, count, backlog, severity, and trust-delta context where available.citizens-final.csvfor final citizen state.config.jsonfor the scenario, seed, models, metrics, and parameters used.
Generate an advisory AI summary artifact from a completed local run bundle using the built-in fake provider:
dotnet run --project src/PolityKit.Sim.Cli -- ai-summary \
--run runs/village-food-crisis-12345 \
--provider fakeThe fake provider is local and deterministic. It creates ai-summary.json with provenance and boundary metadata, but the generated text is advisory interpretation, not simulation data.
The earlier summary, suggest-scenario, and critique-model command names, plus --bundle, remain available as compatibility aliases; new local workflows should prefer the ai-* --run form.
Generate a validated scenario suggestion draft from the same completed bundle:
dotnet run --project src/PolityKit.Sim.Cli -- ai-suggest-scenario \
--run runs/village-food-crisis-12345 \
--provider fakeThis writes ai-scenario-suggestions.json only when the provider returned a draft and the existing scenario validator accepts it. The draft remains a proposed artifact for review, not an automatically accepted scenario file.
Generate an advisory model critique from the same completed bundle:
dotnet run --project src/PolityKit.Sim.Cli -- ai-critique-model \
--run runs/village-food-crisis-12345 \
--model regulated-market \
--provider fakeThis writes ai-model-critique.json with model manifest assumptions, governance dimensions, run metrics, failure diagnostics, and provenance. Critiques are prompts for human review; they are not proof that a model is correct or incorrect, and they do not rewrite model code.
After a sweep, inspect:
sweep-summary.jsonfor every parameter combination, final metrics, best/worst runs by metric, and a ranked sensitivity report.sweep-metrics.csvfor a flat table of final metrics by sweep run.run-001/,run-002/, and so on for full per-combination run bundles.
Run a local stress sweep across scenarios, seeds, models, and parameter values:
dotnet run --project src/PolityKit.Sim.Cli -- stress \
--scenario village-food-crisis \
--scenario examples/medicine-shortage.json \
--seed 111,222 \
--models need-based-allocation,market-based-allocation \
--sweep needPriorityWeight=0.75,1.0,1.25 \
--out runs/v0-6-stressRun a stress sweep that compares baseline models with multiple governance presets across existing challenge scenarios:
dotnet run --project src/PolityKit.Sim.Cli -- stress \
--grid-name baseline-preset-comparison \
--scenario examples/medicine-shortage.json \
--scenario examples/corruption-stress.json \
--seed 111,222 \
--models need-based-allocation,market-based-allocation,hierarchy-based-allocation,participatory-commons,regulated-market,technocratic-administration \
--sweep needWeightMultiplier=0.8,1.0,1.2 \
--out runs/baseline-preset-comparison-stressAfter a stress sweep, inspect:
stress-summary.jsonfor collapse events, sensitivity, and model robustness summaries.stress-metrics.csvfor final metrics by stress run.modelRobustnessto compare collapse rate, recovery rate, collapse timing, most sensitive parameter, and best/worst scenario names. Treat these as simulation diagnostics for the tested assumptions, not as real-world model rankings.
For mixed baseline-plus-preset stress runs, modelRobustness uses the same summary shape for both families:
{
"modelRobustness": [
{
"model": "NeedBasedAllocation",
"runsCompleted": 12,
"mostSensitiveParameter": "needWeightMultiplier"
},
{
"model": "CompositeGovernance:participatory-commons",
"runsCompleted": 12,
"mostSensitiveParameter": "needWeightMultiplier"
}
]
}Generate an advisory batch anomaly artifact from a completed stress summary:
dotnet run --project src/PolityKit.Sim.Cli -- ai-anomalies \
--stress-summary runs/baseline-preset-comparison-stress/stress-summary.json \
--provider fakeThis writes ai-anomalies.json with structured anomaly candidates for model, scenario, seed, metric, observed value, and explanation. The artifact flags provider output that references run IDs, models, scenarios, seeds, or metrics that were not present in the source stress summary.
AI-assisted workflows are optional tools for reading recorded simulation artifacts. They generate interpretations, critiques, draft scenarios, and anomaly candidates from existing summary.json, config.json, and stress-summary.json files. They do not run the simulation engine, alter model behavior, change metric calculations, rewrite scenario validation, change seeds, or modify completed run results.
Treat every AI artifact as advisory review material:
ai-summary.jsonis generated interpretation of a completed run bundle.ai-scenario-suggestions.jsonis a proposed draft that must pass normal scenario validation before use.ai-model-critique.jsonis a review prompt about assumptions, observed failure modes, suggested tests, and documentation gaps.ai-anomalies.jsonis a set of anomaly candidates to compare against deterministic stress outputs.
Known limitations:
- Generated text can hallucinate, omit important caveats, or overstate patterns in the deterministic output.
- Provider behavior can drift across model versions, even when PolityKit inputs stay the same.
- Prompt wording and context selection can change what the provider emphasizes.
- External providers may receive scenario names, model names, seeds, parameters, metrics, event summaries, and other run data.
- AI output is not evidence that a model is correct, robust, predictive, fair, or policy-ready.
Always inspect the deterministic source files and provenance before using an AI-assisted artifact in analysis, documentation, or follow-up experiments.
Start the API:
dotnet run --project src/PolityKit.Sim.ApiThe default HTTP endpoint is:
http://localhost:5020
List models:
Invoke-RestMethod http://localhost:5020/api/modelsList metrics:
Invoke-RestMethod http://localhost:5020/api/metricsList scenarios:
Invoke-RestMethod http://localhost:5020/api/scenariosCreate a run:
$body = @{
scenario = "village-food-crisis"
seed = 12345
ticks = 60
models = @(
"need-based-allocation",
"market-based-allocation"
)
parameters = @{
needPriorityWeight = 1.0
vulnerabilityPriorityWeight = 0.5
}
} | ConvertTo-Json -Depth 5
$run = Invoke-RestMethod `
-Method Post `
-Uri http://localhost:5020/api/runs `
-ContentType "application/json" `
-Body $body
$runFetch the run detail, metrics, events, and dashboard-ready payload:
Invoke-RestMethod "http://localhost:5020/api/runs/$($run.id)"
Invoke-RestMethod "http://localhost:5020/api/runs/$($run.id)/metrics"
Invoke-RestMethod "http://localhost:5020/api/runs/$($run.id)/events"
Invoke-RestMethod "http://localhost:5020/api/runs/$($run.id)/dashboard"Rerun a completed run with the same scenario and seed:
$rerun = Invoke-RestMethod `
-Method Post `
-Uri "http://localhost:5020/api/runs/$($run.id)/rerun" `
-ContentType "application/json" `
-Body (@{} | ConvertTo-Json)Rerun with changed model parameters while keeping the original seed:
$rerun = Invoke-RestMethod `
-Method Post `
-Uri "http://localhost:5020/api/runs/$($run.id)/rerun" `
-ContentType "application/json" `
-Body (@{
parameters = @{
needPriorityWeight = 1.25
}
} | ConvertTo-Json -Depth 5)Compare two completed runs:
Invoke-RestMethod "http://localhost:5020/api/runs/$($run.id)/compare/$($rerun.id)"Run a basic parameter sweep:
$sweep = Invoke-RestMethod `
-Method Post `
-Uri "http://localhost:5020/api/runs/sweep" `
-ContentType "application/json" `
-Body (@{
scenario = "village-food-crisis"
seed = 12345
ticks = 60
models = @("need-based-allocation")
parameters = @{
fixedWeight = 1.0
}
sweep = @{
needPriorityWeight = @(0.75, 1.0, 1.25)
vulnerabilityPriorityWeight = @(0.25, 0.5)
}
} | ConvertTo-Json -Depth 6)The sweep response includes each generated run, its parameter combination, final metrics, best/worst metric runs, and sensitivity rankings.
Run a stress sweep from the API:
$stress = Invoke-RestMethod `
-Method Post `
-Uri "http://localhost:5020/api/runs/stress" `
-ContentType "application/json" `
-Body (@{
gridName = "v0-6-stress"
scenarios = @("village-food-crisis", "examples/medicine-shortage.json")
seeds = @(111, 222)
models = @("need-based-allocation", "market-based-allocation")
sweep = @{
needPriorityWeight = @(0.75, 1.0, 1.25)
}
} | ConvertTo-Json -Depth 6)The stress response includes run summaries, collapse events, sensitivity rankings, and modelRobustness summaries for comparing models under the tested assumptions.
API stress requests can mix baseline names and preset IDs:
$stress = Invoke-RestMethod `
-Method Post `
-Uri "http://localhost:5020/api/runs/stress" `
-ContentType "application/json" `
-Body (@{
gridName = "baseline-preset-comparison"
scenarios = @("village-food-crisis")
seeds = @(111, 222)
ticks = 60
models = @(
"need-based-allocation",
"market-based-allocation",
"hierarchy-based-allocation",
"participatory-commons",
"regulated-market"
)
sweep = @{
needWeightMultiplier = @(0.8, 1.0, 1.2)
}
} | ConvertTo-Json -Depth 6)List all persisted API runs:
Invoke-RestMethod http://localhost:5020/api/runsThe API stores run records as JSON files under data/runs by default. Configure RunStorage:Directory to change the storage location.
API run, sweep, stress, and comparison responses include aiAnalysis. By default this records used: false; AI-generated text, if added later, must stay advisory and record provenance such as source run IDs, files, scenarios, models, seeds, metrics, provider, model, prompt template version, and creation time rather than becoming authoritative simulation data.
The shared analysis layer includes an optional provider abstraction with local disabled mode. By default AI analysis returns AI analysis is not configured. without requiring any provider package or sending run data externally.
For local examples and tests, configure AiAnalysis:Enabled=true and AiAnalysis:ProviderName=fake, then call POST /api/runs/{id}/ai/summary to generate an advisory run-summary artifact for a stored run, POST /api/runs/{id}/ai/scenario-suggestions to generate a validated scenario suggestion draft, POST /api/runs/{id}/ai/model-critique?model=regulated-market to generate an advisory model critique, or POST /api/runs/stress/ai/anomalies with a stress request body to generate advisory anomaly candidates from the resulting stress summary. The older POST /api/runs/{id}/ai-summary and POST /api/runs/{id}/scenario-suggestions aliases remain available for compatibility.
Disabled mode example:
$run = Invoke-RestMethod `
-Method Post `
-Uri http://localhost:5020/api/runs `
-ContentType "application/json" `
-Body (@{
scenario = "village-food-crisis"
ticks = 5
models = @("need-based-allocation")
} | ConvertTo-Json -Depth 6)
try {
Invoke-RestMethod `
-Method Post `
-Uri "http://localhost:5020/api/runs/$($run.id)/ai/summary"
} catch {
$_.ErrorDetails.Message
}With default configuration this returns a ProblemDetails response with status 503, title AI analysis is disabled., and detail AI analysis is not configured.
Configured fake-provider example:
Start the API with the local fake provider:
$env:AiAnalysis__Enabled = "true"
$env:AiAnalysis__ProviderName = "fake"
dotnet run --project src/PolityKit.Sim.ApiThen create or reuse a stored run and request an advisory summary:
$run = Invoke-RestMethod `
-Method Post `
-Uri http://localhost:5020/api/runs `
-ContentType "application/json" `
-Body (@{
scenario = "village-food-crisis"
ticks = 5
models = @("need-based-allocation")
} | ConvertTo-Json -Depth 6)
Invoke-RestMethod `
-Method Post `
-Uri "http://localhost:5020/api/runs/$($run.id)/ai/summary"The fake-provider response is an advisory artifact with aiAnalysis.used: true, source run/scenario/model/seed provenance, provider metadata, and generated interpretation text. It does not change the stored run or any deterministic endpoint response.
See AI boundaries and safety for the optional-AI rule, advisory-output rule, provenance shape, provider guardrails, and privacy note for data sent to external providers.
The current API exposes:
GET /api/models
GET /api/metrics
GET /api/scenarios
GET /api/runs
POST /api/runs
GET /api/runs/{id}
GET /api/runs/{id}/metrics
GET /api/runs/{id}/events
GET /api/runs/{id}/dashboard
POST /api/runs/{id}/ai/summary
POST /api/runs/{id}/ai/scenario-suggestions
POST /api/runs/{id}/ai/model-critique
POST /api/runs/{id}/rerun
GET /api/runs/{id}/compare/{comparisonId}
POST /api/runs/sweep
POST /api/runs/stress
POST /api/runs/stress/ai/anomalies
Example run request:
{
"scenario": "village-food-crisis",
"seed": 12345,
"ticks": 120,
"models": [
"need-based-allocation",
"market-based-allocation",
"hierarchy-based-allocation"
],
"parameters": {
"needPriorityWeight": 1.0,
"vulnerabilityPriorityWeight": 0.5
}
}The API stores runs in the configured file-backed run store.
Example JSON scenarios live in examples/:
village-food-crisis.jsonmedicine-shortage.jsonhousing-displacement.jsoninterpretability-demo.jsoncorruption-stress.json
The scenario guide lives at docs/politykit/scenarios.md, and the formal schema lives at docs/politykit/scenario.schema.json.
The golden interpreted run bundle lives at examples/golden-interpreted-run.
Each scenario includes:
nameseedticksinitialPopulationinitialResourcesshocks
Currently handled shock types include:
CropFailureMedicineShortageHousingLossAdministrativeOverloadAdminLossCorruptionSpike
WorldState represents the current simulation state: tick, population, resources, institutional state, environment, and recorded events.
Citizens are simulated agents with simple properties such as food need, health need, housing need, wealth, social power, trust in system, and vulnerability.
The current resource pool includes:
- Food
- Medicine
- Housing
- Administrative capacity
- Production capacity
A system model decides how a simulated society responds to current world conditions. Starter models use neutral mechanical names:
NeedBasedAllocation: prioritizes unmet need and vulnerability.MarketBasedAllocation: prioritizes wealth and demand pressure.HierarchyBasedAllocation: prioritizes social power, obligation, and visible need.
Each model exposes a manifest with assumptions and known failure modes.
Composite governance presets appear as CompositeGovernance:<preset-id> models. They are simplified bundles of governance dimensions, not claims about real societies. Their manifests include both preset-level assumptions and per-dimension assumptions such as allocation mechanism, decision authority, accountability, information flow, property regime, and appeal process.
See Governance presets for the current preset list, manifest interpretation rules, and wording boundaries for comparing presets against baseline models.
Governance presets let users compare bundles of declared assumptions without turning a single label into a whole model. Current preset IDs include:
participatory-commonsregulated-marketcentral-planningpatronage-hierarchymutual-aid-federationtechnocratic-administration
Treat these IDs as experiment names. A preset result means "under this scenario, seed, model version, and declared assumptions, this behavior emerged." It does not mean the preset label describes or evaluates a real-world society.
For each selected model, the engine:
- Creates a fresh seeded world from the scenario.
- Applies scheduled shocks on each tick.
- Asks the model for a
SystemDecision. - Applies shared world rules.
- Records configured metrics.
- Returns per-model worlds, events, and metric series.
Metrics describe what happened during a run:
Needs Met: share of citizens with food, health, and housing needs met.Inequality: Gini-style wealth inequality score.Trust: average of institutional trust and citizen trust.Severe Failures: severe events plus citizens in severe need or very low trust.Administrative Load: appeal backlog plus administrative overflow events.
Models should expose the assumptions that drive their behavior. Important values should be documented and configurable where practical.
PolityKit should compare systems under shared conditions, not declare universal winners.
Useful questions include:
- Which model fails first under scarcity?
- Which model preserves trust longest?
- Which model is most sensitive to corruption?
- Which model recovers fastest after a shock?
- Which model produces high output but high inequality?
- Which model degrades gracefully as resources decline?
The engine defines shared world mechanics. System models decide what actions to take within that world.
For example:
- The engine defines what happens when a citizen does not receive enough food.
- A system model decides who receives food.
This separation keeps comparisons consistent.
Given the same scenario, seed, model, configuration, and version, a run should produce the same result.
Every run records:
- Scenario name.
- Model name and version.
- Configuration values.
- Random seed.
- Simulation duration.
- Metrics.
- Event log.
- Final citizen state.
AI analysis is optional and never required to run simulations. AI output may help explain or propose follow-up artifacts, but it is not simulation data and must not change deterministic run results. Any AI-assisted artifact should record whether AI was used, the input run IDs or files it read, the scenarios, models, seeds, and metrics it referenced, and the provider/model that generated the text.
PolityKit results should be read carefully.
A result does not mean:
This system works in the real world.
It means:
Under this scenario, using this model, with these assumptions, this behavior emerged.
The most interesting results are often patterns: sudden collapse after a threshold, slow decline hidden by short-term stability, fairness paired with administrative load, or fast crisis response paired with poor long-term trust.
Governance preset results need the same caution. A preset label is shorthand for a manifest, not an argument about the real world. Compare the selected dimensions, assumptions, failure modes, scenario, seed, and parameter grid before drawing conclusions.
Useful contribution areas include:
- New scenario files and stress cases.
- New metrics.
- New model variants with explicit assumptions.
- CLI improvements.
- API persistence and query features.
- Visualization and dashboard tooling.
- Documentation for assumptions, formulas, and model limitations.
- Tests for new behavior.
The project should welcome disagreement by turning it into inspectable model-building: fork the model, change the assumptions, run the same scenario, and compare the results.
Contributor docs:
- Contributing guide
- How to add a model
- Governance presets
- How to add a metric
- How to add a scenario
- Scenario format reference
See docs/politykit/implementation/politykit-roadmap.md.
PolityKit is licensed under the Apache License 2.0. See LICENSE.
PolityKit is a simulation framework for exploring assumptions and system behavior. It should not be used as a source of political, economic, legal, or policy authority. Models are simplified by design and should be interpreted as experimental tools rather than representations of real societies.