roadmodel 0.2.98__tar.gz → 0.2.99__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. {roadmodel-0.2.98 → roadmodel-0.2.99}/PKG-INFO +1 -1
  2. {roadmodel-0.2.98/roadmodel/data → roadmodel-0.2.99/docs}/catalog.json +1 -1
  3. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/claude-commands/roadmap-refresh.md +5 -6
  4. {roadmodel-0.2.98/roadmodel/data → roadmodel-0.2.99/docs/claude-commands}/roadmap-step.md +1 -2
  5. {roadmodel-0.2.98/roadmodel/data → roadmodel-0.2.99/docs/templates}/phase-roadmap-template.md +11 -12
  6. {roadmodel-0.2.98/roadmodel/data → roadmodel-0.2.99/docs/templates}/project-roadmap-template.md +43 -43
  7. {roadmodel-0.2.98 → roadmodel-0.2.99}/pyproject.toml +1 -1
  8. {roadmodel-0.2.98/docs → roadmodel-0.2.99/roadmodel/data}/catalog.json +1 -1
  9. {roadmodel-0.2.98/docs/templates → roadmodel-0.2.99/roadmodel/data}/phase-roadmap-template.md +11 -12
  10. {roadmodel-0.2.98/docs/templates → roadmodel-0.2.99/roadmodel/data}/project-roadmap-template.md +43 -43
  11. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/roadmap-refresh.md +5 -6
  12. {roadmodel-0.2.98/docs/claude-commands → roadmodel-0.2.99/roadmodel/data}/roadmap-step.md +1 -2
  13. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/__init__.py +1 -1
  14. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/ladder_layout.py +15 -12
  15. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/scoring.py +27 -4
  16. {roadmodel-0.2.98 → roadmodel-0.2.99}/.github/README.md +0 -0
  17. {roadmodel-0.2.98 → roadmodel-0.2.99}/.gitignore +0 -0
  18. {roadmodel-0.2.98 → roadmodel-0.2.99}/LICENSE +0 -0
  19. {roadmodel-0.2.98 → roadmodel-0.2.99}/NOTICE +0 -0
  20. {roadmodel-0.2.98 → roadmodel-0.2.99}/README.md +0 -0
  21. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/benchmarks.json +0 -0
  22. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/claude-commands/roadmap-phase.md +0 -0
  23. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/claude-commands/roadmap-project.md +0 -0
  24. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/claude-commands/roadmodel-upgrade.md +0 -0
  25. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/context-windows.json +0 -0
  26. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/effort-tokens.json +0 -0
  27. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/model-selector.txt +0 -0
  28. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/model-tier-cost-scale.md +0 -0
  29. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/settings-display.md +0 -0
  30. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/templates/planning-kit-how-to-use.md +0 -0
  31. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/templates/prompt-phase-roadmap.md +0 -0
  32. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/templates/prompt-project-roadmap.md +0 -0
  33. {roadmodel-0.2.98 → roadmodel-0.2.99}/docs/user-context.example.md +0 -0
  34. {roadmodel-0.2.98 → roadmodel-0.2.99}/hatch_build.py +0 -0
  35. {roadmodel-0.2.98 → roadmodel-0.2.99}/infra/README.md +0 -0
  36. {roadmodel-0.2.98 → roadmodel-0.2.99}/infra/gcp-killswitch/README.md +0 -0
  37. {roadmodel-0.2.98 → roadmodel-0.2.99}/infra/supabase/README.md +0 -0
  38. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/benchmarks.json +0 -0
  39. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/context-windows.json +0 -0
  40. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/effort-tokens.json +0 -0
  41. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/model-selector.txt +0 -0
  42. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/model-tier-cost-scale.md +0 -0
  43. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/planning-kit-how-to-use.md +0 -0
  44. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/prompt-phase-roadmap.md +0 -0
  45. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/prompt-project-roadmap.md +0 -0
  46. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/roadmap-phase.md +0 -0
  47. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/roadmap-project.md +0 -0
  48. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/roadmodel-upgrade.md +0 -0
  49. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/settings-display.md +0 -0
  50. {roadmodel-0.2.98 → roadmodel-0.2.99}/roadmodel/data/user-context.example.md +0 -0
  51. {roadmodel-0.2.98 → roadmodel-0.2.99}/scripts/agent_context.py +0 -0
  52. {roadmodel-0.2.98 → roadmodel-0.2.99}/scripts/agent_rules.py +0 -0
  53. {roadmodel-0.2.98 → roadmodel-0.2.99}/scripts/update_projects.py +0 -0
  54. {roadmodel-0.2.98 → roadmodel-0.2.99}/scripts/updater_lock.py +0 -0
  55. {roadmodel-0.2.98 → roadmodel-0.2.99}/scripts/upgrade_fleet.py +0 -0
  56. {roadmodel-0.2.98 → roadmodel-0.2.99}/scripts/worktree_memory.py +0 -0
  57. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/__main__.py +0 -0
  58. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/cli.py +0 -0
  59. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/config.py +0 -0
  60. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/cost.py +0 -0
  61. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/errors.py +0 -0
  62. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/mcp_server.py +0 -0
  63. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/private_files.py +0 -0
  64. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/providers/__init__.py +0 -0
  65. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/providers/_safety.py +0 -0
  66. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/providers/anthropic.py +0 -0
  67. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/providers/google.py +0 -0
  68. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/providers/openai.py +0 -0
  69. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/providers/openai_compatible.py +0 -0
  70. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/providers/registry.py +0 -0
  71. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/recommend.py +0 -0
  72. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/series.py +0 -0
  73. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/usage.py +0 -0
  74. {roadmodel-0.2.98 → roadmodel-0.2.99}/src/roadmodel/user_context.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: roadmodel
