Your wardrobe in. The lightest feasible trip plan out.
OneBag Solver is an exact, offline optimizer for travel wardrobes. Give it the clothes you actually own, measured weight and volume, day-by-day role/tag needs, laundry points, fixed baggage, and bag limits. It returns the lightest capsule that can cover every day, plus the schedule that proves it.
No account. No API key. No photos. No AI-generated packing guesses. No runtime dependencies.
The included Tokyo example has 15 wardrobe candidates, 6 fixed items, 7 days of city, smart, cold, wind, rain, and trail requirements, and laundry after day 4.
$ onebag-solver check examples/tokyo-spring-week.json
OK: Tokyo spring week (7 days, 15 wardrobe candidates, 6 fixed items)
$ onebag-solver solve examples/tokyo-spring-week.json --format markdownThe exact result selects 6 clothing items and covers all 26 daily assignments:
all-day-shoes, convertible-pants, cotton-white,
oxford-blue, softshell, thermal-grey
Packed weight: 5,680 g / 6,000 g
Packed volume: 11,950 ml / 12,500 ml
See the committed Markdown plan or JSON plan before installing anything.
Download onebag-solver-0.1.0.pyz from the
latest release, then:
python onebag-solver-0.1.0.pyz check your-trip.json
python onebag-solver-0.1.0.pyz solve your-trip.json --output plan.mdThe zip application contains the whole program. Python 3.11+ is the only requirement.
Download the wheel from the release, or install from a source checkout:
python -m pip install onebag_solver-0.1.0-py3-none-any.whl
onebag-solver --versionOneBag Solver is not published to PyPI in v0.1.0; use the tagged GitHub release
page and its SHA256SUMS manifest.
Validate an input without solving it:
onebag-solver check examples/tokyo-spring-week.jsonCreate a readable packing and wear plan:
onebag-solver solve examples/tokyo-spring-week.json
onebag-solver solve examples/tokyo-spring-week.json --output trip-plan.mdCreate deterministic JSON for another tool:
onebag-solver solve examples/tokyo-spring-week.json \
--format json --output trip-plan.jsonpython -m onebag_solver accepts the same commands.
| Exit | Meaning |
|---|---|
0 |
Valid input or a complete plan was produced. |
2 |
Usage, file, JSON, schema, or output-path error. |
3 |
The input is valid, but no feasible capsule exists. |
The deliberately impossible formal-dinner example demonstrates exit 3:
$ onebag-solver solve examples/impossible-formal-dinner.json
no feasible plan: role 'top' cannot cover every required dayA daily need has one role and zero or more required tags. A wardrobe item is
eligible when its role matches and its provides tags contain all required
tags.
{
"schema_version": 1,
"trip": {
"name": "Three days in Berlin",
"max_packed_weight_g": 7000,
"max_packed_volume_ml": 18000,
"laundry_after_days": [2],
"days": [
{
"day": 1,
"label": "Arrival",
"needs": [{"role": "top", "requires": ["city"]}]
}
]
},
"wardrobe": [
{
"id": "merino-tee",
"name": "Merino tee",
"role": "top",
"weight_g": 160,
"volume_ml": 500,
"wears_per_wash": 3,
"washable": true,
"provides": ["city", "trail"]
}
],
"fixed_items": []
}Laundry after day 2 resets usage counters for washable items before day 3.
Non-washable items never reset. All selected clothes count as packed, including
what is worn on day 1. See the complete input reference.
The solver enumerates clothing subsets per role, verifies each subset with an exact capacity-matching schedule, keeps weight/volume/count Pareto fronts, and combines them under global bag limits. The final order is:
- lowest total weight;
- then lowest volume;
- then fewest selected clothes;
- then lexicographically smallest item IDs.
The same input therefore produces the same bytes. To keep exhaustive solving predictable without a native dependency, v0.1 accepts at most 16 candidates per role and 31 days. It rejects larger inputs instead of returning an undocumented approximation. See the architecture and ADR 0001.
From a clean checkout, using Python 3.11+:
python -m venv .venv
# Activate it: .venv\Scripts\activate on Windows, or source .venv/bin/activate
python -m pip install -r requirements-dev.txt
python -m pip install --no-deps -e .
ruff check .
ruff format --check .
python -m unittest discover -s tests -v
onebag-solver check examples/tokyo-spring-week.json
onebag-solver solve examples/tokyo-spring-week.json --format json
python scripts/build_release.py
python scripts/release_check.pySuccess ends with RELEASE_CHECK_OK. The final command verifies checksums,
installs the wheel into an isolated directory, runs the zipapp, validates the
real plan, and checks exit codes 2 and 3. If any command fails, follow the
repair guide and rerun from that failed gate.
- Product specification and success criteria
- Opportunity research and closest neighbours
- Architecture and module boundaries
- Input format
- Failure diagnosis and repair
- Implementation sources
- Changelog
The research found an underserved intersection of one-bag packing, measured capacity, laundry scheduling, and deterministic optimization. It does not claim that no private or unindexed implementation exists, and it does not promise a star count.
Start with CONTRIBUTING.md. Report sensitive vulnerabilities through GitHub private vulnerability reporting. OneBag Solver is available under the MIT License.