2.0.0: clean foundations#
Status: proposed · Base: 1.5.0
2.0.0 is the only release on this roadmap allowed to break things, and it breaks them on
purpose and with a map. Three 1.x releases of features leave behind parallel ways of doing the
same thing; 2.0 keeps the best one of each and makes it the only one. One space API, one
clock, columns by default, typed scenarios, per-agent random streams, a stable C ABI and a
checkpoint format that lasts. Every removal was deprecated in 1.5 at the latest, and
modelly migrate --to 2.0 rewrites what can be rewritten. All on Windows, macOS and Linux (see
Platforms).
Principles#
No surprise breaks. Nothing is removed in 2.0 that did not warn in 1.5, naming the replacement.
One way. Where 1.x grew two ways to do a thing, 2.0 keeps one.
Same science. A model migrated to 2.0 gives statistically the same results as on 1.5; where the random streams change (per-agent streams), the migration guide says so and the agreement test (Welch, as in the playbooks) proves it.
Faster everywhere. No playbook slower than 1.5 on any OS.
Supported 1.x. 1.5 is a long-term-support line: it keeps receiving bug and security fixes after 2.0.0, so every user can migrate when their own work allows.
Epics#
H1 · Removals and the migration tool#
Goal: remove every deprecated name and make upgrading a command, not a project.
Work items: remove everything deprecated in 1.3 to 1.5; modelly migrate --to 2.0 (the
codemod from modelly.migrate, extended to 1.x → 2.0 rewrites) with a dry run, a diff and a
report of what needs a human; a migration guide with before/after for every removal; migration
tested on every zoo and hub model.
Done when: every zoo model and the three community models migrate automatically, pass their validation tests, and agree with their 1.5 results.
Size: L
H2 · One space API#
Goal: grids, networks, continuous space and geographic space share one protocol: the same calls to place, move, query neighbours and iterate, whatever the geometry.
Design: a Space protocol (place, move, neighbors, within, positions as a column);
discrete spaces keep cells, continuous and geographic spaces keep coordinates, both answer the
same queries; property layers become fields (from 1.4 F6) on every space; old space classes kept
as thin aliases through 2.x where they map cleanly.
Done when: every zoo model runs on the new protocol; a model can switch grid to network to continuous space by changing one line, verified by a tutorial.
Size: XL
H3 · Columns by default#
Goal: agent state lives in columns unless the model asks otherwise, so every model gets the 1.x column speed-ups without rewriting.
Design: typed attribute declarations (wealth: float = Column(0.0) or plain annotations)
become columns automatically; attributes that cannot be columns (objects, lists) stay per-agent
and are reported by modelly profile; DataCollector gathers columns without Python loops.
Done when: the classic playbook variants (per-agent code) run at least as fast as their 1.5 column variants after migration; no model loses an attribute in migration.
Size: L
H4 · One clock#
Goal: ticks and events on one scheduler with one documented ordering rule.
Design: steps are events at integer times; phases are priorities; tie-breaking is fully
specified (time, priority, insertion order); the compiled scheduler from 1.4 is the only one; a
schedule report shows what runs when.
Done when: every model with mixed ticks and events gives the same results as on 1.5 under the documented ordering; the ordering spec is a docs page with tests for each rule.
Size: M
H5 · Typed scenarios and configuration#
Goal: scenarios are typed, validated and loadable from files.
Design: Scenario as a dataclass_transform base (the default-type TODO in
modelly/core/model.py that waits for Python 3.13); validation with clear errors (range, type,
units); TOML and YAML loading; scenarios hashed into the manifest; sweeps over typed spaces.
Size: M
H6 · Per-agent random streams by default#
Goal: results independent of iteration order, partitioning and executor.
Design: opt-in in 1.4 (F1), default in 2.0; counter-based generators (Philox) keyed by run seed and agent id, shared by CPU and GPU; the model-level generators remain for model-level draws.
Done when: partition-independence holds for every space by default; agreement tests show the same distributions as 1.5 on every playbook.
Size: M · Depends on: 1.4 F1, F2
H7 · Stable ABI and native code#
Goal: one wheel per platform for every supported Python, and native code ready for every CPython build.
Design: the compiled modules move to the limited C API (abi3) where measurement shows no loss, keeping the version-specific build only where it matters; free-threaded builds are first-class; the private and unstable APIs left are inventoried and justified.
Done when: abi3 wheels for every row of the support matrix; no playbook slower than the version-specific build by more than 3%; a new CPython release installs on day one.
Size: M
H8 · Checkpoint and data formats v2#
Goal: a checkpoint written by 2.0 loads in every later 2.x release.
Design: a versioned, documented state format (columns as Arrow, structure as JSON, only
user objects pickled); forward migrations between format versions; modelly checkpoint upgrade
for 1.x files where the state maps; result stores and manifests versioned the same way.
Done when: a 2.0 checkpoint loads in a 2.1 test build; 1.5 checkpoints of every zoo model upgrade and resume with the same results.
Size: M
H9 · Python and platform baseline#
Work items: Python 3.13 minimum (3.12 dropped, as its own end of life approaches); a single test and release matrix covering every platform in the support table; installation verified on clean Windows, macOS and Linux machines with no compiler and no admin rights.
Size: S
H10 · Public API contract#
Work items: every public name listed in one place with its stability level (stable, provisional); the semantic-versioning promise written down; type-checked public API (strict); the plugin API v1 from 1.5 carried over unchanged.
Size: S
H11 · Documentation 2.0#
Work items: docs restructured around tasks (build, calibrate, scale, share, publish); every
page tested (doctests and executed notebooks) on all three OSs; the migration guide and the
“what is new in 2.0” tour; versioned docs keep /1.5/ as the LTS reference.
Size: M
Priorities#
Priority |
Epics |
|---|---|
Must |
H1 Removals and migration, H2 One space API, H4 One clock, H8 Formats v2, H10 API contract |
Should |
H3 Columns by default, H5 Typed scenarios, H6 Per-agent streams, H11 Docs |
Could |
H7 abi3 (if measurement allows), H9 is required but small |
Won’t |
New features unrelated to the foundations; those go to 2.1 |
flowchart LR
F1["1.4 Distributed"] --> H6[H6 Per-agent streams]
F2["1.4 GPU"] --> H6
F6["1.4 Fields"] --> H2[H2 One space API]
H2 --> H3[H3 Columns by default]
H4[H4 One clock] --> H8[H8 Formats v2]
H3 --> H8
H5[H5 Typed scenarios] --> H8
H8 --> H1[H1 Migration tool]
H2 --> H1
H4 --> H1
H1 --> H11[H11 Docs 2.0]
Sprint plan#
2.0 has one more sprint than its features need: users migrate their models on the beta and report what the migration tool misses, and S7 fixes it.
Sprint |
Goal |
Main items |
Exit |
|---|---|---|---|
S1 |
Contract and clock |
Public API inventory and stability levels; one scheduler with the ordering spec |
Ordering spec tests pass on every example |
S2 |
Space protocol |
|
Grid and network zoo models pass on the protocol |
S3 |
Columns and streams · a1 |
Continuous and geographic spaces on the protocol; columns by default; per-agent streams default |
Playbooks agree with 1.5 (Welch) |
S4 |
Formats and scenarios |
Checkpoint and result formats v2; typed scenarios; Python 3.13 minimum |
1.5 checkpoints upgrade and resume |
S5 |
Migration tool |
|
Every zoo model migrates automatically |
S6 |
Beta and abi3 · b1 |
abi3 builds measured; docs 2.0; call for migration testing |
API frozen; hub models migrated |
S7 |
Migration feedback · rc1 |
Fix what users’ migrations reveal |
No open blocker |
S8 |
Hardening · 2.0.0 |
Full matrix on all platforms; LTS branch |
All gates pass |
Release gates#
Release |
Gate |
|---|---|
2.0.0a1 |
Space protocol, one clock, columns by default and per-agent streams in; playbooks agree with 1.5 |
2.0.0b1 |
Every Must epic done; API frozen; every zoo and hub model migrated automatically |
2.0.0rc1 |
No open blocker from user migrations |
2.0.0 |
Determinism and agreement suites green on Windows, macOS and Linux; no playbook slower than 1.5 on any OS; LTS for 1.5 announced |
Success metrics#
Metric |
1.5.0 |
2.0.0 target |
|---|---|---|
Ways to place and move an agent |
one per space type |
one |
Schedulers |
ticks plus events |
one clock |
Models migrated automatically |
not applicable |
every zoo and hub model |
Checkpoint compatibility |
same minor version |
every later 2.x |
Wheels per platform |
one per Python version |
one (abi3) where measured equal |
Slowest playbook versus 1.5 |
not applicable |
not slower on any OS |
Risks#
Risk |
Likelihood |
Impact |
Mitigation |
|---|---|---|---|
Migration breaks user models silently |
Medium |
High |
Agreement tests in the migration report; dry run by default; LTS for 1.5 |
The space protocol cannot express a space well |
Medium |
High |
Prototype in S2 on all four space types before committing; keep thin aliases |
Per-agent streams change results users have published |
High |
Medium |
Documented in the guide; the 1.5 LTS reproduces old results; agreement tests prove the distributions match |
abi3 is slower |
Medium |
Low |
Keep version-specific wheels where measured slower |
Too many changes at once |
High |
High |
Won’t list strictly enforced: no new features in 2.0 |
Open questions#
[ ] Python 3.13 or 3.14 as the 2.0 minimum?
[ ] Do the old space classes stay as aliases through 2.x, or go in 2.1?
[ ] When does 1.5 LTS end: when 2.1 ships, or when the hub’s models have all migrated?
Sprint review log#
Sprint |
Shipped |
Slipped |
Notes |
|---|---|---|---|
S1 |
|||
S2 |
|||
S3 |
|||
S4 |
|||
S5 |
|||
S6 |
|||
S7 |
|||
S8 |