3
- Version: 0.2.98
3
+ Version: 0.2.99
4
4
  Summary: BYO-key CLI that recommends the right AI model, platform, and settings for a prompt.
5
5
  Project-URL: Homepage, https://roadmodel.ai
6
6
  Project-URL: Repository, https://github.com/nathanramoscfa/roadmodel
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema_version": "4",
3
3
  "output_contract_version": 2,
4
- "generated_at_utc": "2026-10-25T19:01:45Z",
4
+ "generated_at_utc": "2026-10-27T17:02:15Z",
5
5
  "source_doc_sha256": {
6
6
  "model-selector.txt": "e2ef6c5a18f05ff952fad9f576720b8fc4637f563f60ce5c077c5501fc21d1b7",
7
7
  "model-tier-cost-scale.md": "dad707e59d0f3e75cf699d81368ba66783cc2a6a0bf625c430e8f884ef844a1c"
@@ -204,8 +204,7 @@ complexity, novel or not; its Model rationale names them), then:
204
204
  fix, not a new pick, so it takes no `Settings updated` line.
205
205
  - Every ladder, a step's Settings and a phase's Phase roadmap settings
206
206
  alike, takes the table layout (roadmodel 0.2.95 on), as `roadmodel
207
- ladder` prints it: Cost, Balanced and Quality columns (the one its
208
- **Runs:** line names marked ✓), each rank (**Pick**, **Runner‑up**,
207
+ ladder` prints it: Cost, Balanced and Quality columns, each rank (**Pick**, **Runner‑up**,
209
208
  **Backup**) in a column of its own beside its Model / Platform / Level / AA /
210
209
  Price rows — Level the bare level of the platform's own dial, AA its AA
211
210
  Intelligence Index there (`not measured` where AA has no row), Price its
@@ -222,10 +221,10 @@ complexity, novel or not; its Model rationale names them), then:
222
221
  progress` step's is what an agent is running, and a written phase's
223
222
  records what wrote its roadmap, so those keep their layout. One
224
223
  exception reaches every section: a 0.2.95–0.2.97 table, whose fields are
225
- indented with ` ` (some viewers draw each as a highlighted blob),
226
- takes the rank column wherever it stands, Complete steps included, every
227
- cell kept. That is a layout fix, not a new pick, and takes no `Settings
228
- updated` line. Then
224
+ indented with ` ` (some viewers draw each as a highlighted blob), or
225
+ a 0.2.98 table still carrying ✓, takes the rank column without ✓ wherever
226
+ it stands, Complete steps included, every cell kept. That is a layout fix,
227
+ not a new pick, and takes no `Settings updated` line. Then
229
228
  run `roadmodel rerank <every roadmap file>` (roadmodel 0.2.97 on): it
230
229
  gives each of those ladder tables the ranks this release computes, so a
231
230
  change to how roadmodel ranks reaches every step not yet run. It reads
@@ -114,8 +114,7 @@ the dials and make sure it is set.
114
114
  **Backup**) sits in a column of its own beside its Model, Platform, Level, AA and
115
115
  Price rows. Level is the bare level of that platform's own dial (`High`
116
116
  is Intelligence High on Codex, Effort High on Claude Code and
