Skip to content

Repository files navigation

OneBag Solver

CI MIT License

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.

See it solve a real week

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 markdown

The 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.

Install

Single-file release

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.md

The zip application contains the whole program. Python 3.11+ is the only requirement.

Python package

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 --version

OneBag Solver is not published to PyPI in v0.1.0; use the tagged GitHub release page and its SHA256SUMS manifest.

Use

Validate an input without solving it:

onebag-solver check examples/tokyo-spring-week.json

Create 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.md

Create deterministic JSON for another tool:

onebag-solver solve examples/tokyo-spring-week.json \
  --format json --output trip-plan.json

python -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 day

Model your trip

A 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.

What "exact" means

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:

  1. lowest total weight;
  2. then lowest volume;
  3. then fewest selected clothes;
  4. 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.

Reproduce acceptance

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.py

Success 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.

Project evidence

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.

Contributing and security

Start with CONTRIBUTING.md. Report sensitive vulnerabilities through GitHub private vulnerability reporting. OneBag Solver is available under the MIT License.

About

Exact offline optimizer for one-bag travel wardrobes

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages