v3.0.0-beta.1
Pre-release
Pre-release
·
186 commits
to main
since this release
Binacle.Net v3.0.0-beta.1 is a prerelease of v3.0.0, a major update from v2.1.1.
Warning
v3.0.0 introduces breaking changes. Existing integrations must be reviewed and updated. V2 endpoints are removed, ViPaq tokens from earlier versions no longer decode, and health check IP restrictions are matched differently.
Note
This is a prerelease, published for verification. The v3.0.x documentation is not out yet, so the v2.1.x pages are still the current ones. Do not pin a deployment to a beta tag - latest and 3.0 stay on the last stable image.
🔎 Overview
- V2 endpoints were removed.
- V4 endpoints were introduced as experimental.
- V3 endpoints remain stable and unchanged, and are the recommended version.
- ViPaq was rebuilt with a smaller, simpler format. Tokens from earlier versions no longer decode.
- Algorithms were unified — fitting and packing now share one implementation.
- Packing Logs configuration was flattened, with breaking changes for existing integrations.
- Forwarded headers are now supported, so the real caller is resolved when running behind a proxy or CDN.
- Health check IP restrictions are matched differently, with breaking changes for existing allow-lists.
- The login rate limit counts per connection address, not per caller-supplied header.
- The project was restructured, separating the API, library, and ViPaq into their own roots.
- Versioned documentation now covers every minor line, so older images keep their docs.
⚙️ Core Changes
- Removal of all V2 endpoints.
- Added 16 experimental V4 endpoints, covering everything V3 does.
- V4 splits a request into three shapes. One bin, one answer —
fit/bin,pack/bin, and their{preset}/{bin}variants. - Many bins, one answer —
pack/smallest-bin,pack/smallest-bin/{preset},fit/smallest-bin, andfit/smallest-bin/{preset}return the smallest bin that works;pack/best-binandpack/best-bin/{preset}return the bin the items fill the most. - Many bins, every answer —
fit/compare-bins,pack/compare-bins, and their{preset}variants return one result per bin, in the order the bins were sent. - Presets can be listed with
presetsor fetched one at a time withpresets/{preset}. - V4 is experimental and can change at any time. V3 remains stable and is the recommended version.
- V3 endpoints are unchanged and remain stable, apart from the ViPaq payload.
- Added forwarded headers support, configured in
Config_Files/ForwardedHeaders.json. Disabled by default. - When enabled, the caller's address and scheme are resolved from
X-Forwarded-ForandX-Forwarded-Protobefore anything reads them, so rate limiting and health check IP restrictions see the real caller rather than the proxy. - Trust is explicit — a proxy on loopback or a private network is trusted by default, anything else must be named. The app refuses to start if nothing is trusted, because that would make every caller's header believable.
- A different header can be read instead, for CDNs that send one —
CF-Connecting-IP,X-Real-IP,X-Azure-ClientIP. ASPNETCORE_FORWARDEDHEADERS_ENABLEDis ignored. It switches the underlying middleware on with no proxy verification, which lets any caller choose their own address.TrustedProxiesentries are read exactly as written, the same rule as health checkRestrictedIPs.010.10.10.10used to be read as octal and trust8.10.10.10, and172.17.1used to mean172.17.0.1; both now fail startup validation rather than trusting a host you did not name.- Added a
/_debugendpoint, off by default, enabled withDEBUG_ENDPOINT=True. It echoes the caller's own request — connection address and headers — for working out what a proxy is sending. - A startup warning when a forwarding header arrives and does not take effect, either because the feature is off or because the trust list does not name your proxy. Logged once. Without it both states are silent and the app quietly reads the proxy as the caller.
- Existing environment variables are unchanged —
DEBUG_ENDPOINTis the only new one. - The image now creates
/app/dataand gives it to the app user. A volume mounted over a directory the image did not have was owned by root and unwritable, which broke logs, packing logs and the SQLite database on a fresh named volume. - The image now ships
libgssapi-krb5-2. Npgsql probes for it on every connection and printedCannot load library libgssapi_krb5.so.2at startup for anyone on the Postgres backend — the app was never affected, but the line reads like a fatal error. - The image carries OCI labels — title, description, source, documentation, licenses, and the base image — so a registry and
docker inspectdescribe it.
🧪 Diagnostics Module
- Packing Logs configuration was flattened —
Path,FileName,DateFormat, andChannelLimitnow sit directly underPackingLogs. - Removed the fitting configuration block, now that fitting and packing share one log.
- Implementations depending on the old nested shape must be updated, or startup validation will fail.
- The default log path changed from
data/pack-logs/packing/todata/pack-logs/. - Packing log entries now include a
Timestampfield. - Added an optional
RetentionDaysunderPackingLogs. Log files older than that are deleted once a day. Unset by default, which keeps every file — deletion stays opt-in. - Health check
RestrictedIPsnow uses CIDR notation correctly. The value after/was previously read as an address mask, so192.168.1.0/24covered nearly the whole IPv4 range instead of 256 addresses. Existing CIDR entries are now much narrower than they were. - Health check
RestrictedIPsnow matches IPv4 callers in containers. Addresses arriving in IPv4-mapped IPv6 form are unmapped before comparison, which they previously were not — no IPv4 entry could match. - Removed the
start-endrange form fromRestrictedIPs. Entries such as192.168.1.0-192.168.1.255now fail startup validation. Use CIDR instead. RestrictedIPsentries are now read exactly as written. An IPv4 address must be four plain decimal parts with no leading zeros, and an IPv6 address must be in its short, lowercase form.010.10.10.10used to be read as octal and admit8.10.10.10;10.1used to mean10.0.0.1;167772161meant the same. All of these now fail startup validation instead of quietly admitting a host you did not name.192.168.1.1/24still means the whole192.168.1.0/24— that is what CIDR notation means — but the startup log now says so.
🔌 Service Module
- The login rate limit is no longer bypassable. It counted attempts per
X-Forwarded-FororX-Real-IPvalue, both written by the caller, so varying the header reset the limit on every request. It now counts per connection address. - Behind a proxy this means every caller shares one limit unless forwarded headers are enabled, because the connection address is the proxy's. Enable them, and the limit is per caller again.
🎨 UI Module
- The Protocol Decoder reads the new ViPaq format only. Tokens from earlier versions are rejected.
📈 Algorithms
- Fitting and packing now share one algorithm. Fitting stops early on the first item that does not fit.
- Packing results are unchanged — the shared algorithm is the previous packing implementation.
- The separate fitting algorithm family was retired.
🏗️ Internal Work
- Restructured the repository — the API, library, ViPaq, and shared test data now live in their own roots.
- Extracted Binacle.Geometry into its own library.
- Reworked the packing log pipeline, moving the generic parts into the Kernel.
- Added benchmark suites for algorithms, bin processing, result selection, and ViPaq.
- Added cross-language ViPaq interop tests between C# and TypeScript.
- Patched two high-severity advisories in transitive dependencies —
Microsoft.OpenApiand the bundled SQLite native library.
📚 Versioned Docs
- Documentation is now versioned per minor line —
v1.3.x,v2.0.x,v2.1.x,v3.0.x— so any image can be matched to its docs. - Backfilled the
v2.0.xandv2.1.xdocumentation, which was previously missing. - The
latestdocumentation now redirects to the current version, so existing links keep working.
🛠️ Migration Guide
To upgrade to v3.0.0, follow these steps:
-
Remove all V2 usage
- Any calls to V2 endpoints must be removed or migrated.
- Replace
/api/v2/presets,/api/v2/fit/by-custom,/api/v2/fit/by-preset/{preset},/api/v2/pack/by-custom, and/api/v2/pack/by-preset/{preset}with their V3 equivalents.
-
Switch to V3 endpoints
- V3 requires an algorithm to be selected, where V2 used a fixed one, and drops V2's other parameters.
- See the v2.1.x documentation for the old contract.
-
Regenerate all ViPaq tokens
- The format was rebuilt and is not backwards compatible.
- Tokens from earlier versions no longer decode, and there is no fallback reader.
- Re-run the packing request to get a new token. Any stored token — a saved link or a bookmarked result — is stale.
- This applies to V3 responses as well, even though V3 is otherwise unchanged.
-
Do not mix versions
- Images before v3.0.0 produce the old ViPaq format; v3.0.0 onward produces and reads only the new one.
- An encoder and a decoder on different sides of this release will not interoperate.
-
Update Packing Logs configuration
- Move
Path,FileName,DateFormat, andChannelLimitout of the nestedPackingblock, directly underPackingLogs, and delete theFittingblock. - Left in the old shape with
Enabled: true, startup validation now fails. - Repoint log collection from
data/pack-logs/packing/todata/pack-logs/. The oldpacking/andfitting/directories are safe to remove.
- Move
-
Review health check
RestrictedIPs- Replace any
start-endentries with CIDR —192.168.1.0-192.168.1.255becomes192.168.1.0/24. Left as they are, startup validation now fails. - Re-check any CIDR entry. It now covers what it says, which is far less than before — confirm the addresses you expect are still inside it, or you will lock yourself out.
- A range that does not line up with a CIDR boundary must be split into several entries, or widened to the enclosing subnet.
- Drop any leading zeros —
010.10.10.10becomes10.10.10.10, and note it used to admit8.10.10.10, so check that host was not the one you meant. Write IPv6 entries in the short lowercase form:2001:0DB8::1becomes2001:db8::1. - If Binacle.Net runs behind a proxy, load balancer or CDN, enable forwarded headers as well. Without it the list is compared against the proxy's address and can never match your monitoring system.
- Replace any
Full Changelog: v2.1.1...v3.0.0-beta.1