117
- Antigravity). The ✓ in a column's header marks the one its **Runs:**
118
- line names. From roadmodel 0.2.97 the three ranks of a column come from
117
+ Antigravity). From roadmodel 0.2.97 the three ranks of a column come from
119
118
  three makers (a tight pool is a maker's); where too few are funded, a
120
119
  missing rank is the Pick one level lower, its Level marked ↓, and the
121
120
  note line says which classification the ladder was ranked for. A 0.2.94
@@ -758,8 +758,7 @@ that owns it.}}
758
758
  <c> --complexity <x> [--novel]` prints them for the
759
759
  step's classification (MCP tool: `roadmap_settings`).
760
760
  Layout (roadmodel 0.2.95 on): one table whose columns
761
- are Cost, Balanced and Quality (the column the **Runs:**
762
- line names marked ✓). Each rank — **Pick**, **Runner‑up**,
761
+ are Cost, Balanced and Quality. Each rank — **Pick**, **Runner‑up**,
763
762
  **Backup** — names the first of its rows from a column of
764
763
  its own (blank below it, no `&nbsp;`), beside
765
764
  field rows: Model (bold); Platform; Level, the bare
@@ -774,7 +773,7 @@ that owns it.}}
774
773
  no Thinking row: Thinking is always On wherever the
775
774
  platform has the toggle, and every AA Index and Price
776
775
  already assumes it. A note line under the table explains
777
- ✓ and Price, and a `**Conversation:**` line closes the
776
+ Price, and a `**Conversation:**` line closes the
778
777
  ladder. Each rank comes from its own maker (roadmodel
779
778
  0.2.97 on), because a tight usage pool is a maker's: the
780
779
  Runner-up is the column's recommendation with the Pick's
@@ -892,7 +891,7 @@ step's classification, pasted as printed. The three table
892
891
  shapes after it are the fallback where roadmodel cannot be
893
892
  reached}}):
894
893
 
895
- | | | Cost | Balanced ✓ | Quality |
894
+ | | | Cost | Balanced | Quality |
896
895
  | ------------- | -------- | --------------------- | --------------------- | --------------------- |
897
896
  | **Pick** | Model | **{{Model}}** | **{{Model}}** | **{{Model}}** |
898
897
  | | Platform | {{Platform}} | {{Platform}} | {{Platform}} |
@@ -910,8 +909,8 @@ reached}}):
910
909
  | | AA | {{AA Index}} | {{AA Index}} | {{AA Index}} |
911
910
  | | Price | {{$ per 1M}} | {{$ per 1M}} | {{$ per 1M}} |
912
911
 
913
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
914
- model uses at that level.
912
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
913
+ level.
915
914
 
916
915
  **Conversation:** New
917
916
 
@@ -1331,7 +1330,7 @@ printed with its **Runs:** line. Where roadmodel cannot be
1331
1330
  reached, the single-column variant that matches PLATFORM,
1332
1331
  carrying ONLY the rows that platform's panel exposes.}}
1333
1332
 
1334
- | | | Cost | Balanced ✓ | Quality |
1333
+ | | | Cost | Balanced | Quality |
1335
1334
  | ------------- | -------- | --------------------- | --------------------- | --------------------- |
1336
1335
  | **Pick** | Model | **{{Model}}** | **{{Model}}** | **{{Model}}** |
1337
1336
  | | Platform | {{Platform}} | {{Platform}} | {{Platform}} |
@@ -1349,8 +1348,8 @@ carrying ONLY the rows that platform's panel exposes.}}
1349
1348
  | | AA | {{AA Index}} | {{AA Index}} | {{AA Index}} |
1350
1349
  | | Price | {{$ per 1M}} | {{$ per 1M}} | {{$ per 1M}} |
1351
1350
 
1352
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
1353
- model uses at that level.
1351
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
1352
+ level.
1354
1353
 
1355
1354
  **Conversation:** New
1356
1355
 
@@ -1481,7 +1480,7 @@ this step's classification, pasted as printed with its
1481
1480
  **Runs:** line; where roadmodel cannot be reached, the
1482
1481
  single-column variant that matches PLATFORM.}}
1483
1482
 
1484
- | | | Cost | Balanced ✓ | Quality |
1483
+ | | | Cost | Balanced | Quality |
1485
1484
  | ------------- | -------- | --------------------- | --------------------- | --------------------- |
1486
1485
  | **Pick** | Model | **{{Model}}** | **{{Model}}** | **{{Model}}** |
1487
1486
  | | Platform | {{Platform}} | {{Platform}} | {{Platform}} |
@@ -1499,8 +1498,8 @@ single-column variant that matches PLATFORM.}}
1499
1498
  | | AA | {{AA Index}} | {{AA Index}} | {{AA Index}} |
1500
1499
  | | Price | {{$ per 1M}} | {{$ per 1M}} | {{$ per 1M}} |
1501
1500
 
1502
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
1503
- model uses at that level.
1501
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
1502
+ level.
1504
1503
 
1505
1504
  **Conversation:** New
1506
1505
 
@@ -250,7 +250,7 @@ dependency graph in §5 is honoured.
250
250
  **Phase roadmap settings** — the session that writes
251
251
  `phase01-roadmap.md` (`/roadmap-phase 1`):
252
252
 
253
- | | | Cost | Balanced | Quality ✓ |
253
+ | | | Cost | Balanced | Quality |
254
254
  | ------------- | -------- | ------------------- | ------------------- | ------------------- |
255
255
  | **Pick** | Model | **<Model>** | **<Model>** | **<Model>** |
256
256
  | | Platform | <Platform> | <Platform> | <Platform> |
@@ -268,8 +268,8 @@ dependency graph in §5 is honoured.
268
268
  | | AA | <AA Index> | <AA Index> | <AA Index> |
269
269
  | | Price | <$ per 1M> | <$ per 1M> | <$ per 1M> |
270
270
 
271
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
272
- model uses at that level.
271
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
272
+ level.
273
273
 
274
274
  **Conversation:** New
275
275
 
@@ -327,26 +327,26 @@ key pays for the platform.>
327
327
  **Phase roadmap settings** — the session that writes
328
328
  `phase02-roadmap.md` (`/roadmap-phase 2`):
329
329
 
330
- | | | Cost | Balanced | Quality ✓ |
331
- | ------------- | -------- | ----- | -------- | --------- |
332
- | **Pick** | Model | **…** | **…** | **…** |
333
- | | Platform | … | … | … |
334
- | | Level | … | … | … |
335
- | | AA | … | … | … |
336
- | | Price | … | … | … |
337
- | **Runner‑up** | Model | **…** | **…** | **…** |
338
- | | Platform | … | … | … |
339
- | | Level | … | … | … |
340
- | | AA | … | … | … |
341
- | | Price | … | … | … |
342
- | **Backup** | Model | **…** | **…** | **…** |
343
- | | Platform | … | … | … |
344
- | | Level | … | … | … |
345
- | | AA | … | … | … |
346
- | | Price | … | … | … |
347
-
348
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
349
- model uses at that level.
330
+ | | | Cost | Balanced | Quality |
331
+ | ------------- | -------- | ----- | -------- | ------- |
332
+ | **Pick** | Model | **…** | **…** | **…** |
333
+ | | Platform | … | … | … |
334
+ | | Level | … | … | … |
335
+ | | AA | … | … | … |
336
+ | | Price | … | … | … |
337
+ | **Runner‑up** | Model | **…** | **…** | **…** |
338
+ | | Platform | … | … | … |
339
+ | | Level | … | … | … |
340
+ | | AA | … | … | … |
341
+ | | Price | … | … | … |
342
+ | **Backup** | Model | **…** | **…** | **…** |
343
+ | | Platform | … | … | … |
344
+ | | Level | … | … | … |
345
+ | | AA | … | … | … |
346
+ | | Price | … | … | … |
347
+
348
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
349
+ level.
350
350
 
351
351
  **Conversation:** New
352
352
 
@@ -378,26 +378,26 @@ model uses at that level.
378
378
  **Phase roadmap settings** — the session that writes
379
379
  `phaseNN-roadmap.md` (`/roadmap-phase N`):
380
380
 
381
- | | | Cost | Balanced | Quality ✓ |
382
- | ------------- | -------- | ----- | -------- | --------- |
383
- | **Pick** | Model | **…** | **…** | **…** |
384
- | | Platform | … | … | … |
385
- | | Level | … | … | … |
386
- | | AA | … | … | … |
387
- | | Price | … | … | … |
388
- | **Runner‑up** | Model | **…** | **…** | **…** |
389
- | | Platform | … | … | … |
390
- | | Level | … | … | … |
391
- | | AA | … | … | … |
392
- | | Price | … | … | … |
393
- | **Backup** | Model | **…** | **…** | **…** |
394
- | | Platform | … | … | … |
395
- | | Level | … | … | … |
396
- | | AA | … | … | … |
397
- | | Price | … | … | … |
398
-
399
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
400
- model uses at that level.
381
+ | | | Cost | Balanced | Quality |
382
+ | ------------- | -------- | ----- | -------- | ------- |
383
+ | **Pick** | Model | **…** | **…** | **…** |
384
+ | | Platform | … | … | … |
385
+ | | Level | … | … | … |
386
+ | | AA | … | … | … |
387
+ | | Price | … | … | … |
388
+ | **Runner‑up** | Model | **…** | **…** | **…** |
389
+ | | Platform | … | … | … |
390
+ | | Level | … | … | … |
391
+ | | AA | … | … | … |
392
+ | | Price | … | … | … |
393
+ | **Backup** | Model | **…** | **…** | **…** |
394
+ | | Platform | … | … | … |
395
+ | | Level | … | … | … |
396
+ | | AA | … | … | … |
397
+ | | Price | … | … | … |
398
+
399
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
400
+ level.
401
401
 
402
402
  **Conversation:** New
403
403
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "roadmodel"
7
- version = "0.2.98"
7
+ version = "0.2.99"
8
8
  description = "BYO-key CLI that recommends the right AI model, platform, and settings for a prompt."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema_version": "4",
3
3
  "output_contract_version": 2,
4
- "generated_at_utc": "2026-10-25T19:01:45Z",
4
+ "generated_at_utc": "2026-10-27T17:02:15Z",
5
5
  "source_doc_sha256": {
6
6
  "model-selector.txt": "e2ef6c5a18f05ff952fad9f576720b8fc4637f563f60ce5c077c5501fc21d1b7",
7
7
  "model-tier-cost-scale.md": "dad707e59d0f3e75cf699d81368ba66783cc2a6a0bf625c430e8f884ef844a1c"
@@ -758,8 +758,7 @@ that owns it.}}
758
758
  <c> --complexity <x> [--novel]` prints them for the
759
759
  step's classification (MCP tool: `roadmap_settings`).
760
760
  Layout (roadmodel 0.2.95 on): one table whose columns
761
- are Cost, Balanced and Quality (the column the **Runs:**
762
- line names marked ✓). Each rank — **Pick**, **Runner‑up**,
761
+ are Cost, Balanced and Quality. Each rank — **Pick**, **Runner‑up**,
763
762
  **Backup** — names the first of its rows from a column of
764
763
  its own (blank below it, no `&nbsp;`), beside
765
764
  field rows: Model (bold); Platform; Level, the bare
@@ -774,7 +773,7 @@ that owns it.}}
774
773
  no Thinking row: Thinking is always On wherever the
775
774
  platform has the toggle, and every AA Index and Price
776
775
  already assumes it. A note line under the table explains
777
- ✓ and Price, and a `**Conversation:**` line closes the
776
+ Price, and a `**Conversation:**` line closes the
778
777
  ladder. Each rank comes from its own maker (roadmodel
779
778
  0.2.97 on), because a tight usage pool is a maker's: the
780
779
  Runner-up is the column's recommendation with the Pick's
@@ -892,7 +891,7 @@ step's classification, pasted as printed. The three table
892
891
  shapes after it are the fallback where roadmodel cannot be
893
892
  reached}}):
894
893
 
895
- | | | Cost | Balanced ✓ | Quality |
894
+ | | | Cost | Balanced | Quality |
896
895
  | ------------- | -------- | --------------------- | --------------------- | --------------------- |
897
896
  | **Pick** | Model | **{{Model}}** | **{{Model}}** | **{{Model}}** |
898
897
  | | Platform | {{Platform}} | {{Platform}} | {{Platform}} |
@@ -910,8 +909,8 @@ reached}}):
910
909
  | | AA | {{AA Index}} | {{AA Index}} | {{AA Index}} |
911
910
  | | Price | {{$ per 1M}} | {{$ per 1M}} | {{$ per 1M}} |
912
911
 
913
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
914
- model uses at that level.
912
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
913
+ level.
915
914
 
916
915
  **Conversation:** New
917
916
 
@@ -1331,7 +1330,7 @@ printed with its **Runs:** line. Where roadmodel cannot be
1331
1330
  reached, the single-column variant that matches PLATFORM,
1332
1331
  carrying ONLY the rows that platform's panel exposes.}}
1333
1332
 
1334
- | | | Cost | Balanced ✓ | Quality |
1333
+ | | | Cost | Balanced | Quality |
1335
1334
  | ------------- | -------- | --------------------- | --------------------- | --------------------- |
1336
1335
  | **Pick** | Model | **{{Model}}** | **{{Model}}** | **{{Model}}** |
1337
1336
  | | Platform | {{Platform}} | {{Platform}} | {{Platform}} |
@@ -1349,8 +1348,8 @@ carrying ONLY the rows that platform's panel exposes.}}
1349
1348
  | | AA | {{AA Index}} | {{AA Index}} | {{AA Index}} |
1350
1349
  | | Price | {{$ per 1M}} | {{$ per 1M}} | {{$ per 1M}} |
1351
1350
 
1352
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
1353
- model uses at that level.
1351
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
1352
+ level.
1354
1353
 
1355
1354
  **Conversation:** New
1356
1355
 
@@ -1481,7 +1480,7 @@ this step's classification, pasted as printed with its
1481
1480
  **Runs:** line; where roadmodel cannot be reached, the
1482
1481
  single-column variant that matches PLATFORM.}}
1483
1482
 
1484
- | | | Cost | Balanced ✓ | Quality |
1483
+ | | | Cost | Balanced | Quality |
1485
1484
  | ------------- | -------- | --------------------- | --------------------- | --------------------- |
1486
1485
  | **Pick** | Model | **{{Model}}** | **{{Model}}** | **{{Model}}** |
1487
1486
  | | Platform | {{Platform}} | {{Platform}} | {{Platform}} |
@@ -1499,8 +1498,8 @@ single-column variant that matches PLATFORM.}}
1499
1498
  | | AA | {{AA Index}} | {{AA Index}} | {{AA Index}} |
1500
1499
  | | Price | {{$ per 1M}} | {{$ per 1M}} | {{$ per 1M}} |
1501
1500
 
1502
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
1503
- model uses at that level.
1501
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
1502
+ level.
1504
1503
 
1505
1504
  **Conversation:** New
1506
1505
 
@@ -250,7 +250,7 @@ dependency graph in §5 is honoured.
250
250
  **Phase roadmap settings** — the session that writes
251
251
  `phase01-roadmap.md` (`/roadmap-phase 1`):
252
252
 
253
- | | | Cost | Balanced | Quality ✓ |
253
+ | | | Cost | Balanced | Quality |
254
254
  | ------------- | -------- | ------------------- | ------------------- | ------------------- |
255
255
  | **Pick** | Model | **<Model>** | **<Model>** | **<Model>** |
256
256
  | | Platform | <Platform> | <Platform> | <Platform> |
@@ -268,8 +268,8 @@ dependency graph in §5 is honoured.
268
268
  | | AA | <AA Index> | <AA Index> | <AA Index> |
269
269
  | | Price | <$ per 1M> | <$ per 1M> | <$ per 1M> |
270
270
 
271
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
272
- model uses at that level.
271
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
272
+ level.
273
273
 
274
274
  **Conversation:** New
275
275
 
@@ -327,26 +327,26 @@ key pays for the platform.>
327
327
  **Phase roadmap settings** — the session that writes
328
328
  `phase02-roadmap.md` (`/roadmap-phase 2`):
329
329
 
330
- | | | Cost | Balanced | Quality ✓ |
331
- | ------------- | -------- | ----- | -------- | --------- |
332
- | **Pick** | Model | **…** | **…** | **…** |
333
- | | Platform | … | … | … |
334
- | | Level | … | … | … |
335
- | | AA | … | … | … |
336
- | | Price | … | … | … |
337
- | **Runner‑up** | Model | **…** | **…** | **…** |
338
- | | Platform | … | … | … |
339
- | | Level | … | … | … |
340
- | | AA | … | … | … |
341
- | | Price | … | … | … |
342
- | **Backup** | Model | **…** | **…** | **…** |
343
- | | Platform | … | … | … |
344
- | | Level | … | … | … |
345
- | | AA | … | … | … |
346
- | | Price | … | … | … |
347
-
348
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
349
- model uses at that level.
330
+ | | | Cost | Balanced | Quality |
331
+ | ------------- | -------- | ----- | -------- | ------- |
332
+ | **Pick** | Model | **…** | **…** | **…** |
333
+ | | Platform | … | … | … |
334
+ | | Level | … | … | … |
335
+ | | AA | … | … | … |
336
+ | | Price | … | … | … |
337
+ | **Runner‑up** | Model | **…** | **…** | **…** |
338
+ | | Platform | … | … | … |
339
+ | | Level | … | … | … |
340
+ | | AA | … | … | … |
341
+ | | Price | … | … | … |
342
+ | **Backup** | Model | **…** | **…** | **…** |
343
+ | | Platform | … | … | … |
344
+ | | Level | … | … | … |
345
+ | | AA | … | … | … |
346
+ | | Price | … | … | … |
347
+
348
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
349
+ level.
350
350
 
351
351
  **Conversation:** New
352
352
 
@@ -378,26 +378,26 @@ model uses at that level.
378
378
  **Phase roadmap settings** — the session that writes
379
379
  `phaseNN-roadmap.md` (`/roadmap-phase N`):
380
380
 
381
- | | | Cost | Balanced | Quality ✓ |
382
- | ------------- | -------- | ----- | -------- | --------- |
383
- | **Pick** | Model | **…** | **…** | **…** |
384
- | | Platform | … | … | … |
385
- | | Level | … | … | … |
386
- | | AA | … | … | … |
387
- | | Price | … | … | … |
388
- | **Runner‑up** | Model | **…** | **…** | **…** |
389
- | | Platform | … | … | … |
390
- | | Level | … | … | … |
391
- | | AA | … | … | … |
392
- | | Price | … | … | … |
393
- | **Backup** | Model | **…** | **…** | **…** |
394
- | | Platform | … | … | … |
395
- | | Level | … | … | … |
396
- | | AA | … | … | … |
397
- | | Price | … | … | … |
398
-
399
- ✓ runs by default. Price: list $ per 1M tokens (3 in : 1 out) × the tokens the
400
- model uses at that level.
381
+ | | | Cost | Balanced | Quality |
382
+ | ------------- | -------- | ----- | -------- | ------- |
383
+ | **Pick** | Model | **…** | **…** | **…** |
384
+ | | Platform | … | … | … |
385
+ | | Level | … | … | … |
386
+ | | AA | … | … | … |
387
+ | | Price | … | … | … |
388
+ | **Runner‑up** | Model | **…** | **…** | **…** |
389
+ | | Platform | … | … | … |
390
+ | | Level | … | … | … |
391
+ | | AA | … | … | … |
392
+ | | Price | … | … | … |
393
+ | **Backup** | Model | **…** | **…** | **…** |
394
+ | | Platform | … | … | … |
395
+ | | Level | … | … | … |
396
+ | | AA | … | … | … |
397
+ | | Price | … | … | … |
398
+
399
+ Price: list $ per 1M tokens (3 in : 1 out) × the tokens the model uses at that
400
+ level.
401
401
 
402
402
  **Conversation:** New
403
403
 
@@ -204,8 +204,7 @@ complexity, novel or not; its Model rationale names them), then:
204
204
  fix, not a new pick, so it takes no `Settings updated` line.
205
205
  - Every ladder, a step's Settings and a phase's Phase roadmap settings
206
206
  alike, takes the table layout (roadmodel 0.2.95 on), as `roadmodel
207
- ladder` prints it: Cost, Balanced and Quality columns (the one its
208
- **Runs:** line names marked ✓), each rank (**Pick**, **Runner‑up**,
207
+ ladder` prints it: Cost, Balanced and Quality columns, each rank (**Pick**, **Runner‑up**,
209
208
  **Backup**) in a column of its own beside its Model / Platform / Level / AA /
210
209
  Price rows — Level the bare level of the platform's own dial, AA its AA
211
210
  Intelligence Index there (`not measured` where AA has no row), Price its
@@ -222,10 +221,10 @@ complexity, novel or not; its Model rationale names them), then:
222
221
  progress` step's is what an agent is running, and a written phase's
223
222
  records what wrote its roadmap, so those keep their layout. One
224
223
  exception reaches every section: a 0.2.95–0.2.97 table, whose fields are
225
- indented with `&nbsp;` (some viewers draw each as a highlighted blob),
226
- takes the rank column wherever it stands, Complete steps included, every
227
- cell kept. That is a layout fix, not a new pick, and takes no `Settings
228
- updated` line. Then
224
+ indented with `&nbsp;` (some viewers draw each as a highlighted blob), or
225
+ a 0.2.98 table still carrying ✓, takes the rank column without ✓ wherever
226
+ it stands, Complete steps included, every cell kept. That is a layout fix,
227
+ not a new pick, and takes no `Settings updated` line. Then
229
228
  run `roadmodel rerank <every roadmap file>` (roadmodel 0.2.97 on): it
230
229
  gives each of those ladder tables the ranks this release computes, so a
231
230
  change to how roadmodel ranks reaches every step not yet run. It reads
@@ -114,8 +114,7 @@ the dials and make sure it is set.
114
114
  **Backup**) sits in a column of its own beside its Model, Platform, Level, AA and
115
115
  Price rows. Level is the bare level of that platform's own dial (`High`
116
116
  is Intelligence High on Codex, Effort High on Claude Code and
117
- Antigravity). The ✓ in a column's header marks the one its **Runs:**
118
- line names. From roadmodel 0.2.97 the three ranks of a column come from
117
+ Antigravity). From roadmodel 0.2.97 the three ranks of a column come from
119
118
  three makers (a tight pool is a maker's); where too few are funded, a
120
119
  missing rank is the Pick one level lower, its Level marked ↓, and the
121
120
  note line says which classification the ladder was ranked for. A 0.2.94
@@ -1,2 +1,2 @@
1
1
  # src/roadmodel/__init__.py
2
- __version__ = "0.2.98"
2
+ __version__ = "0.2.99"
@@ -123,7 +123,7 @@ def _grid(rows: list[list[str]]) -> list[str]:
123
123
  def ladder_markdown(
124
124
  columns: Mapping[str, Mapping[str, Option | None]],
125
125
  *,
126
- runs: str | None,
126
+ runs: str | None = None,
127
127
  conversation: str | None,
128
128
  ranked_for: str | None = None,
129
129
  ) -> str:
@@ -132,7 +132,7 @@ def ladder_markdown(
132
132
  none), and a field row only when some option of that rank has a value
133
133
  there (an older backup has no AA Index; a rank with no option in any
134
134
  column reads `none` alone)."""
135
- head = ["", "", *(t.capitalize() + (f" {RUNS_MARK}" if t == runs else "") for t in TIERS)]
135
+ head = ["", "", *(t.capitalize() for t in TIERS)]
136
136
  rows = [head]
137
137
  priced = unmeasured = stepped = False
138
138
  for label, key in RANKS:
@@ -155,8 +155,6 @@ def ladder_markdown(
155
155
  )
156
156
  stepped |= any(o is not None and o.stepped_down for o in opts)
157
157
  notes = [f"Ranked for {ranked_for}."] if ranked_for else []
158
- if runs:
159
- notes.append(f"{RUNS_MARK} runs by default.")
160
158
  if stepped:
161
159
  notes.append(
162
160
  f"{STEP_MARK} the Pick one level lower: no other maker is funded, and a "
@@ -357,22 +355,25 @@ def _list_ladder(
357
355
  # that runs, its Conversation value, the classification its note names, and
358
356
  # whether converting it is a display fix that reaches every section.
359
357
  _Found = tuple[int, dict[str, dict[str, "Option | None"]], str | None, str | None, str | None, bool]
360
- # The 0.2.95–0.2.97 table: one empty header cell before Cost.
361
- _INDENT_HEAD_RE: Final = re.compile(r"^\|\s*\|\s*Cost\b")
358
+ # The 0.2.95–0.2.98 table: one empty header cell before Cost (0.2.95–0.2.97)
359
+ # or two with a ✓ in the header or note (0.2.98).
360
+ _INDENT_HEAD_RE: Final = re.compile(r"^\|\s*\|(?:\s*\|)?\s*Cost\b")
362
361
  _PRICE_RE: Final = re.compile(r"^\$([0-9]+(?:\.[0-9]+)?)/1M(\*?)$")
363
362
 
364
363
 
365
364
  def _indented_ladder(
366
365
  lines: list[str], start: int
367
366
  ) -> tuple[int, dict[str, dict[str, Option | None]], str | None, str | None, str | None] | None:
368
- """A 0.2.95–0.2.97 ladder table starting at ``lines[start]`` (rank rows
369
- over `&nbsp;`-indented fields): the index past its note and Conversation
370
- line (its Runs paragraph stays), its columns with every cell read back,
371
- the column marked ✓, its Conversation value and the classification its
372
- note names; None when a row is not one this release wrote."""
367
+ """A 0.2.95–0.2.98 ladder table starting at ``lines[start]`` (rank rows
368
+ over `&nbsp;`-indented fields, or a 0.2.98 table still carrying ✓): the
369
+ index past its note and Conversation line (its Runs paragraph stays), its
370
+ columns with every cell read back, the column marked ✓, its Conversation
371
+ value and the classification its note names; None when a row is not one
372
+ those releases wrote or the table is already in the current layout."""
373
373
  head = _table_cells(lines[start])
374
+ tier_cells = head[-len(TIERS) :]
374
375
  runs = next(
375
- (t for t, cell in zip(TIERS, head[1:], strict=False) if cell.endswith(RUNS_MARK)), None
376
+ (t for t, cell in zip(TIERS, tier_cells, strict=False) if cell.endswith(RUNS_MARK)), None
376
377
  )
377
378
  cells, j = _table_rows(lines, start + 2)
378
379
  keys = {label.replace("\u2011", "-"): key for label, key in RANKS}
@@ -409,6 +410,8 @@ def _indented_ladder(
409
410
  n += 1
410
411
  note = " ".join(" ".join(lines[k:n]).split())
411
412
  end = n
413
+ if len(head) == 2 + len(TIERS) and runs is None and f"{RUNS_MARK} runs by default." not in note:
414
+ return None
412
415
  k = _skip_blank(lines, end)
413
416
  conversation = None
414
417
  if k < len(lines) and (conv := _CONVERSATION_RE.match(lines[k])):
@@ -1808,10 +1808,36 @@ def ladder(
1808
1808
  # none: the picks then fall back to the models' frontier.
1809
1809
  points = frontier(settings, bench) or front
1810
1810
 
1811
+ aa_band = _aa_band(bench, cat)
1811
1812
  adequate = [p for p in points if p.candidate.requirement_penalty == 0]
1812
1813
  if not adequate:
1813
1814
  adequate = [max(points, key=_nearest)]
1814
- top = _top(adequate, task.category)
1815
+ raw_top = _top(adequate, task.category)
1816
+ # Within a maker, a model the evidence cannot tell from the strongest
1817
+ # (within the category and AA noise bands both ways, as in _backup_for)
1818
+ # wins when it is cheaper: GPT-6.1 Sol at $4.00/1M is not passed over for
1819
+ # GPT-6 Astra at $16.36/1M over 1.4 AA points. Each model is read at its
1820
+ # own strongest effort in the band so a model's lower effort does not
1821
+ # displace its higher one on QUALITY.
1822
+ prepaid = raw_top.candidate.scarcity < 1.0
1823
+ peers = [
1824
+ p
1825
+ for p in points
1826
+ if p.candidate.provider == raw_top.candidate.provider
1827
+ and (p.candidate.scarcity < 1.0 or not prepaid)
1828
+ and _near_tied(
1829
+ p.candidate, p.aa_index, raw_top.candidate, raw_top.aa_index, task.category, aa_band
1830
+ )
1831
+ ]
1832
+ by_model: dict[str, list[FrontierPoint]] = {}
1833
+ for p in peers:
1834
+ by_model.setdefault(p.candidate.model_id, []).append(p)
1835
+ top = min(
1836
+ (_top(ps, task.category) for ps in by_model.values()),
1837
+ key=lambda p: (p.price_usd, -p.candidate.score),
1838
+ )
1839
+ if top not in adequate:
1840
+ adequate = [p for p in points if p.candidate.requirement_penalty == 0 or p is top]
1815
1841
  span = adequate[: adequate.index(top) + 1]
1816
1842
  specialist = _specialist(task, settings, points, top, bench)
1817
1843
  by_level = {(c.model_id, c.evidence_level): c for c in settings if c.evidence_level}
@@ -1916,9 +1942,6 @@ def ladder(
1916
1942
  )
1917
1943
  balanced_rung = settle(_below(balanced_rung, quality_rung, cat))
1918
1944
  cost_rung = settle(_below(cost_rung, balanced_rung, cat))
1919
- # General capability is level within the same noise band, read on the
1920
- # AA Index's own 0–100 scale (the planning evidence).
1921
- aa_band = _aa_band(bench, cat)
1922
1945
  rungs = {
1923
1946
  r.tier: replace(r, backup=_backup_for(r, settings, task, headroom, bench, cat, aa_band))
1924
1947
  for r in (cost_rung, balanced_rung, quality_rung)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes